增加趋势回调
This commit is contained in:
@@ -2228,6 +2228,7 @@ def insert_trade_record(
|
||||
exchange_trade_id=None,
|
||||
key_signal_type=None,
|
||||
entry_reason=None,
|
||||
trend_plan_id=None,
|
||||
):
|
||||
hold_minutes = calc_hold_minutes(hold_seconds)
|
||||
open_ts = opened_at or app_now_str()
|
||||
@@ -2238,12 +2239,13 @@ def insert_trade_record(
|
||||
snap_sl = initial_stop_loss if initial_stop_loss not in (None, "") else stop_loss
|
||||
er = (entry_reason or "").strip() or entry_reason_from_key_signal(kst) or ""
|
||||
conn.execute(
|
||||
"INSERT INTO trade_records (symbol,monitor_type,key_signal_type,direction,trigger_price,stop_loss,initial_stop_loss,take_profit,margin_capital,leverage,pnl_amount,hold_seconds,trade_style,risk_amount,planned_rr,actual_rr,hold_minutes,opened_at,opened_at_ms,closed_at,closed_at_ms,result,miss_reason,exchange_trade_id,entry_reason) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
|
||||
"INSERT INTO trade_records (symbol,monitor_type,key_signal_type,direction,trigger_price,stop_loss,initial_stop_loss,take_profit,margin_capital,leverage,pnl_amount,hold_seconds,trade_style,risk_amount,planned_rr,actual_rr,hold_minutes,opened_at,opened_at_ms,closed_at,closed_at_ms,result,miss_reason,exchange_trade_id,entry_reason,trend_plan_id) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
|
||||
(
|
||||
symbol, monitor_type, kst, direction, trigger_price, snap_sl, snap_sl, take_profit,
|
||||
margin_capital, leverage, pnl_amount, hold_seconds,
|
||||
trade_style, risk_amount, planned_rr, actual_rr, hold_minutes,
|
||||
open_ts, open_ts_ms, close_ts, close_ts_ms, result, miss_reason, exchange_trade_id, er or None
|
||||
open_ts, open_ts_ms, close_ts, close_ts_ms, result, miss_reason, exchange_trade_id, er or None,
|
||||
trend_plan_id,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -3000,6 +3002,76 @@ def _gate_place_tp_sl_orders(exchange_symbol, direction, contracts_amount, stop_
|
||||
)
|
||||
|
||||
|
||||
def _gate_place_stop_loss_only_position(exchange_symbol, direction, stop_loss):
|
||||
"""Gate 永续:仅挂仓位类止损触发单(趋势回调用)。"""
|
||||
ensure_markets_loaded()
|
||||
market = exchange.market(exchange_symbol)
|
||||
if not market.get("swap"):
|
||||
raise RuntimeError("仅支持永续合约 symbol")
|
||||
settle = market["settleId"]
|
||||
contract = market["id"]
|
||||
order_type = "close-long-position" if direction == "long" else "close-short-position"
|
||||
close_side = "sell" if direction == "long" else "buy"
|
||||
sl_rule = 2 if close_side == "sell" else 1
|
||||
initial = {
|
||||
"contract": contract,
|
||||
"size": 0,
|
||||
"price": "0",
|
||||
"close": True,
|
||||
"reduce_only": True,
|
||||
"tif": "ioc",
|
||||
"text": "api",
|
||||
}
|
||||
if GATE_POS_MODE == "hedge":
|
||||
initial["auto_size"] = "close_long" if direction == "long" else "close_short"
|
||||
initial["close"] = False
|
||||
sl_s = exchange.price_to_precision(exchange_symbol, float(stop_loss))
|
||||
|
||||
def _payload(trigger_price, rule):
|
||||
trig = {
|
||||
"strategy_type": 0,
|
||||
"price_type": GATE_TPSL_PRICE_TYPE,
|
||||
"price": trigger_price,
|
||||
"rule": rule,
|
||||
}
|
||||
if GATE_TPSL_TRIGGER_EXPIRATION > 0:
|
||||
trig["expiration"] = GATE_TPSL_TRIGGER_EXPIRATION
|
||||
return {
|
||||
"settle": settle,
|
||||
"initial": dict(initial),
|
||||
"trigger": trig,
|
||||
"order_type": order_type,
|
||||
}
|
||||
|
||||
last_err = None
|
||||
for attempt in range(8):
|
||||
try:
|
||||
exchange.privateFuturesPostSettlePriceOrders(_payload(sl_s, sl_rule))
|
||||
return
|
||||
except Exception as e:
|
||||
last_err = e
|
||||
time.sleep(0.2 * (attempt + 1))
|
||||
raise RuntimeError(f"交易所未接受仅止损仓位触发单:{last_err}")
|
||||
|
||||
|
||||
def calc_trend_manual_breakeven_stop(direction, entry_price, offset_pct=None):
|
||||
try:
|
||||
e = float(entry_price)
|
||||
pct = float(
|
||||
offset_pct
|
||||
if offset_pct is not None
|
||||
else float(os.getenv("TREND_PULLBACK_MANUAL_BREAKEVEN_OFFSET_PCT", "0.3"))
|
||||
)
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
if e <= 0:
|
||||
return None
|
||||
direction = (direction or "long").strip().lower()
|
||||
if direction == "short":
|
||||
return e * (1.0 - pct / 100.0)
|
||||
return e * (1.0 + pct / 100.0)
|
||||
|
||||
|
||||
def ensure_markets_loaded(force=False):
|
||||
global MARKETS_LOADED
|
||||
if force or not MARKETS_LOADED:
|
||||
@@ -5290,6 +5362,11 @@ def background_task():
|
||||
check_fib_key_monitors()
|
||||
check_key_monitors()
|
||||
check_order_monitors()
|
||||
cfg = app.extensions.get("strategy_trend_cfg")
|
||||
if cfg:
|
||||
from strategy_trend_register import check_trend_pullback_plans
|
||||
|
||||
check_trend_pullback_plans(cfg)
|
||||
except:
|
||||
pass
|
||||
time.sleep(MONITOR_POLL_SECONDS)
|
||||
@@ -5668,6 +5745,12 @@ def render_main_page(page="trade"):
|
||||
strategy_extra = strategy_page_template_vars(
|
||||
conn, page, default_risk_percent=float(RISK_PERCENT)
|
||||
)
|
||||
if page == "strategy_trend":
|
||||
cfg = app.extensions.get("strategy_trend_cfg")
|
||||
if cfg:
|
||||
from strategy_trend_register import load_trend_page_context
|
||||
|
||||
strategy_extra.update(load_trend_page_context(conn, request, cfg))
|
||||
conn.close()
|
||||
return render_template(
|
||||
"index.html",
|
||||
@@ -7756,8 +7839,10 @@ def strategy_roll_page():
|
||||
|
||||
|
||||
from strategy_register import install_strategy_trading
|
||||
from strategy_trend_register import install_strategy_trend
|
||||
|
||||
install_strategy_trading(app, _REPO_ROOT, app_module=sys.modules[__name__])
|
||||
install_strategy_trend(app, _REPO_ROOT, app_module=sys.modules[__name__])
|
||||
|
||||
|
||||
# 启动
|
||||
|
||||
Reference in New Issue
Block a user