Initial standalone crypto_okx with one-click deploy.
Add deploy/manage.sh bootstrap for git.bz121.com/dekun/crypto_okx and point docs at this repo. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
"""交易记录 / 下单监控标签工具(原 lib.strategy.strategy_trade_labels 瘦身后)."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Optional
|
||||
|
||||
ORDER_TYPE_MANUAL = "下单监控"
|
||||
ORDER_TYPE_KEY = "关键位监控"
|
||||
|
||||
# 历史数据兼容可读;新复盘下拉不再提供策略开仓类型
|
||||
MONITOR_TYPE_TREND_PULLBACK = "趋势回调"
|
||||
MONITOR_TYPE_ROLL = "顺势加仓"
|
||||
ENTRY_REASON_TREND_PULLBACK = "趋势回调"
|
||||
ENTRY_REASON_ROLL = "顺势加仓"
|
||||
|
||||
JOURNAL_ORDER_TYPE_OPTIONS = (
|
||||
ORDER_TYPE_MANUAL,
|
||||
ORDER_TYPE_KEY,
|
||||
)
|
||||
|
||||
# 旧库兼容(normalize / 读历史);不进 JOURNAL 下拉
|
||||
STRATEGY_ENTRY_REASON_OPTIONS = (
|
||||
ENTRY_REASON_TREND_PULLBACK,
|
||||
ENTRY_REASON_ROLL,
|
||||
)
|
||||
|
||||
TREND_HANDOFF_KEY_SIGNAL = ENTRY_REASON_TREND_PULLBACK
|
||||
TREND_HANDOFF_TRADE_NOTE = "趋势回调计划"
|
||||
|
||||
|
||||
def normalize_journal_order_type(raw: Optional[str]) -> str:
|
||||
s = (raw or "").strip()
|
||||
if s in JOURNAL_ORDER_TYPE_OPTIONS:
|
||||
return s
|
||||
# 历史策略类型仍可读,映射到相近展示
|
||||
if s in (MONITOR_TYPE_TREND_PULLBACK, MONITOR_TYPE_ROLL):
|
||||
return s
|
||||
if "关键位" in s:
|
||||
return ORDER_TYPE_KEY
|
||||
return ""
|
||||
|
||||
|
||||
def order_type_from_monitor_type(
|
||||
monitor_type: Optional[str],
|
||||
key_signal_type: Optional[str] = None,
|
||||
) -> str:
|
||||
del key_signal_type
|
||||
mt = (monitor_type or "").strip()
|
||||
if mt == MONITOR_TYPE_TREND_PULLBACK:
|
||||
return MONITOR_TYPE_TREND_PULLBACK
|
||||
if mt == MONITOR_TYPE_ROLL:
|
||||
return MONITOR_TYPE_ROLL
|
||||
if mt == ORDER_TYPE_KEY or "关键位" in mt:
|
||||
return ORDER_TYPE_KEY
|
||||
return ORDER_TYPE_MANUAL
|
||||
|
||||
|
||||
def handoff_trade_miss_reason(miss_reason, row) -> Optional[str]:
|
||||
"""历史趋势保本移交监控单平仓备注兼容."""
|
||||
if trend_plan_id_from_monitor_row(row) is None:
|
||||
return miss_reason
|
||||
base = (miss_reason or "").strip()
|
||||
if TREND_HANDOFF_TRADE_NOTE in base:
|
||||
return base or TREND_HANDOFF_TRADE_NOTE
|
||||
if base:
|
||||
return f"{TREND_HANDOFF_TRADE_NOTE};{base}"
|
||||
return TREND_HANDOFF_TRADE_NOTE
|
||||
|
||||
|
||||
def trend_plan_id_from_monitor_row(row) -> Optional[int]:
|
||||
if row is None:
|
||||
return None
|
||||
try:
|
||||
keys = row.keys() if hasattr(row, "keys") else []
|
||||
except Exception:
|
||||
keys = []
|
||||
if "trend_plan_id" not in keys or row["trend_plan_id"] in (None, ""):
|
||||
return None
|
||||
try:
|
||||
tid = int(row["trend_plan_id"])
|
||||
return tid if tid > 0 else None
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
|
||||
|
||||
def order_had_roll_fills(conn, order_monitor_id) -> bool:
|
||||
"""策略已移除:始终 False(roll_legs 表可能仍在旧库)."""
|
||||
del conn, order_monitor_id
|
||||
return False
|
||||
|
||||
|
||||
def _row_monitor_type(row, default_manual: str) -> str:
|
||||
if row is None:
|
||||
return default_manual
|
||||
try:
|
||||
keys = row.keys() if hasattr(row, "keys") else []
|
||||
except Exception:
|
||||
keys = []
|
||||
if "monitor_type" in keys:
|
||||
mt = (row["monitor_type"] or "").strip()
|
||||
if mt:
|
||||
return mt
|
||||
return default_manual
|
||||
|
||||
|
||||
def _row_key_signal_type(row) -> str:
|
||||
if row is None:
|
||||
return ""
|
||||
try:
|
||||
keys = row.keys() if hasattr(row, "keys") else []
|
||||
except Exception:
|
||||
keys = []
|
||||
if "key_signal_type" not in keys:
|
||||
return ""
|
||||
return (row["key_signal_type"] or "").strip()
|
||||
|
||||
|
||||
def order_monitor_source_type(row, *, default_manual: str = "下单监控") -> str:
|
||||
"""展示/平仓记录:历史趋势移交单仍标「趋势回调」."""
|
||||
if trend_plan_id_from_monitor_row(row) is not None:
|
||||
return MONITOR_TYPE_TREND_PULLBACK
|
||||
mt = _row_monitor_type(row, default_manual)
|
||||
if mt != default_manual:
|
||||
return mt
|
||||
kst = _row_key_signal_type(row)
|
||||
if kst in (
|
||||
MONITOR_TYPE_TREND_PULLBACK,
|
||||
TREND_HANDOFF_KEY_SIGNAL,
|
||||
TREND_HANDOFF_TRADE_NOTE,
|
||||
ENTRY_REASON_TREND_PULLBACK,
|
||||
):
|
||||
return MONITOR_TYPE_TREND_PULLBACK
|
||||
return mt
|
||||
|
||||
|
||||
def apply_order_monitor_source_labels(item: dict, *, default_manual: str = "下单监控") -> dict:
|
||||
out = dict(item or {})
|
||||
out["monitor_type"] = order_monitor_source_type(out, default_manual=default_manual)
|
||||
return out
|
||||
|
||||
|
||||
def trade_record_monitor_type(conn, order_row, *, default_manual: str = "下单监控") -> str:
|
||||
del conn
|
||||
return order_monitor_source_type(order_row, default_manual=default_manual)
|
||||
|
||||
|
||||
def entry_reason_for_monitor_type(monitor_type: str | None) -> str:
|
||||
mt = (monitor_type or "").strip()
|
||||
if mt == MONITOR_TYPE_TREND_PULLBACK:
|
||||
return ENTRY_REASON_TREND_PULLBACK
|
||||
if mt == MONITOR_TYPE_ROLL:
|
||||
return ENTRY_REASON_ROLL
|
||||
return ""
|
||||
|
||||
|
||||
def order_monitor_excluded_from_position_limit(conn, row) -> bool:
|
||||
del conn
|
||||
return order_monitor_source_type(row) == MONITOR_TYPE_TREND_PULLBACK
|
||||
|
||||
|
||||
def count_position_limit_active_monitors(conn) -> int:
|
||||
try:
|
||||
rows = conn.execute("SELECT * FROM order_monitors WHERE status='active'").fetchall()
|
||||
except Exception:
|
||||
return 0
|
||||
n = 0
|
||||
for row in rows:
|
||||
if not order_monitor_excluded_from_position_limit(conn, row):
|
||||
n += 1
|
||||
return n
|
||||
Reference in New Issue
Block a user