# debug_events

run_id: LIVE_DUAL_20260419_062511
level: INFO
event_type: auth_probe_ok
payload_json:
{"balance_keys": ["free", "info", "total", "used"], "credentials": {"exchange": "bingx", "key_aliases_checked": ["BINGX_KEY", "BINGX_API_KEY", "BINGX_KEY", "BINGX_API_KEY", "BYBIT_KEY", "BYBIT_API_KEY", "API_KEY", "CCXT_API_KEY"], "key_found": true, "secret_aliases_checked": ["BINGX_SECRET", "BINGX_API_SECRET", "BINGX_SECRET", "BINGX_API_SECRET", "BYBIT_SECRET", "BYBIT_API_SECRET", "API_SECRET", "CCXT_SECRET"], "secret_found": true}, "credentials_present": true, "fetch_balance_ok": true}


run_id: LIVE_DUAL_20260419_062511
level: ERROR
event_type: close_fail
payload_json:
{"exchange_response": {"error": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "ok": false, "qty": 20.0}, "partial": false, "qty": 20.0, "reason": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "requested_px": 0.1197, "side": "LONG", "symbol": "ENA/USDT:USDT"}


run_id: LIVE_DUAL_20260419_062511
level: ERROR
event_type: close_fail
payload_json:
{"exchange_response": {"error": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "ok": false, "qty": 20.0}, "partial": false, "qty": 20.0, "reason": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "requested_px": 0.12, "side": "LONG", "symbol": "ENA/USDT:USDT"}


run_id: LIVE_DUAL_20260419_062511
level: ERROR
event_type: close_fail
payload_json:
{"exchange_response": {"error": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "ok": false, "qty": 20.0}, "partial": false, "qty": 20.0, "reason": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "requested_px": 0.1205, "side": "LONG", "symbol": "ENA/USDT:USDT"}


run_id: LIVE_DUAL_20260419_062511
level: ERROR
event_type: close_fail
payload_json:
{"exchange_response": {"error": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "ok": false, "qty": 20.0}, "partial": false, "qty": 20.0, "reason": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "requested_px": 0.1204, "side": "LONG", "symbol": "ENA/USDT:USDT"}


run_id: LIVE_DUAL_20260419_062511
level: ERROR
event_type: close_fail
payload_json:
{"exchange_response": {"error": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "ok": false, "qty": 20.0}, "partial": false, "qty": 20.0, "reason": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "requested_px": 0.1208, "side": "LONG", "symbol": "ENA/USDT:USDT"}


run_id: LIVE_DUAL_20260419_064128
level: INFO
event_type: open_ok
payload_json:
{"entry": 0.1211, "entry_lag_sec": 29.0, "entry_slip_bp": 16.542597187758634, "fill": 0.1211, "order_id": "2045754641946468353", "qty": 20.0, "side": "LONG", "symbol": "ENA/USDT:USDT"}


run_id: LIVE_DUAL_20260419_064128
level: INFO
event_type: open_ok
payload_json:
{"entry": 0.1209, "entry_lag_sec": 31.0, "entry_slip_bp": -0.0, "fill": 0.1209, "order_id": "2045754649957588993", "qty": 20.0, "side": "SHORT", "symbol": "ENA/USDT:USDT"}


run_id: LIVE_DUAL_20260419_064128
level: INFO
event_type: close_ok
payload_json:
{"close_reason": "TP Full (Trailing)", "closed": true, "fill": 0.1206, "qty": 20.0, "side": "SHORT", "symbol": "ENA/USDT:USDT"}


run_id: LIVE_DUAL_20260419_064128
level: INFO
event_type: open_ok
payload_json:
{"entry": 0.1204, "entry_lag_sec": 6.0, "entry_slip_bp": 16.583747927031432, "fill": 0.1204, "order_id": "2045755047095263233", "qty": 20.0, "side": "SHORT", "symbol": "ENA/USDT:USDT"}


# stdio_log

run_id: WRAP_20260418_202753
stream_name: stdout
message:
[LIVE API] key="Sm*********************************************************************************ZQ", secret="BV*********************************************************************************JQ"


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[ccxt load_markets] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544074520}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[cfg] top_n=4, notional=2.2, timeframe=0.5m, position_mode=hedge, max_notional_frac=1.0, initial_equity=100.0, open_on_heat=False, heat_min=0.8


run_id: WRAP_20260418_202753
stream_name: stdout
message:
  results_dir: /var/www/vps2.happyuser.info/top/top_1/obw_platform/_reports/_live/livecfg_final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar_0.5m session_db: _reports/_live/bingx_ena_bundle/session.sqlite cache_out: _reports/_live/bingx_ena_bundle/combined_cache_session.db


run_id: WRAP_20260418_202753
stream_name: stdout
message:
  portfolio: {'initial_equity_per_leg': 100.0, 'fee_rate': 0.001, 'slippage_per_side': 4.0, 'max_notional_frac': 1.0, 'position_notional_long': 2.0, 'position_notional_short': 2.0}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
  strategy_params_long: {'firstBuyQtyCoin': 20, 'minOrderQtyCoin': 20, 'minOrderUSDT': 2.0, 'minLongInvestPct': 2.0, 'useEquityPctBase': True, 'baseOrderPctEq': 2, 'equityForSizingUSDT': 100.0, 'tpPercent': 0.25, 'callbackPercent': 0.060000000000000005, 'marginCallLimit': 244, 'linearDropPercent': 0.19, 'autoMerge': False, 'subSellTPPercent': 0.44, 'requireCloseAboveFullTP': True, 'subSellCloseConfirmMode': 'breakeven', 'requireCloseBelowDcaLevel': True, 'blockDcaOnTpTouch': False, 'drop1': 0.3, 'drop2': 0.4, 'drop3': 0.6, 'drop4': 0.8, 'drop5': 0.8, 'mult2': 1.7, 'mult3': 1.0, 'mult4': 2.0, 'mult5': 3.5, 'maxFillsPerBar': 6, 'maxSubSellsPerBar': 10, 'useHighLowTouch': True, 'useLiveSyncStart': False, 'liveStartTime': 0, 'maxOrdersPer3Min': 14, 'useTrendAdaptiveSizing': True, 'trendMaTf': 'W', 'trendMaLen': 20, 'trendSlopeBars': 3, 'trendSlopeLongBoundPct': 1.0, 'trendSlopeShortBoundPct': -1.0, 'trendScoreMinPct': 45.0, 'trendScoreMaxPct': 75.0, 'maxLongInvestPct': 2.2, 'hardBreakevenDeleveragePct': 50.0, 'useEvenBars': False}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
  strategy_params_short: {'firstSellQtyCoin': 20, 'minOrderQtyCoin': 20, 'minOrderUSDT': 2.0, 'minShortInvestPct': 2.0, 'useEquityPctBase': True, 'baseOrderPctEq': 2, 'equityForSizingUSDT': 100.0, 'tpPercent': 0.19, 'callbackPercent': 0.155, 'marginCallLimit': 244, 'linearRisePercent': 0.16, 'autoMerge': False, 'subSellTPPercent': 0.42, 'requireCloseBelowFullTP': True, 'subCoverCloseConfirmMode': 'breakeven', 'requireCloseAboveDcaLevel': True, 'blockDcaOnTpTouch': False, 'rise1': 0.32999999999999996, 'rise2': 0.4, 'rise3': 0.6, 'rise4': 0.8, 'rise5': 0.8, 'mult2': 1.6, 'mult3': 1.0, 'mult4': 2.0, 'mult5': 3.5, 'maxFillsPerBar': 6, 'maxSubSellsPerBar': 10, 'useHighLowTouch': True, 'useLiveSyncStart': False, 'liveStartTime': 0, 'maxOrdersPer3Min': 14, 'useTrendAdaptiveSizing': True, 'trendMaTf': 'W', 'trendMaLen': 20, 'trendSlopeBars': 3, 'trendSlopeLongBoundPct': 1.0, 'trendSlopeShortBoundPct': -1.0, 'trendScoreMinPct': 45.0, 'trendScoreMaxPct': 75.0, 'maxShortInvestPct': 2.4, 'hardBreakevenDeleveragePct': 50.0, 'useEvenBars': False}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[positions fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544075169}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544075739}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544076285}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544078519}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544080736}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544082970}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544083532}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544085733}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544087930}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544090138}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544092338}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544094538}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544096741}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544098947}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544101150}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544103356}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544105560}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544107766}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544109990}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544112191}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544114388}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544116597}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544118799}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544121000}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544123213}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544125417}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544127622}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544129837}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544132048}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544134251}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544136459}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544138671}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544140885}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544143110}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544143670}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544146221}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544148435}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544150635}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544152839}


run_id: WRAP_20260418_202753
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544155040}


run_id: WRAP_20260418_203206
stream_name: stdout
message:
[ccxt load_markets] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544327923}


run_id: WRAP_20260418_203206
stream_name: stdout
message:
[positions fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544329014}


run_id: WRAP_20260418_203206
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544329599}


run_id: WRAP_20260418_203206
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544329811}


run_id: WRAP_20260418_203206
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544332016}


run_id: WRAP_20260418_203206
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544334219}


run_id: WRAP_20260418_203206
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544336424}


run_id: WRAP_20260418_203206
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544338629}


run_id: WRAP_20260418_203206
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544340840}


run_id: WRAP_20260418_203206
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544343046}


run_id: WRAP_20260418_203206
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544345268}


run_id: WRAP_20260418_203804
stream_name: stdout
message:
[ccxt load_markets] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544685876}


run_id: WRAP_20260418_203804
stream_name: stdout
message:
[positions fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544686734}


run_id: WRAP_20260418_203804
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544687292}


run_id: WRAP_20260418_203804
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544687854}


run_id: WRAP_20260418_203804
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544690081}


run_id: WRAP_20260418_203804
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544692286}


run_id: WRAP_20260418_203804
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776544694843}


run_id: WRAP_20260418_204501
stream_name: stdout
message:
[ccxt load_markets] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776545103129}


run_id: WRAP_20260418_204501
stream_name: stdout
message:
[positions fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776545104046}


run_id: WRAP_20260418_204501
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776545104605}


run_id: WRAP_20260418_204501
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776545105166}


run_id: WRAP_20260418_204501
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776545107388}


run_id: WRAP_20260418_204501
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776545109590}


run_id: WRAP_20260418_204501
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776545111798}


run_id: WRAP_20260418_204501
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776545114019}


run_id: WRAP_20260418_204501
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776545116238}


run_id: WRAP_20260418_204501
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776545118448}


run_id: WRAP_20260418_204501
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776545120655}


run_id: WRAP_20260418_204501
stream_name: stdout
message:
[balance fetch] bybit {"retCode":10003,"retMsg":"API key is invalid.","result":{},"retExtInfo":{},"time":1776545123203}


run_id: WRAP_20260418_204834
stream_name: stdout
message:
  portfolio: {'initial_equity_per_leg': 100.0, 'fee_rate': 0.001, 'slippage_per_side': 4.0, 'max_notional_frac': 1.0, 'position_notional_long': 1.2, 'position_notional_short': 1.2}


run_id: WRAP_20260418_204834
stream_name: stdout
message:
  strategy_params_long: {'firstBuyQtyCoin': 20, 'minOrderQtyCoin': 20, 'minOrderUSDT': 1.2, 'minLongInvestPct': 2.0, 'useEquityPctBase': True, 'baseOrderPctEq': 2, 'equityForSizingUSDT': 100.0, 'tpPercent': 0.25, 'callbackPercent': 0.060000000000000005, 'marginCallLimit': 244, 'linearDropPercent': 0.19, 'autoMerge': False, 'subSellTPPercent': 0.44, 'requireCloseAboveFullTP': True, 'subSellCloseConfirmMode': 'breakeven', 'requireCloseBelowDcaLevel': True, 'blockDcaOnTpTouch': False, 'drop1': 0.3, 'drop2': 0.4, 'drop3': 0.6, 'drop4': 0.8, 'drop5': 0.8, 'mult2': 1.7, 'mult3': 1.0, 'mult4': 2.0, 'mult5': 3.5, 'maxFillsPerBar': 6, 'maxSubSellsPerBar': 10, 'useHighLowTouch': True, 'useLiveSyncStart': False, 'liveStartTime': 0, 'maxOrdersPer3Min': 14, 'useTrendAdaptiveSizing': True, 'trendMaTf': 'W', 'trendMaLen': 20, 'trendSlopeBars': 3, 'trendSlopeLongBoundPct': 1.0, 'trendSlopeShortBoundPct': -1.0, 'trendScoreMinPct': 45.0, 'trendScoreMaxPct': 75.0, 'maxLongInvestPct': 2.2, 'hardBreakevenDeleveragePct': 50.0, 'useEvenBars': False}


run_id: WRAP_20260418_204834
stream_name: stdout
message:
  strategy_params_short: {'firstSellQtyCoin': 20, 'minOrderQtyCoin': 20, 'minOrderUSDT': 1.2, 'minShortInvestPct': 2.0, 'useEquityPctBase': True, 'baseOrderPctEq': 2, 'equityForSizingUSDT': 100.0, 'tpPercent': 0.19, 'callbackPercent': 0.155, 'marginCallLimit': 244, 'linearRisePercent': 0.16, 'autoMerge': False, 'subSellTPPercent': 0.42, 'requireCloseBelowFullTP': True, 'subCoverCloseConfirmMode': 'breakeven', 'requireCloseAboveDcaLevel': True, 'blockDcaOnTpTouch': False, 'rise1': 0.32999999999999996, 'rise2': 0.4, 'rise3': 0.6, 'rise4': 0.8, 'rise5': 0.8, 'mult2': 1.6, 'mult3': 1.0, 'mult4': 2.0, 'mult5': 3.5, 'maxFillsPerBar': 6, 'maxSubSellsPerBar': 10, 'useHighLowTouch': True, 'useLiveSyncStart': False, 'liveStartTime': 0, 'maxOrdersPer3Min': 14, 'useTrendAdaptiveSizing': True, 'trendMaTf': 'W', 'trendMaLen': 20, 'trendSlopeBars': 3, 'trendSlopeLongBoundPct': 1.0, 'trendSlopeShortBoundPct': -1.0, 'trendScoreMinPct': 45.0, 'trendScoreMaxPct': 75.0, 'maxShortInvestPct': 2.4, 'hardBreakevenDeleveragePct': 50.0, 'useEvenBars': False}


run_id: WRAP_20260419_062503
stream_name: stdout
message:
[auth_probe_ok] {"balance_keys": ["free", "info", "total", "used"], "credentials": {"exchange": "bingx", "key_aliases_checked": ["BINGX_KEY", "BINGX_API_KEY", "BINGX_KEY", "BINGX_API_KEY", "BYBIT_KEY", "BYBIT_API_KEY", "API_KEY", "CCXT_API_KEY"], "key_found": true, "secret_aliases_checked": ["BINGX_SECRET", "BINGX_API_SECRET", "BINGX_SECRET", "BINGX_API_SECRET", "BYBIT_SECRET", "BYBIT_API_SECRET", "API_SECRET", "CCXT_SECRET"], "secret_found": true}, "credentials_present": true, "fetch_balance_ok": true}


run_id: WRAP_20260419_062503
stream_name: stdout
message:
[close_fail] {"exchange_response": {"error": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "ok": false, "qty": 20.0}, "partial": false, "qty": 20.0, "reason": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "requested_px": 0.1197, "side": "LONG", "symbol": "ENA/USDT:USDT"}


run_id: WRAP_20260419_062503
stream_name: stdout
message:
[close_fail] {"exchange_response": {"error": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "ok": false, "qty": 20.0}, "partial": false, "qty": 20.0, "reason": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "requested_px": 0.12, "side": "LONG", "symbol": "ENA/USDT:USDT"}


run_id: WRAP_20260419_062503
stream_name: stdout
message:
[close_fail] {"exchange_response": {"error": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "ok": false, "qty": 20.0}, "partial": false, "qty": 20.0, "reason": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "requested_px": 0.1205, "side": "LONG", "symbol": "ENA/USDT:USDT"}


run_id: WRAP_20260419_062503
stream_name: stdout
message:
[close_fail] {"exchange_response": {"error": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "ok": false, "qty": 20.0}, "partial": false, "qty": 20.0, "reason": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "requested_px": 0.1204, "side": "LONG", "symbol": "ENA/USDT:USDT"}


run_id: WRAP_20260419_062503
stream_name: stdout
message:
[close_fail] {"exchange_response": {"error": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "ok": false, "qty": 20.0}, "partial": false, "qty": 20.0, "reason": "bingx {\"code\":109400,\"msg\":\"In the Hedge mode, the 'ReduceOnly' field can not be filled.\",\"data\":{}}", "requested_px": 0.1208, "side": "LONG", "symbol": "ENA/USDT:USDT"}


run_id: WRAP_20260419_064123
stream_name: stdout
message:
[open_ok] {"entry": 0.1211, "entry_lag_sec": 29.0, "entry_slip_bp": 16.542597187758634, "fill": 0.1211, "order_id": "2045754641946468353", "qty": 20.0, "side": "LONG", "symbol": "ENA/USDT:USDT"}


run_id: WRAP_20260419_064123
stream_name: stdout
message:
[open_ok] {"entry": 0.1209, "entry_lag_sec": 31.0, "entry_slip_bp": -0.0, "fill": 0.1209, "order_id": "2045754649957588993", "qty": 20.0, "side": "SHORT", "symbol": "ENA/USDT:USDT"}


run_id: WRAP_20260419_064123
stream_name: stdout
message:
[close_ok] {"close_reason": "TP Full (Trailing)", "closed": true, "fill": 0.1206, "qty": 20.0, "side": "SHORT", "symbol": "ENA/USDT:USDT"}


run_id: WRAP_20260419_064123
stream_name: stdout
message:
[open_ok] {"entry": 0.1204, "entry_lag_sec": 6.0, "entry_slip_bp": 16.583747927031432, "fill": 0.1204, "order_id": "2045755047095263233", "qty": 20.0, "side": "SHORT", "symbol": "ENA/USDT:USDT"}


# run_meta

run_id: WRAP_20260418_152500
status: stopped
extra_json: {"wrapper": "bt_live_paper_runner_separated_universe_4.py"}
argv_json:
["bt_live_paper_runner_separated_universe_4.py", "--mode", "live", "--env-file", ".env", "--cfg", "configs/final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml", "--exchange", "bingx", "--symbol-format", "usdtm", "--poll-sec", "2", "--bar-delay-sec", "1", "--limit_klines", "300", "--prewarm-bars", "300", "--results-dir", "_reports/_live/bingx_ena_bundle", "--session-db", "session.sqlite", "--cache-out", "combined_cache_session.db", "--hour-cache", "save", "--universe-file", "universe/universe_ENA_1m.txt", "--debug"]

env_json:
{"cfg": "configs/final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml", "exchange": "bingx", "mode": "live", "paper_source": "api", "results_dir": "_reports/_live/bingx_ena_bundle"}

platform_json:
{"executable": "/var/www/vps2.happyuser.info/top/backtest_SK/.venv38/bin/python3", "platform": "Linux-5.0.16-100.fc28.x86_64-x86_64-with-glibc2.2.5", "python": "3.8.18 (default, Aug  8 2025, 19:31:55) \n[GCC 8.3.1 20190223 (Red Hat 8.3.1-2)]"}


run_id: WRAP_20260418_202753
status: stopped
extra_json: {"wrapper": "bt_live_paper_runner_separated_universe_4.py"}
argv_json:
["bt_live_paper_runner_separated_universe_4.py", "--mode", "live", "--env-file", ".env", "--cfg", "configs/final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml", "--exchange", "bybit", "--symbol-format", "usdtm", "--poll-sec", "2", "--bar-delay-sec", "1", "--limit_klines", "300", "--prewarm-bars", "300", "--results-dir", "_reports/_live/bingx_ena_bundle", "--session-db", "session.sqlite", "--cache-out", "combined_cache_session.db", "--hour-cache", "save", "--universe-file", "universe/universe_ENA_1m.txt", "--debug"]

env_json:
{"cfg": "configs/final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml", "exchange": "bybit", "mode": "live", "paper_source": "api", "results_dir": "_reports/_live/bingx_ena_bundle"}


run_id: WRAP_20260419_062320
status: stopped
extra_json: {"wrapper": "bt_live_paper_runner_separated_universe_4.py"}
argv_json:
["bt_live_paper_runner_separated_universe_4.py", "--mode", "live", "--env-file", ".env", "--cfg", "configs/final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml", "--exchange", "bingx", "--symbol-format", "usdtm", "--poll-sec", "2", "--bar-delay-sec", "1", "--limit_klines", "300", "--prewarm-bars", "300", "--results-dir", "_reports/_live/bingx_ena_bundle", "--session-db", "session.sqlite", "--cache-out", "combined_cache_session.db", "--hour-cache", "save", "--universe-file", "universe/universe_ENA_1m.txt", "--live-runner-module", "live_runner_dual_restored_full_fixed", "--debug"]


run_id: WRAP_20260419_062503
status: stopped
extra_json: {"wrapper": "bt_live_paper_runner_separated_universe_4.py"}
argv_json:
["bt_live_paper_runner_separated_universe_4.py", "--mode", "live", "--env-file", ".env", "--cfg", "configs/final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml", "--exchange", "bingx", "--symbol-format", "usdtm", "--poll-sec", "2", "--bar-delay-sec", "1", "--limit_klines", "300", "--prewarm-bars", "300", "--results-dir", "_reports/_live/bingx_ena_bundle", "--session-db", "session.sqlite", "--cache-out", "combined_cache_session.db", "--hour-cache", "save", "--universe-file", "universe/universe_ENA_1m.txt", "--live-runner-module", "runners.live_runner_dual", "--debug"]


# code_snapshots

run_id: WRAP_20260418_152500
label: bt_live_paper_runner_separated_universe_4.py
path: bt_live_paper_runner_separated_universe_4.py
sha256: d997ca308725ed5b2e67aba046ccab1d506cf1bad212f601609125b34ebcb68a
text_content:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from __future__ import annotations

import argparse
import os
import sys
import time
from typing import Any, Dict, List

try:
    from runners.live_debug_bundle import (
        ensure_live_debug_bundle_db,
        install_stdio_capture,
        record_run_meta,
        snapshot_files,
        debug_event,
        finalize_bundle,
        exception_text,
    )
except Exception:
    def ensure_live_debug_bundle_db(db_path: str) -> None:
        return None
    def install_stdio_capture(db_path: str, run_id: str):
        return lambda: None
    def record_run_meta(db_path: str, run_id: str, argv=None, env=None, extra=None) -> None:
        return None
    def snapshot_files(db_path: str, run_id: str, paths):
        return None
    def debug_event(db_path: str, run_id: str, event_type: str, payload=None, level: str = 'INFO') -> None:
        return None
    def finalize_bundle(db_path: str, run_id: str, status: str = 'ok', error_text: str = '', results_dir: str = '', extra_files=None):
        return None
    def exception_text() -> str:
        return ''


def _read_text(path: str) -> str:
    with open(path, 'r', encoding='utf-8') as f:
        return f.read()


def _load_yaml_or_json(path: str) -> Dict[str, Any]:
    if path.endswith('.json'):
        import json
        return json.loads(_read_text(path))
    import yaml
    return yaml.safe_load(_read_text(path))


def _split_csv(s: str) -> List[str]:
    return [x.strip() for x in str(s or '').split(',') if x.strip()]


def _read_universe_file(path: str) -> List[str]:
    syms: List[str] = []
    if not path:
        return syms
    try:
        if not os.path.isabs(path):
            udir = os.path.join(os.path.dirname(__file__), 'universe')
            path = os.path.join(udir, os.path.basename(path))
        with open(path, 'r', encoding='utf-8') as f:
            for ln in f:
                ln = ln.strip()
                if ln and not ln.startswith('#'):
                    syms.append(ln)
    except Exception:
        pass
    return syms


def _merge_universe(cfg_uni: Dict[str, Any], file_syms: List[str], allow_cli: List[str], deny_cli: List[str]) -> Dict[str, Any]:
    uni = dict(cfg_uni or {})
    allow = set(uni.get('allow', []) or [])
    deny = set(uni.get('deny', []) or [])
    allow.update(file_syms)
    allow.update(allow_cli)
    deny.update(deny_cli)
    if file_syms and 'file' not in uni:
        uni['file'] = '<cli>'
    uni['allow'] = sorted(allow)
    uni['deny'] = sorted(deny)
    return uni


def _hint_restrict_symbols(cfg: Dict[str, Any], allow: List[str]) -> None:
    if allow:
        cfg.setdefault('universe', {})['allow'] = list(allow)
        cfg.setdefault('md_builder', {})['restrict_to_symbols'] = list(allow)
        cfg['symbols_whitelist'] = list(allow)
        os.environ['RS_UNIVERSE_ALLOW'] = ','.join(allow)
        os.environ['RS_SYMBOLS_WHITELIST'] = ','.join(allow)


def _run_backtest(cfg_path: str, limit_bars: int | None):
    bt_entry = os.path.join(os.getcwd(), 'backtester_core.py')
    if not os.path.exists(bt_entry):
        raise SystemExit('backtester_core.py not found. Run from the project root.')
    cmd = [sys.executable, bt_entry, '--cfg', cfg_path]
    if limit_bars and int(limit_bars) > 0:
        cmd += ['--limit-bars', str(int(limit_bars))]
    print('[backtest] exec:', ' '.join(cmd))
    os.execvp(sys.executable, cmd)


def _is_dual_cfg(cfg: Dict[str, Any]) -> bool:
    return bool(cfg.get('strategy_class_long') and cfg.get('strategy_class_short'))


def _run_live(cfg: Dict[str, Any], args):
    if _is_dual_cfg(cfg):
        try:
            from runners.live_runner_dual import run_live as _run_live_dual
            print('[live] using runners.live_runner_dual.run_live')
            return _run_live_dual(cfg, args)
        except Exception as e:
            print('[live] runners.live_runner_dual.run_live not available:', e)
            print('[live] falling back to runners.live_runner.run_live')
    try:
        from runners.live_runner import run_live as _run_live_single
        print('[live] using runners.live_runner.run_live')
        return _run_live_single(cfg, args)
    except Exception as e:
        print('[live] runners.live_runner.run_live not available:', e)
        print('[live] Falling back to heartbeat... (CTRL+C to exit)')
        while True:
            print('.', end='', flush=True)
            time.sleep(max(1, int(getattr(args, 'poll_sec', 10) or 10)))


def _run_paper_api(cfg: Dict[str, Any], args):
    try:
        from runners.paper_api_runner import run_paper_api as _run_paper_api
        return _run_paper_api(cfg, args)
    except Exception as e:
        print('[paper-api] runners.paper_api_runner.run_paper_api not available:', e)
        print('[paper-api] Using minimal fallback loop with heartbeat only.')
        poll = int(getattr(args, 'poll_sec', 10) or 10)
        while True:
            print('.', end='', flush=True)
            time.sleep(poll)


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument('--mode', choices=['backtest', 'paper', 'live'], required=True)
    ap.add_argument('--paper-source', choices=['db', 'api'], default='api')
    ap.add_argument('--orders-db', default='')
    ap.add_argument('--cfg', required=True)
    ap.add_argument('--db')
    ap.add_argument('--results-dir', default='')
    ap.add_argument('--limit-bars', type=int, default=0)
    ap.add_argument('--session-db', default='')
    ap.add_argument('--cache-out', default='')
    ap.add_argument('--hour-cache', choices=['off', 'save', 'load'], default='off')
    ap.add_argument('--env-file', default='')
    ap.add_argument('--exchange', default='bingx')
    ap.add_argument('--symbol-format', default='usdtm')
    ap.add_argument('--poll-sec', type=int, default=2)
    ap.add_argument('--bar-delay-sec', type=int, default=1)
    ap.add_argument('--limit_klines', type=int, default=180)
    ap.add_argument('--prewarm-bars', type=int, default=None)
    ap.add_argument('--prewarm-hours', type=int, default=None)
    ap.add_argument('--debug', action='store_true')
    ap.add_argument('--heat-report', action='store_true')
    ap.add_argument('--universe-file', default='')
    ap.add_argument('--allow-symbols', default='')
    ap.add_argument('--deny-symbols', default='')
    args = ap.parse_args()

    cfg_name = os.path.splitext(os.path.basename(args.cfg))[0]
    cfg = _load_yaml_or_json(args.cfg)
    timeframe = str(cfg.get('timeframe') or 'na')
    if not args.results_dir:
        args.results_dir = os.path.join('_reports', '_live', f'livecfg_{cfg_name}_{timeframe}')
    os.makedirs(args.results_dir, exist_ok=True)
    if args.session_db:
        if not os.path.isabs(args.session_db) and os.path.dirname(args.session_db) == '':
            args.session_db = os.path.join(args.results_dir, args.session_db)
    else:
        args.session_db = os.path.join(args.results_dir, 'session.sqlite')
    if args.cache_out:
        if not os.path.isabs(args.cache_out) and os.path.dirname(args.cache_out) == '':
            args.cache_out = os.path.join(args.results_dir, args.cache_out)
    else:
        args.cache_out = os.path.join(args.results_dir, 'combined_cache_session.db')
    if not args.orders_db:
        args.orders_db = args.session_db
    print(f'[results] dir: {args.results_dir}')

    bundle_run_id = time.strftime('WRAP_%Y%m%d_%H%M%S')
    ensure_live_debug_bundle_db(args.session_db)
    restore_stdio = install_stdio_capture(args.session_db, bundle_run_id)
    record_run_meta(args.session_db, bundle_run_id, argv=sys.argv, env={
        'mode': args.mode,
        'paper_source': args.paper_source,
        'exchange': args.exchange,
        'results_dir': args.results_dir,
        'cfg': args.cfg,
    }, extra={'wrapper': os.path.basename(__file__)})
    snapshot_files(args.session_db, bundle_run_id, [__file__, args.cfg])
    debug_event(args.session_db, bundle_run_id, 'wrapper_start', {'mode': args.mode, 'results_dir': args.results_dir})

    cfg_uni = cfg.get('universe', {}) or {}
    file_syms = _read_universe_file(args.universe_file or cfg.get('universe_file', ''))
    allow_cli = _split_csv(args.allow_symbols)
    deny_cli = _split_csv(args.deny_symbols)
    uni = _merge_universe(cfg_uni, file_syms, allow_cli, deny_cli)
    cfg['universe'] = uni
    _hint_restrict_symbols(cfg, list(uni.get('allow', []) or []))

    try:
        if args.mode == 'backtest':
            _run_backtest(args.cfg, args.limit_bars)
        elif args.mode == 'paper':
            if args.paper_source == 'api':
                _run_paper_api(cfg, args)
            else:
                raise SystemExit('paper --paper-source=db is not implemented in this wrapper version')
        else:
            _run_live(cfg, args)
    except KeyboardInterrupt:
        debug_event(args.session_db, bundle_run_id, 'wrapper_stop', {'reason': 'keyboard_interrupt'})
        finalize_bundle(args.session_db, bundle_run_id, status='stopped', results_dir=args.results_dir)
        restore_stdio()
        raise
    except Exception:
        err = exception_text()
        debug_event(args.session_db, bundle_run_id, 'wrapper_error', {'traceback': err}, level='ERROR')
        finalize_bundle(args.session_db, bundle_run_id, status='error', error_text=err, results_dir=args.results_dir)
        restore_stdio()
        raise


if __name__ == '__main__':
    main()


run_id: WRAP_20260418_152500
label: final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml
path: configs/final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml
sha256: 0bacd51455956d331c6e8982b638b9610d019e9e5b29c27774bedf957e376609
text_content:
live: true
source: api
timeframe: 0.5m
portfolio:
  initial_equity_per_leg: 100.0
  fee_rate: 0.001
  slippage_per_side: 4.0
  max_notional_frac: 1.0
strategy_class_long: strategies.cryptomine_pack_dual_full.CryptomineLongPackAdaptiveEven
strategy_class_short: strategies.cryptomine_pack_dual_full.CryptomineShortPackAdaptiveEven
strategy_params_long:
  firstBuyQtyCoin: 0.09
  minOrderQtyCoin: 0.09
  minOrderUSDT: 2.0
  useEquityPctBase: true
  baseOrderPctEq: 0.6
  equityForSizingUSDT: 100.0
  tpPercent: 0.25
  callbackPercent: 0.060000000000000005
  marginCallLimit: 244
  linearDropPercent: 0.19
  autoMerge: false
  subSellTPPercent: 0.44
  requireCloseAboveFullTP: true
  subSellCloseConfirmMode: breakeven
  requireCloseBelowDcaLevel: true
  blockDcaOnTpTouch: false
  drop1: 0.3
  drop2: 0.4
  drop3: 0.6
  drop4: 0.8
  drop5: 0.8
  mult2: 1.7
  mult3: 1.0
  mult4: 2.0
  mult5: 3.5
  maxFillsPerBar: 6
  maxSubSellsPerBar: 10
  useHighLowTouch: true
  useLiveSyncStart: false
  liveStartTime: 0
  maxOrdersPer3Min: 14
  useTrendAdaptiveSizing: true
  trendMaTf: W
  trendMaLen: 20
  trendSlopeBars: 3
  trendSlopeLongBoundPct: 1.0
  trendSlopeShortBoundPct: -1.0
  trendScoreMinPct: 45.0
  trendScoreMaxPct: 75.0
  minLongInvestPct: 0.5
  maxLongInvestPct: 2.2
  hardBreakevenDeleveragePct: 50.0
  useEvenBars: false
strategy_params_short:
  firstSellQtyCoin: 0.09
  minOrderQtyCoin: 0.09
  minOrderUSDT: 2.0
  useEquityPctBase: true
  baseOrderPctEq: 0.6
  equityForSizingUSDT: 100.0
  tpPercent: 0.19
  callbackPercent: 0.155
  marginCallLimit: 244
  linearRisePercent: 0.16
  autoMerge: false
  subSellTPPercent: 0.42
  requireCloseBelowFullTP: true
  subCoverCloseConfirmMode: breakeven
  requireCloseAboveDcaLevel: true
  blockDcaOnTpTouch: false
  rise1: 0.32999999999999996
  rise2: 0.4
  rise3: 0.6
  rise4: 0.8
  rise5: 0.8
  mult2: 1.6
  mult3: 1.0
  mult4: 2.0
  mult5: 3.5
  maxFillsPerBar: 6
  maxSubSellsPerBar: 10
  useHighLowTouch: true
  useLiveSyncStart: false
  liveStartTime: 0
  maxOrdersPer3Min: 14
  useTrendAdaptiveSizing: true
  trendMaTf: W
  trendMaLen: 20
  trendSlopeBars: 3
  trendSlopeLongBoundPct: 1.0
  trendSlopeShortBoundPct: -1.0
  trendScoreMinPct: 45.0
  trendScoreMaxPct: 75.0
  minShortInvestPct: 0.5
  maxShortInvestPct: 2.4
  hardBreakevenDeleveragePct: 50.0
  useEvenBars: false
runner:
  prewarm:
    bars: 200


run_id: WRAP_20260418_192049
label: final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml
path: configs/final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml
sha256: eec11964dd2856268a71e27cdd8c1ca4e8d8067eb3af9faaefc57da45f3ccdfd
text_content:
live: true
source: api
timeframe: 0.5m
portfolio:
  initial_equity_per_leg: 100.0
  fee_rate: 0.001
  slippage_per_side: 4.0
  max_notional_frac: 1.0
  position_notional_long: 2.0
  position_notional_short: 2.0
strategy_class_long: strategies.cryptomine_pack_dual_full.CryptomineLongPackAdaptiveEven
strategy_class_short: strategies.cryptomine_pack_dual_full.CryptomineShortPackAdaptiveEven
strategy_params_long:
  firstBuyQtyCoin: 0.09
  minOrderQtyCoin: 0.09
  minOrderUSDT: 2.0
  useEquityPctBase: true
  baseOrderPctEq: 0.6
  equityForSizingUSDT: 100.0
  tpPercent: 0.25
  callbackPercent: 0.060000000000000005
  marginCallLimit: 244
  linearDropPercent: 0.19
  autoMerge: false
  subSellTPPercent: 0.44
  requireCloseAboveFullTP: true
  subSellCloseConfirmMode: breakeven
  requireCloseBelowDcaLevel: true
  blockDcaOnTpTouch: false
  drop1: 0.3
  drop2: 0.4
  drop3: 0.6
  drop4: 0.8
  drop5: 0.8
  mult2: 1.7
  mult3: 1.0
  mult4: 2.0
  mult5: 3.5
  maxFillsPerBar: 6
  maxSubSellsPerBar: 10
  useHighLowTouch: true
  useLiveSyncStart: false
  liveStartTime: 0
  maxOrdersPer3Min: 14
  useTrendAdaptiveSizing: true
  trendMaTf: W
  trendMaLen: 20
  trendSlopeBars: 3
  trendSlopeLongBoundPct: 1.0
  trendSlopeShortBoundPct: -1.0
  trendScoreMinPct: 45.0
  trendScoreMaxPct: 75.0
  minLongInvestPct: 2.0
  maxLongInvestPct: 2.2
  hardBreakevenDeleveragePct: 50.0
  useEvenBars: false
strategy_params_short:
  firstSellQtyCoin: 0.09
  minOrderQtyCoin: 0.09
  minOrderUSDT: 2.0
  useEquityPctBase: true
  baseOrderPctEq: 0.6
  equityForSizingUSDT: 100.0
  tpPercent: 0.19
  callbackPercent: 0.155
  marginCallLimit: 244
  linearRisePercent: 0.16
  autoMerge: false
  subSellTPPercent: 0.42
  requireCloseBelowFullTP: true
  subCoverCloseConfirmMode: breakeven
  requireCloseAboveDcaLevel: true
  blockDcaOnTpTouch: false
  rise1: 0.32999999999999996
  rise2: 0.4
  rise3: 0.6
  rise4: 0.8
  rise5: 0.8
  mult2: 1.6
  mult3: 1.0
  mult4: 2.0
  mult5: 3.5
  maxFillsPerBar: 6
  maxSubSellsPerBar: 10
  useHighLowTouch: true
  useLiveSyncStart: false
  liveStartTime: 0
  maxOrdersPer3Min: 14
  useTrendAdaptiveSizing: true
  trendMaTf: W
  trendMaLen: 20
  trendSlopeBars: 3
  trendSlopeLongBoundPct: 1.0
  trendSlopeShortBoundPct: -1.0
  trendScoreMinPct: 45.0
  trendScoreMaxPct: 75.0
  minShortInvestPct: 2.0
  maxShortInvestPct: 2.4
  hardBreakevenDeleveragePct: 50.0
  useEvenBars: false
runner:
  prewarm:
    bars: 200


run_id: WRAP_20260418_193249
label: final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml
path: configs/final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml
sha256: 396e91b117b98a42fbc451b92e80037ebe2ee36718e47497e7c039e24e79efcd
text_content:
live: true
source: api
timeframe: 0.5m
portfolio:
  initial_equity_per_leg: 100.0
  fee_rate: 0.001
  slippage_per_side: 4.0
  max_notional_frac: 1.0
  position_notional_long: 2.0
  position_notional_short: 2.0
strategy_class_long: strategies.cryptomine_pack_dual_full.CryptomineLongPackAdaptiveEven
strategy_class_short: strategies.cryptomine_pack_dual_full.CryptomineShortPackAdaptiveEven
strategy_params_long:
  firstBuyQtyCoin: 0.09
  minOrderQtyCoin: 0.09
  minOrderUSDT: 2.0
  useEquityPctBase: true
  baseOrderPctEq: 2
  equityForSizingUSDT: 100.0
  tpPercent: 0.25
  callbackPercent: 0.060000000000000005
  marginCallLimit: 244
  linearDropPercent: 0.19
  autoMerge: false
  subSellTPPercent: 0.44
  requireCloseAboveFullTP: true
  subSellCloseConfirmMode: breakeven
  requireCloseBelowDcaLevel: true
  blockDcaOnTpTouch: false
  drop1: 0.3
  drop2: 0.4
  drop3: 0.6
  drop4: 0.8
  drop5: 0.8
  mult2: 1.7
  mult3: 1.0
  mult4: 2.0
  mult5: 3.5
  maxFillsPerBar: 6
  maxSubSellsPerBar: 10
  useHighLowTouch: true
  useLiveSyncStart: false
  liveStartTime: 0
  maxOrdersPer3Min: 14
  useTrendAdaptiveSizing: true
  trendMaTf: W
  trendMaLen: 20
  trendSlopeBars: 3
  trendSlopeLongBoundPct: 1.0
  trendSlopeShortBoundPct: -1.0
  trendScoreMinPct: 45.0
  trendScoreMaxPct: 75.0
  minLongInvestPct: 2.0
  maxLongInvestPct: 2.2
  hardBreakevenDeleveragePct: 50.0
  useEvenBars: false
strategy_params_short:
  firstSellQtyCoin: 0.09
  minOrderQtyCoin: 0.09
  minOrderUSDT: 2.0
  useEquityPctBase: true
  baseOrderPctEq: 2
  equityForSizingUSDT: 100.0
  tpPercent: 0.19
  callbackPercent: 0.155
  marginCallLimit: 244
  linearRisePercent: 0.16
  autoMerge: false
  subSellTPPercent: 0.42
  requireCloseBelowFullTP: true
  subCoverCloseConfirmMode: breakeven
  requireCloseAboveDcaLevel: true
  blockDcaOnTpTouch: false
  rise1: 0.32999999999999996
  rise2: 0.4
  rise3: 0.6
  rise4: 0.8
  rise5: 0.8
  mult2: 1.6
  mult3: 1.0
  mult4: 2.0
  mult5: 3.5
  maxFillsPerBar: 6
  maxSubSellsPerBar: 10
  useHighLowTouch: true
  useLiveSyncStart: false
  liveStartTime: 0
  maxOrdersPer3Min: 14
  useTrendAdaptiveSizing: true
  trendMaTf: W
  trendMaLen: 20
  trendSlopeBars: 3
  trendSlopeLongBoundPct: 1.0
  trendSlopeShortBoundPct: -1.0
  trendScoreMinPct: 45.0
  trendScoreMaxPct: 75.0
  minShortInvestPct: 2.0
  maxShortInvestPct: 2.4
  hardBreakevenDeleveragePct: 50.0
  useEvenBars: false
runner:
  prewarm:
    bars: 200


run_id: WRAP_20260418_193445
label: final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml
path: configs/final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml
sha256: 6a1c2fdee92a87115a17870dd6d6009df2d1fade65e6060bda3e06b4645a69d2
text_content:
live: true
source: api
timeframe: 0.5m
portfolio:
  initial_equity_per_leg: 100.0
  fee_rate: 0.001
  slippage_per_side: 4.0
  max_notional_frac: 1.0
  position_notional_long: 2.0
  position_notional_short: 2.0
strategy_class_long: strategies.cryptomine_pack_dual_full.CryptomineLongPackAdaptiveEven
strategy_class_short: strategies.cryptomine_pack_dual_full.CryptomineShortPackAdaptiveEven
strategy_params_long:
  firstBuyQtyCoin: 20
  minOrderQtyCoin: 20
  minOrderUSDT: 2.0
  useEquityPctBase: true
  baseOrderPctEq: 2
  equityForSizingUSDT: 100.0
  tpPercent: 0.25
  callbackPercent: 0.060000000000000005
  marginCallLimit: 244
  linearDropPercent: 0.19
  autoMerge: false
  subSellTPPercent: 0.44
  requireCloseAboveFullTP: true
  subSellCloseConfirmMode: breakeven
  requireCloseBelowDcaLevel: true
  blockDcaOnTpTouch: false
  drop1: 0.3
  drop2: 0.4
  drop3: 0.6
  drop4: 0.8
  drop5: 0.8
  mult2: 1.7
  mult3: 1.0
  mult4: 2.0
  mult5: 3.5
  maxFillsPerBar: 6
  maxSubSellsPerBar: 10
  useHighLowTouch: true
  useLiveSyncStart: false
  liveStartTime: 0
  maxOrdersPer3Min: 14
  useTrendAdaptiveSizing: true
  trendMaTf: W
  trendMaLen: 20
  trendSlopeBars: 3
  trendSlopeLongBoundPct: 1.0
  trendSlopeShortBoundPct: -1.0
  trendScoreMinPct: 45.0
  trendScoreMaxPct: 75.0
  minLongInvestPct: 2.0
  maxLongInvestPct: 2.2
  hardBreakevenDeleveragePct: 50.0
  useEvenBars: false
strategy_params_short:
  firstSellQtyCoin: 20
  minOrderQtyCoin: 20
  minOrderUSDT: 2.0
  useEquityPctBase: true
  baseOrderPctEq: 2
  equityForSizingUSDT: 100.0
  tpPercent: 0.19
  callbackPercent: 0.155
  marginCallLimit: 244
  linearRisePercent: 0.16
  autoMerge: false
  subSellTPPercent: 0.42
  requireCloseBelowFullTP: true
  subCoverCloseConfirmMode: breakeven
  requireCloseAboveDcaLevel: true
  blockDcaOnTpTouch: false
  rise1: 0.32999999999999996
  rise2: 0.4
  rise3: 0.6
  rise4: 0.8
  rise5: 0.8
  mult2: 1.6
  mult3: 1.0
  mult4: 2.0
  mult5: 3.5
  maxFillsPerBar: 6
  maxSubSellsPerBar: 10
  useHighLowTouch: true
  useLiveSyncStart: false
  liveStartTime: 0
  maxOrdersPer3Min: 14
  useTrendAdaptiveSizing: true
  trendMaTf: W
  trendMaLen: 20
  trendSlopeBars: 3
  trendSlopeLongBoundPct: 1.0
  trendSlopeShortBoundPct: -1.0
  trendScoreMinPct: 45.0
  trendScoreMaxPct: 75.0
  minShortInvestPct: 2.0
  maxShortInvestPct: 2.4
  hardBreakevenDeleveragePct: 50.0
  useEvenBars: false
runner:
  prewarm:
    bars: 200


run_id: WRAP_20260418_193555
label: final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml
path: configs/final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml
sha256: ceb85c394f080537ee31ceb9f691681ea96d0dd80a09c3cc51de4a1bc48e2104
text_content:
live: true
source: api
timeframe: 0.5m
portfolio:
  initial_equity_per_leg: 100.0
  fee_rate: 0.001
  slippage_per_side: 4.0
  max_notional_frac: 1.0
  position_notional_long: 2.0
  position_notional_short: 2.0
strategy_class_long: strategies.cryptomine_pack_dual_full.CryptomineLongPackAdaptiveEven
strategy_class_short: strategies.cryptomine_pack_dual_full.CryptomineShortPackAdaptiveEven
strategy_params_long:
  firstBuyQtyCoin: 20
  minOrderQtyCoin: 20
  minOrderUSDT: 2.0
  minLongInvestPct: 2.0
  useEquityPctBase: true
  baseOrderPctEq: 2
  equityForSizingUSDT: 100.0
  tpPercent: 0.25
  callbackPercent: 0.060000000000000005
  marginCallLimit: 244
  linearDropPercent: 0.19
  autoMerge: false
  subSellTPPercent: 0.44
  requireCloseAboveFullTP: true
  subSellCloseConfirmMode: breakeven
  requireCloseBelowDcaLevel: true
  blockDcaOnTpTouch: false
  drop1: 0.3
  drop2: 0.4
  drop3: 0.6
  drop4: 0.8
  drop5: 0.8
  mult2: 1.7
  mult3: 1.0
  mult4: 2.0
  mult5: 3.5
  maxFillsPerBar: 6
  maxSubSellsPerBar: 10
  useHighLowTouch: true
  useLiveSyncStart: false
  liveStartTime: 0
  maxOrdersPer3Min: 14
  useTrendAdaptiveSizing: true
  trendMaTf: W
  trendMaLen: 20
  trendSlopeBars: 3
  trendSlopeLongBoundPct: 1.0
  trendSlopeShortBoundPct: -1.0
  trendScoreMinPct: 45.0
  trendScoreMaxPct: 75.0
  minLongInvestPct: 2.0
  maxLongInvestPct: 2.2
  hardBreakevenDeleveragePct: 50.0
  useEvenBars: false
strategy_params_short:
  firstSellQtyCoin: 20
  minOrderQtyCoin: 20
  minOrderUSDT: 2.0
  minShortInvestPct: 2.0
  useEquityPctBase: true
  baseOrderPctEq: 2
  equityForSizingUSDT: 100.0
  tpPercent: 0.19
  callbackPercent: 0.155
  marginCallLimit: 244
  linearRisePercent: 0.16
  autoMerge: false
  subSellTPPercent: 0.42
  requireCloseBelowFullTP: true
  subCoverCloseConfirmMode: breakeven
  requireCloseAboveDcaLevel: true
  blockDcaOnTpTouch: false
  rise1: 0.32999999999999996
  rise2: 0.4
  rise3: 0.6
  rise4: 0.8
  rise5: 0.8
  mult2: 1.6
  mult3: 1.0
  mult4: 2.0
  mult5: 3.5
  maxFillsPerBar: 6
  maxSubSellsPerBar: 10
  useHighLowTouch: true
  useLiveSyncStart: false
  liveStartTime: 0
  maxOrdersPer3Min: 14
  useTrendAdaptiveSizing: true
  trendMaTf: W
  trendMaLen: 20
  trendSlopeBars: 3
  trendSlopeLongBoundPct: 1.0
  trendSlopeShortBoundPct: -1.0
  trendScoreMinPct: 45.0
  trendScoreMaxPct: 75.0
  minShortInvestPct: 2.0
  maxShortInvestPct: 2.4
  hardBreakevenDeleveragePct: 50.0
  useEvenBars: false
runner:
  prewarm:
    bars: 200


run_id: WRAP_20260418_204834
label: final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml
path: configs/final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar.yaml
sha256: 32354c1e44536ecc558f23ad1fde162f8de063cc00928c37a1b2398ae010e64b
text_content:
live: true
source: api
timeframe: 0.5m
portfolio:
  initial_equity_per_leg: 100.0
  fee_rate: 0.001
  slippage_per_side: 4.0
  max_notional_frac: 1.0
  position_notional_long: 1.2
  position_notional_short: 1.2
strategy_class_long: strategies.cryptomine_pack_dual_full.CryptomineLongPackAdaptiveEven
strategy_class_short: strategies.cryptomine_pack_dual_full.CryptomineShortPackAdaptiveEven
strategy_params_long:
  firstBuyQtyCoin: 20
  minOrderQtyCoin: 20
  minOrderUSDT: 1.2
  minLongInvestPct: 1.2
  useEquityPctBase: true
  baseOrderPctEq: 2
  equityForSizingUSDT: 100.0
  tpPercent: 0.25
  callbackPercent: 0.060000000000000005
  marginCallLimit: 244
  linearDropPercent: 0.19
  autoMerge: false
  subSellTPPercent: 0.44
  requireCloseAboveFullTP: true
  subSellCloseConfirmMode: breakeven
  requireCloseBelowDcaLevel: true
  blockDcaOnTpTouch: false
  drop1: 0.3
  drop2: 0.4
  drop3: 0.6
  drop4: 0.8
  drop5: 0.8
  mult2: 1.7
  mult3: 1.0
  mult4: 2.0
  mult5: 3.5
  maxFillsPerBar: 6
  maxSubSellsPerBar: 10
  useHighLowTouch: true
  useLiveSyncStart: false
  liveStartTime: 0
  maxOrdersPer3Min: 14
  useTrendAdaptiveSizing: true
  trendMaTf: W
  trendMaLen: 20
  trendSlopeBars: 3
  trendSlopeLongBoundPct: 1.0
  trendSlopeShortBoundPct: -1.0
  trendScoreMinPct: 45.0
  trendScoreMaxPct: 75.0
  minLongInvestPct: 2.0
  maxLongInvestPct: 2.2
  hardBreakevenDeleveragePct: 50.0
  useEvenBars: false
strategy_params_short:
  firstSellQtyCoin: 20
  minOrderQtyCoin: 20
  minOrderUSDT: 1.2
  minShortInvestPct: 1.2
  useEquityPctBase: true
  baseOrderPctEq: 2
  equityForSizingUSDT: 100.0
  tpPercent: 0.19
  callbackPercent: 0.155
  marginCallLimit: 244
  linearRisePercent: 0.16
  autoMerge: false
  subSellTPPercent: 0.42
  requireCloseBelowFullTP: true
  subCoverCloseConfirmMode: breakeven
  requireCloseAboveDcaLevel: true
  blockDcaOnTpTouch: false
  rise1: 0.32999999999999996
  rise2: 0.4
  rise3: 0.6
  rise4: 0.8
  rise5: 0.8
  mult2: 1.6
  mult3: 1.0
  mult4: 2.0
  mult5: 3.5
  maxFillsPerBar: 6
  maxSubSellsPerBar: 10
  useHighLowTouch: true
  useLiveSyncStart: false
  liveStartTime: 0
  maxOrdersPer3Min: 14
  useTrendAdaptiveSizing: true
  trendMaTf: W
  trendMaLen: 20
  trendSlopeBars: 3
  trendSlopeLongBoundPct: 1.0
  trendSlopeShortBoundPct: -1.0
  trendScoreMinPct: 45.0
  trendScoreMaxPct: 75.0
  minShortInvestPct: 2.0
  maxShortInvestPct: 2.4
  hardBreakevenDeleveragePct: 50.0
  useEvenBars: false
runner:
  prewarm:
    bars: 200


run_id: WRAP_20260419_062320
label: bt_live_paper_runner_separated_universe_4.py
path: bt_live_paper_runner_separated_universe_4.py
sha256: 1a99aded7f3f3f0fee964aa72a7f978edd2e089b4d5652dfdb50aebdd40b111f
text_content:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from __future__ import annotations

import argparse
import os
import sys
import time
from typing import Any, Dict, List

try:
    from runners.live_debug_bundle import (
        ensure_live_debug_bundle_db,
        install_stdio_capture,
        record_run_meta,
        snapshot_files,
        debug_event,
        finalize_bundle,
        exception_text,
    )
except Exception:
    def ensure_live_debug_bundle_db(db_path: str) -> None:
        return None
    def install_stdio_capture(db_path: str, run_id: str):
        return lambda: None
    def record_run_meta(db_path: str, run_id: str, argv=None, env=None, extra=None) -> None:
        return None
    def snapshot_files(db_path: str, run_id: str, paths):
        return None
    def debug_event(db_path: str, run_id: str, event_type: str, payload=None, level: str = 'INFO') -> None:
        return None
    def finalize_bundle(db_path: str, run_id: str, status: str = 'ok', error_text: str = '', results_dir: str = '', extra_files=None):
        return None
    def exception_text() -> str:
        return ''


def _read_text(path: str) -> str:
    with open(path, 'r', encoding='utf-8') as f:
        return f.read()


def _load_yaml_or_json(path: str) -> Dict[str, Any]:
    if path.endswith('.json'):
        import json
        return json.loads(_read_text(path))
    import yaml
    return yaml.safe_load(_read_text(path))


def _split_csv(s: str) -> List[str]:
    return [x.strip() for x in str(s or '').split(',') if x.strip()]


def _read_universe_file(path: str) -> List[str]:
    syms: List[str] = []
    if not path:
        return syms
    try:
        if not os.path.isabs(path):
            udir = os.path.join(os.path.dirname(__file__), 'universe')
            path = os.path.join(udir, os.path.basename(path))
        with open(path, 'r', encoding='utf-8') as f:
            for ln in f:
                ln = ln.strip()
                if ln and not ln.startswith('#'):
                    syms.append(ln)
    except Exception:
        pass
    return syms


def _merge_universe(cfg_uni: Dict[str, Any], file_syms: List[str], allow_cli: List[str], deny_cli: List[str]) -> Dict[str, Any]:
    uni = dict(cfg_uni or {})
    allow = set(uni.get('allow', []) or [])
    deny = set(uni.get('deny', []) or [])
    allow.update(file_syms)
    allow.update(allow_cli)
    deny.update(deny_cli)
    if file_syms and 'file' not in uni:
        uni['file'] = '<cli>'
    uni['allow'] = sorted(allow)
    uni['deny'] = sorted(deny)
    return uni


def _hint_restrict_symbols(cfg: Dict[str, Any], allow: List[str]) -> None:
    if allow:
        cfg.setdefault('universe', {})['allow'] = list(allow)
        cfg.setdefault('md_builder', {})['restrict_to_symbols'] = list(allow)
        cfg['symbols_whitelist'] = list(allow)
        os.environ['RS_UNIVERSE_ALLOW'] = ','.join(allow)
        os.environ['RS_SYMBOLS_WHITELIST'] = ','.join(allow)


def _run_backtest(cfg_path: str, limit_bars: int | None):
    bt_entry = os.path.join(os.getcwd(), 'backtester_core.py')
    if not os.path.exists(bt_entry):
        raise SystemExit('backtester_core.py not found. Run from the project root.')
    cmd = [sys.executable, bt_entry, '--cfg', cfg_path]
    if limit_bars and int(limit_bars) > 0:
        cmd += ['--limit-bars', str(int(limit_bars))]
    print('[backtest] exec:', ' '.join(cmd))
    os.execvp(sys.executable, cmd)


def _is_dual_cfg(cfg: Dict[str, Any]) -> bool:
    return bool(cfg.get('strategy_class_long') and cfg.get('strategy_class_short'))


def _run_live(cfg: Dict[str, Any], args):
    if getattr(args, 'live_runner_module', ''):
        try:
            import importlib
            mod = importlib.import_module(str(args.live_runner_module))
            fn = getattr(mod, 'run_live')
            print(f'[live] using {args.live_runner_module}.run_live')
            return fn(cfg, args)
        except Exception as e:
            print(f'[live] {args.live_runner_module}.run_live not available:', e)
            print('[live] falling back to auto runner selection')
    if _is_dual_cfg(cfg):
        try:
            from runners.live_runner_dual import run_live as _run_live_dual
            print('[live] using runners.live_runner_dual.run_live')
            return _run_live_dual(cfg, args)
        except Exception as e:
            print('[live] runners.live_runner_dual.run_live not available:', e)
            print('[live] falling back to runners.live_runner.run_live')
    try:
        from runners.live_runner import run_live as _run_live_single
        print('[live] using runners.live_runner.run_live')
        return _run_live_single(cfg, args)
    except Exception as e:
        print('[live] runners.live_runner.run_live not available:', e)
        print('[live] Falling back to heartbeat... (CTRL+C to exit)')
        while True:
            print('.', end='', flush=True)
            time.sleep(max(1, int(getattr(args, 'poll_sec', 10) or 10)))


def _run_paper_api(cfg: Dict[str, Any], args):
    try:
        from runners.paper_api_runner import run_paper_api as _run_paper_api
        return _run_paper_api(cfg, args)
    except Exception as e:
        print('[paper-api] runners.paper_api_runner.run_paper_api not available:', e)
        print('[paper-api] Using minimal fallback loop with heartbeat only.')
        poll = int(getattr(args, 'poll_sec', 10) or 10)
        while True:
            print('.', end='', flush=True)
            time.sleep(poll)


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument('--mode', choices=['backtest', 'paper', 'live'], required=True)
    ap.add_argument('--paper-source', choices=['db', 'api'], default='api')
    ap.add_argument('--orders-db', default='')
    ap.add_argument('--cfg', required=True)
    ap.add_argument('--db')
    ap.add_argument('--results-dir', default='')
    ap.add_argument('--limit-bars', type=int, default=0)
    ap.add_argument('--session-db', default='')
    ap.add_argument('--cache-out', default='')
    ap.add_argument('--hour-cache', choices=['off', 'save', 'load'], default='off')
    ap.add_argument('--env-file', default='')
    ap.add_argument('--exchange', default='bingx')
    ap.add_argument('--symbol-format', default='usdtm')
    ap.add_argument('--poll-sec', type=int, default=2)
    ap.add_argument('--bar-delay-sec', type=int, default=1)
    ap.add_argument('--limit_klines', type=int, default=180)
    ap.add_argument('--prewarm-bars', type=int, default=None)
    ap.add_argument('--prewarm-hours', type=int, default=None)
    ap.add_argument('--debug', action='store_true')
    ap.add_argument('--heat-report', action='store_true')
    ap.add_argument('--universe-file', default='')
    ap.add_argument('--allow-symbols', default='')
    ap.add_argument('--deny-symbols', default='')
    ap.add_argument('--live-runner-module', default='', help='Explicit live runner module path, e.g. runners.live_runner_dual_verbose_debug')
    args = ap.parse_args()

    cfg_name = os.path.splitext(os.path.basename(args.cfg))[0]
    cfg = _load_yaml_or_json(args.cfg)
    timeframe = str(cfg.get('timeframe') or 'na')
    if not args.results_dir:
        args.results_dir = os.path.join('_reports', '_live', f'livecfg_{cfg_name}_{timeframe}')
    os.makedirs(args.results_dir, exist_ok=True)
    if args.session_db:
        if not os.path.isabs(args.session_db) and os.path.dirname(args.session_db) == '':
            args.session_db = os.path.join(args.results_dir, args.session_db)
    else:
        args.session_db = os.path.join(args.results_dir, 'session.sqlite')
    if args.cache_out:
        if not os.path.isabs(args.cache_out) and os.path.dirname(args.cache_out) == '':
            args.cache_out = os.path.join(args.results_dir, args.cache_out)
    else:
        args.cache_out = os.path.join(args.results_dir, 'combined_cache_session.db')
    if not args.orders_db:
        args.orders_db = args.session_db
    print(f'[results] dir: {args.results_dir}')

    bundle_run_id = time.strftime('WRAP_%Y%m%d_%H%M%S')
    ensure_live_debug_bundle_db(args.session_db)
    restore_stdio = install_stdio_capture(args.session_db, bundle_run_id)
    record_run_meta(args.session_db, bundle_run_id, argv=sys.argv, env={
        'mode': args.mode,
        'paper_source': args.paper_source,
        'exchange': args.exchange,
        'results_dir': args.results_dir,
        'cfg': args.cfg,
    }, extra={'wrapper': os.path.basename(__file__)})
    snapshot_files(args.session_db, bundle_run_id, [__file__, args.cfg])
    debug_event(args.session_db, bundle_run_id, 'wrapper_start', {'mode': args.mode, 'results_dir': args.results_dir})

    cfg_uni = cfg.get('universe', {}) or {}
    file_syms = _read_universe_file(args.universe_file or cfg.get('universe_file', ''))
    allow_cli = _split_csv(args.allow_symbols)
    deny_cli = _split_csv(args.deny_symbols)
    uni = _merge_universe(cfg_uni, file_syms, allow_cli, deny_cli)
    cfg['universe'] = uni
    _hint_restrict_symbols(cfg, list(uni.get('allow', []) or []))

    try:
        if args.mode == 'backtest':
            _run_backtest(args.cfg, args.limit_bars)
        elif args.mode == 'paper':
            if args.paper_source == 'api':
                _run_paper_api(cfg, args)
            else:
                raise SystemExit('paper --paper-source=db is not implemented in this wrapper version')
        else:
            _run_live(cfg, args)
    except KeyboardInterrupt:
        debug_event(args.session_db, bundle_run_id, 'wrapper_stop', {'reason': 'keyboard_interrupt'})
        finalize_bundle(args.session_db, bundle_run_id, status='stopped', results_dir=args.results_dir)
        restore_stdio()
        raise
    except Exception:
        err = exception_text()
        debug_event(args.session_db, bundle_run_id, 'wrapper_error', {'traceback': err}, level='ERROR')
        finalize_bundle(args.session_db, bundle_run_id, status='error', error_text=err, results_dir=args.results_dir)
        restore_stdio()
        raise


if __name__ == '__main__':
    main()


# attached_artifacts

run_id: WRAP_20260418_202753
name: live_positions.json
sha256: 44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a
path:
/var/www/vps2.happyuser.info/top/top_1/obw_platform/_reports/_live/livecfg_final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar_0.5m/live_positions.json


# config_snapshots

run_id: LIVE_DUAL_20260418_152504
ts_utc: 2026-04-18T15:25:04.648599
cfg_json:
{"live": true, "source": "api", "timeframe": "0.5m", "portfolio": {"initial_equity_per_leg": 100.0, "fee_rate": 0.001, "slippage_per_side": 4.0, "max_notional_frac": 1.0}, "strategy_class_long": "strategies.cryptomine_pack_dual_full.CryptomineLongPackAdaptiveEven", "strategy_class_short": "strategies.cryptomine_pack_dual_full.CryptomineShortPackAdaptiveEven", "strategy_params_long": {"firstBuyQtyCoin": 0.09, "minOrderQtyCoin": 0.09, "minOrderUSDT": 2.0, "useEquityPctBase": true, "baseOrderPctEq": 0.6, "equityForSizingUSDT": 100.0, "tpPercent": 0.25, "callbackPercent": 0.060000000000000005, "marginCallLimit": 244, "linearDropPercent": 0.19, "autoMerge": false, "subSellTPPercent": 0.44, "requireCloseAboveFullTP": true, "subSellCloseConfirmMode": "breakeven", "requireCloseBelowDcaLevel": true, "blockDcaOnTpTouch": false, "drop1": 0.3, "drop2": 0.4, "drop3": 0.6, "drop4": 0.8, "drop5": 0.8, "mult2": 1.7, "mult3": 1.0, "mult4": 2.0, "mult5": 3.5, "maxFillsPerBar": 6, "maxSubSellsPerBar": 10, "useHighLowTouch": true, "useLiveSyncStart": false, "liveStartTime": 0, "maxOrdersPer3Min": 14, "useTrendAdaptiveSizing": true, "trendMaTf": "W", "trendMaLen": 20, "trendSlopeBars": 3, "trendSlopeLongBoundPct": 1.0, "trendSlopeShortBoundPct": -1.0, "trendScoreMinPct": 45.0, "trendScoreMaxPct": 75.0, "minLongInvestPct": 0.5, "maxLongInvestPct": 2.2, "hardBreakevenDeleveragePct": 50.0, "useEvenBars": false}, "strategy_params_short": {"firstSellQtyCoin": 0.09, "minOrderQtyCoin": 0.09, "minOrderUSDT": 2.0, "useEquityPctBase": true, "baseOrderPctEq": 0.6, "equityForSizingUSDT": 100.0, "tpPercent": 0.19, "callbackPercent": 0.155, "marginCallLimit": 244, "linearRisePercent": 0.16, "autoMerge": false, "subSellTPPercent": 0.42, "requireCloseBelowFullTP": true, "subCoverCloseConfirmMode": "breakeven", "requireCloseAboveDcaLevel": true, "blockDcaOnTpTouch": false, "rise1": 0.32999999999999996, "rise2": 0.4, "rise3": 0.6, "rise4": 0.8, "rise5": 0.8, "mult2": 1.6, "mult3": 1.0, "mult4": 2.0, "mult5": 3.5, "maxFillsPerBar": 6, "maxSubSellsPerBar": 10, "useHighLowTouch": true, "useLiveSyncStart": false, "liveStartTime": 0, "maxOrdersPer3Min": 14, "useTrendAdaptiveSizing": true, "trendMaTf": "W", "trendMaLen": 20, "trendSlopeBars": 3, "trendSlopeLongBoundPct": 1.0, "trendSlopeShortBoundPct": -1.0, "trendScoreMinPct": 45.0, "trendScoreMaxPct": 75.0, "minShortInvestPct": 0.5, "maxShortInvestPct": 2.4, "hardBreakevenDeleveragePct": 50.0, "useEvenBars": false}, "runner": {"prewarm": {"bars": 200}}, "universe": {"file": "<cli>", "allow": ["ENA/USDT:USDT"], "deny": []}, "md_builder": {"restrict_to_symbols": ["ENA/USDT:USDT"]}, "symbols_whitelist": ["ENA/USDT:USDT"]}


run_id: LIVE_DUAL_20260418_192053
ts_utc: 2026-04-18T19:20:53.438762
cfg_json:
{"live": true, "source": "api", "timeframe": "0.5m", "portfolio": {"initial_equity_per_leg": 100.0, "fee_rate": 0.001, "slippage_per_side": 4.0, "max_notional_frac": 1.0, "position_notional_long": 2.0, "position_notional_short": 2.0}, "strategy_class_long": "strategies.cryptomine_pack_dual_full.CryptomineLongPackAdaptiveEven", "strategy_class_short": "strategies.cryptomine_pack_dual_full.CryptomineShortPackAdaptiveEven", "strategy_params_long": {"firstBuyQtyCoin": 0.09, "minOrderQtyCoin": 0.09, "minOrderUSDT": 2.0, "useEquityPctBase": true, "baseOrderPctEq": 0.6, "equityForSizingUSDT": 100.0, "tpPercent": 0.25, "callbackPercent": 0.060000000000000005, "marginCallLimit": 244, "linearDropPercent": 0.19, "autoMerge": false, "subSellTPPercent": 0.44, "requireCloseAboveFullTP": true, "subSellCloseConfirmMode": "breakeven", "requireCloseBelowDcaLevel": true, "blockDcaOnTpTouch": false, "drop1": 0.3, "drop2": 0.4, "drop3": 0.6, "drop4": 0.8, "drop5": 0.8, "mult2": 1.7, "mult3": 1.0, "mult4": 2.0, "mult5": 3.5, "maxFillsPerBar": 6, "maxSubSellsPerBar": 10, "useHighLowTouch": true, "useLiveSyncStart": false, "liveStartTime": 0, "maxOrdersPer3Min": 14, "useTrendAdaptiveSizing": true, "trendMaTf": "W", "trendMaLen": 20, "trendSlopeBars": 3, "trendSlopeLongBoundPct": 1.0, "trendSlopeShortBoundPct": -1.0, "trendScoreMinPct": 45.0, "trendScoreMaxPct": 75.0, "minLongInvestPct": 2.0, "maxLongInvestPct": 2.2, "hardBreakevenDeleveragePct": 50.0, "useEvenBars": false}, "strategy_params_short": {"firstSellQtyCoin": 0.09, "minOrderQtyCoin": 0.09, "minOrderUSDT": 2.0, "useEquityPctBase": true, "baseOrderPctEq": 0.6, "equityForSizingUSDT": 100.0, "tpPercent": 0.19, "callbackPercent": 0.155, "marginCallLimit": 244, "linearRisePercent": 0.16, "autoMerge": false, "subSellTPPercent": 0.42, "requireCloseBelowFullTP": true, "subCoverCloseConfirmMode": "breakeven", "requireCloseAboveDcaLevel": true, "blockDcaOnTpTouch": false, "rise1": 0.32999999999999996, "rise2": 0.4, "rise3": 0.6, "rise4": 0.8, "rise5": 0.8, "mult2": 1.6, "mult3": 1.0, "mult4": 2.0, "mult5": 3.5, "maxFillsPerBar": 6, "maxSubSellsPerBar": 10, "useHighLowTouch": true, "useLiveSyncStart": false, "liveStartTime": 0, "maxOrdersPer3Min": 14, "useTrendAdaptiveSizing": true, "trendMaTf": "W", "trendMaLen": 20, "trendSlopeBars": 3, "trendSlopeLongBoundPct": 1.0, "trendSlopeShortBoundPct": -1.0, "trendScoreMinPct": 45.0, "trendScoreMaxPct": 75.0, "minShortInvestPct": 2.0, "maxShortInvestPct": 2.4, "hardBreakevenDeleveragePct": 50.0, "useEvenBars": false}, "runner": {"prewarm": {"bars": 200}}, "universe": {"file": "<cli>", "allow": ["ENA/USDT:USDT"], "deny": []}, "md_builder": {"restrict_to_symbols": ["ENA/USDT:USDT"]}, "symbols_whitelist": ["ENA/USDT:USDT"]}


run_id: LIVE_DUAL_20260418_193252
ts_utc: 2026-04-18T19:32:52.949523
cfg_json:
{"live": true, "source": "api", "timeframe": "0.5m", "portfolio": {"initial_equity_per_leg": 100.0, "fee_rate": 0.001, "slippage_per_side": 4.0, "max_notional_frac": 1.0, "position_notional_long": 2.0, "position_notional_short": 2.0}, "strategy_class_long": "strategies.cryptomine_pack_dual_full.CryptomineLongPackAdaptiveEven", "strategy_class_short": "strategies.cryptomine_pack_dual_full.CryptomineShortPackAdaptiveEven", "strategy_params_long": {"firstBuyQtyCoin": 0.09, "minOrderQtyCoin": 0.09, "minOrderUSDT": 2.0, "useEquityPctBase": true, "baseOrderPctEq": 2, "equityForSizingUSDT": 100.0, "tpPercent": 0.25, "callbackPercent": 0.060000000000000005, "marginCallLimit": 244, "linearDropPercent": 0.19, "autoMerge": false, "subSellTPPercent": 0.44, "requireCloseAboveFullTP": true, "subSellCloseConfirmMode": "breakeven", "requireCloseBelowDcaLevel": true, "blockDcaOnTpTouch": false, "drop1": 0.3, "drop2": 0.4, "drop3": 0.6, "drop4": 0.8, "drop5": 0.8, "mult2": 1.7, "mult3": 1.0, "mult4": 2.0, "mult5": 3.5, "maxFillsPerBar": 6, "maxSubSellsPerBar": 10, "useHighLowTouch": true, "useLiveSyncStart": false, "liveStartTime": 0, "maxOrdersPer3Min": 14, "useTrendAdaptiveSizing": true, "trendMaTf": "W", "trendMaLen": 20, "trendSlopeBars": 3, "trendSlopeLongBoundPct": 1.0, "trendSlopeShortBoundPct": -1.0, "trendScoreMinPct": 45.0, "trendScoreMaxPct": 75.0, "minLongInvestPct": 2.0, "maxLongInvestPct": 2.2, "hardBreakevenDeleveragePct": 50.0, "useEvenBars": false}, "strategy_params_short": {"firstSellQtyCoin": 0.09, "minOrderQtyCoin": 0.09, "minOrderUSDT": 2.0, "useEquityPctBase": true, "baseOrderPctEq": 2, "equityForSizingUSDT": 100.0, "tpPercent": 0.19, "callbackPercent": 0.155, "marginCallLimit": 244, "linearRisePercent": 0.16, "autoMerge": false, "subSellTPPercent": 0.42, "requireCloseBelowFullTP": true, "subCoverCloseConfirmMode": "breakeven", "requireCloseAboveDcaLevel": true, "blockDcaOnTpTouch": false, "rise1": 0.32999999999999996, "rise2": 0.4, "rise3": 0.6, "rise4": 0.8, "rise5": 0.8, "mult2": 1.6, "mult3": 1.0, "mult4": 2.0, "mult5": 3.5, "maxFillsPerBar": 6, "maxSubSellsPerBar": 10, "useHighLowTouch": true, "useLiveSyncStart": false, "liveStartTime": 0, "maxOrdersPer3Min": 14, "useTrendAdaptiveSizing": true, "trendMaTf": "W", "trendMaLen": 20, "trendSlopeBars": 3, "trendSlopeLongBoundPct": 1.0, "trendSlopeShortBoundPct": -1.0, "trendScoreMinPct": 45.0, "trendScoreMaxPct": 75.0, "minShortInvestPct": 2.0, "maxShortInvestPct": 2.4, "hardBreakevenDeleveragePct": 50.0, "useEvenBars": false}, "runner": {"prewarm": {"bars": 200}}, "universe": {"file": "<cli>", "allow": ["ENA/USDT:USDT"], "deny": []}, "md_builder": {"restrict_to_symbols": ["ENA/USDT:USDT"]}, "symbols_whitelist": ["ENA/USDT:USDT"]}


run_id: LIVE_DUAL_20260418_193448
ts_utc: 2026-04-18T19:34:48.720766
cfg_json:
{"live": true, "source": "api", "timeframe": "0.5m", "portfolio": {"initial_equity_per_leg": 100.0, "fee_rate": 0.001, "slippage_per_side": 4.0, "max_notional_frac": 1.0, "position_notional_long": 2.0, "position_notional_short": 2.0}, "strategy_class_long": "strategies.cryptomine_pack_dual_full.CryptomineLongPackAdaptiveEven", "strategy_class_short": "strategies.cryptomine_pack_dual_full.CryptomineShortPackAdaptiveEven", "strategy_params_long": {"firstBuyQtyCoin": 20, "minOrderQtyCoin": 20, "minOrderUSDT": 2.0, "useEquityPctBase": true, "baseOrderPctEq": 2, "equityForSizingUSDT": 100.0, "tpPercent": 0.25, "callbackPercent": 0.060000000000000005, "marginCallLimit": 244, "linearDropPercent": 0.19, "autoMerge": false, "subSellTPPercent": 0.44, "requireCloseAboveFullTP": true, "subSellCloseConfirmMode": "breakeven", "requireCloseBelowDcaLevel": true, "blockDcaOnTpTouch": false, "drop1": 0.3, "drop2": 0.4, "drop3": 0.6, "drop4": 0.8, "drop5": 0.8, "mult2": 1.7, "mult3": 1.0, "mult4": 2.0, "mult5": 3.5, "maxFillsPerBar": 6, "maxSubSellsPerBar": 10, "useHighLowTouch": true, "useLiveSyncStart": false, "liveStartTime": 0, "maxOrdersPer3Min": 14, "useTrendAdaptiveSizing": true, "trendMaTf": "W", "trendMaLen": 20, "trendSlopeBars": 3, "trendSlopeLongBoundPct": 1.0, "trendSlopeShortBoundPct": -1.0, "trendScoreMinPct": 45.0, "trendScoreMaxPct": 75.0, "minLongInvestPct": 2.0, "maxLongInvestPct": 2.2, "hardBreakevenDeleveragePct": 50.0, "useEvenBars": false}, "strategy_params_short": {"firstSellQtyCoin": 20, "minOrderQtyCoin": 20, "minOrderUSDT": 2.0, "useEquityPctBase": true, "baseOrderPctEq": 2, "equityForSizingUSDT": 100.0, "tpPercent": 0.19, "callbackPercent": 0.155, "marginCallLimit": 244, "linearRisePercent": 0.16, "autoMerge": false, "subSellTPPercent": 0.42, "requireCloseBelowFullTP": true, "subCoverCloseConfirmMode": "breakeven", "requireCloseAboveDcaLevel": true, "blockDcaOnTpTouch": false, "rise1": 0.32999999999999996, "rise2": 0.4, "rise3": 0.6, "rise4": 0.8, "rise5": 0.8, "mult2": 1.6, "mult3": 1.0, "mult4": 2.0, "mult5": 3.5, "maxFillsPerBar": 6, "maxSubSellsPerBar": 10, "useHighLowTouch": true, "useLiveSyncStart": false, "liveStartTime": 0, "maxOrdersPer3Min": 14, "useTrendAdaptiveSizing": true, "trendMaTf": "W", "trendMaLen": 20, "trendSlopeBars": 3, "trendSlopeLongBoundPct": 1.0, "trendSlopeShortBoundPct": -1.0, "trendScoreMinPct": 45.0, "trendScoreMaxPct": 75.0, "minShortInvestPct": 2.0, "maxShortInvestPct": 2.4, "hardBreakevenDeleveragePct": 50.0, "useEvenBars": false}, "runner": {"prewarm": {"bars": 200}}, "universe": {"file": "<cli>", "allow": ["ENA/USDT:USDT"], "deny": []}, "md_builder": {"restrict_to_symbols": ["ENA/USDT:USDT"]}, "symbols_whitelist": ["ENA/USDT:USDT"]}


run_id: LIVE_DUAL_20260418_193559
ts_utc: 2026-04-18T19:35:59.122777
cfg_json:
{"live": true, "source": "api", "timeframe": "0.5m", "portfolio": {"initial_equity_per_leg": 100.0, "fee_rate": 0.001, "slippage_per_side": 4.0, "max_notional_frac": 1.0, "position_notional_long": 2.0, "position_notional_short": 2.0}, "strategy_class_long": "strategies.cryptomine_pack_dual_full.CryptomineLongPackAdaptiveEven", "strategy_class_short": "strategies.cryptomine_pack_dual_full.CryptomineShortPackAdaptiveEven", "strategy_params_long": {"firstBuyQtyCoin": 20, "minOrderQtyCoin": 20, "minOrderUSDT": 2.0, "minLongInvestPct": 2.0, "useEquityPctBase": true, "baseOrderPctEq": 2, "equityForSizingUSDT": 100.0, "tpPercent": 0.25, "callbackPercent": 0.060000000000000005, "marginCallLimit": 244, "linearDropPercent": 0.19, "autoMerge": false, "subSellTPPercent": 0.44, "requireCloseAboveFullTP": true, "subSellCloseConfirmMode": "breakeven", "requireCloseBelowDcaLevel": true, "blockDcaOnTpTouch": false, "drop1": 0.3, "drop2": 0.4, "drop3": 0.6, "drop4": 0.8, "drop5": 0.8, "mult2": 1.7, "mult3": 1.0, "mult4": 2.0, "mult5": 3.5, "maxFillsPerBar": 6, "maxSubSellsPerBar": 10, "useHighLowTouch": true, "useLiveSyncStart": false, "liveStartTime": 0, "maxOrdersPer3Min": 14, "useTrendAdaptiveSizing": true, "trendMaTf": "W", "trendMaLen": 20, "trendSlopeBars": 3, "trendSlopeLongBoundPct": 1.0, "trendSlopeShortBoundPct": -1.0, "trendScoreMinPct": 45.0, "trendScoreMaxPct": 75.0, "maxLongInvestPct": 2.2, "hardBreakevenDeleveragePct": 50.0, "useEvenBars": false}, "strategy_params_short": {"firstSellQtyCoin": 20, "minOrderQtyCoin": 20, "minOrderUSDT": 2.0, "minShortInvestPct": 2.0, "useEquityPctBase": true, "baseOrderPctEq": 2, "equityForSizingUSDT": 100.0, "tpPercent": 0.19, "callbackPercent": 0.155, "marginCallLimit": 244, "linearRisePercent": 0.16, "autoMerge": false, "subSellTPPercent": 0.42, "requireCloseBelowFullTP": true, "subCoverCloseConfirmMode": "breakeven", "requireCloseAboveDcaLevel": true, "blockDcaOnTpTouch": false, "rise1": 0.32999999999999996, "rise2": 0.4, "rise3": 0.6, "rise4": 0.8, "rise5": 0.8, "mult2": 1.6, "mult3": 1.0, "mult4": 2.0, "mult5": 3.5, "maxFillsPerBar": 6, "maxSubSellsPerBar": 10, "useHighLowTouch": true, "useLiveSyncStart": false, "liveStartTime": 0, "maxOrdersPer3Min": 14, "useTrendAdaptiveSizing": true, "trendMaTf": "W", "trendMaLen": 20, "trendSlopeBars": 3, "trendSlopeLongBoundPct": 1.0, "trendSlopeShortBoundPct": -1.0, "trendScoreMinPct": 45.0, "trendScoreMaxPct": 75.0, "maxShortInvestPct": 2.4, "hardBreakevenDeleveragePct": 50.0, "useEvenBars": false}, "runner": {"prewarm": {"bars": 200}}, "universe": {"file": "<cli>", "allow": ["ENA/USDT:USDT"], "deny": []}, "md_builder": {"restrict_to_symbols": ["ENA/USDT:USDT"]}, "symbols_whitelist": ["ENA/USDT:USDT"]}


run_id: LIVE_20260418_204839
ts_utc: 2026-04-18T20:48:39.821386
cfg_json:
{"live": true, "source": "api", "timeframe": "0.5m", "portfolio": {"initial_equity_per_leg": 100.0, "fee_rate": 0.001, "slippage_per_side": 4.0, "max_notional_frac": 1.0, "position_notional_long": 1.2, "position_notional_short": 1.2}, "strategy_class_long": "strategies.cryptomine_pack_dual_full.CryptomineLongPackAdaptiveEven", "strategy_class_short": "strategies.cryptomine_pack_dual_full.CryptomineShortPackAdaptiveEven", "strategy_params_long": {"firstBuyQtyCoin": 20, "minOrderQtyCoin": 20, "minOrderUSDT": 1.2, "minLongInvestPct": 2.0, "useEquityPctBase": true, "baseOrderPctEq": 2, "equityForSizingUSDT": 100.0, "tpPercent": 0.25, "callbackPercent": 0.060000000000000005, "marginCallLimit": 244, "linearDropPercent": 0.19, "autoMerge": false, "subSellTPPercent": 0.44, "requireCloseAboveFullTP": true, "subSellCloseConfirmMode": "breakeven", "requireCloseBelowDcaLevel": true, "blockDcaOnTpTouch": false, "drop1": 0.3, "drop2": 0.4, "drop3": 0.6, "drop4": 0.8, "drop5": 0.8, "mult2": 1.7, "mult3": 1.0, "mult4": 2.0, "mult5": 3.5, "maxFillsPerBar": 6, "maxSubSellsPerBar": 10, "useHighLowTouch": true, "useLiveSyncStart": false, "liveStartTime": 0, "maxOrdersPer3Min": 14, "useTrendAdaptiveSizing": true, "trendMaTf": "W", "trendMaLen": 20, "trendSlopeBars": 3, "trendSlopeLongBoundPct": 1.0, "trendSlopeShortBoundPct": -1.0, "trendScoreMinPct": 45.0, "trendScoreMaxPct": 75.0, "maxLongInvestPct": 2.2, "hardBreakevenDeleveragePct": 50.0, "useEvenBars": false}, "strategy_params_short": {"firstSellQtyCoin": 20, "minOrderQtyCoin": 20, "minOrderUSDT": 1.2, "minShortInvestPct": 2.0, "useEquityPctBase": true, "baseOrderPctEq": 2, "equityForSizingUSDT": 100.0, "tpPercent": 0.19, "callbackPercent": 0.155, "marginCallLimit": 244, "linearRisePercent": 0.16, "autoMerge": false, "subSellTPPercent": 0.42, "requireCloseBelowFullTP": true, "subCoverCloseConfirmMode": "breakeven", "requireCloseAboveDcaLevel": true, "blockDcaOnTpTouch": false, "rise1": 0.32999999999999996, "rise2": 0.4, "rise3": 0.6, "rise4": 0.8, "rise5": 0.8, "mult2": 1.6, "mult3": 1.0, "mult4": 2.0, "mult5": 3.5, "maxFillsPerBar": 6, "maxSubSellsPerBar": 10, "useHighLowTouch": true, "useLiveSyncStart": false, "liveStartTime": 0, "maxOrdersPer3Min": 14, "useTrendAdaptiveSizing": true, "trendMaTf": "W", "trendMaLen": 20, "trendSlopeBars": 3, "trendSlopeLongBoundPct": 1.0, "trendSlopeShortBoundPct": -1.0, "trendScoreMinPct": 45.0, "trendScoreMaxPct": 75.0, "maxShortInvestPct": 2.4, "hardBreakevenDeleveragePct": 50.0, "useEvenBars": false}, "runner": {"prewarm": {"bars": 200}}, "universe": {"file": "<cli>", "allow": ["ENA/USDT:USDT"], "deny": []}, "md_builder": {"restrict_to_symbols": ["ENA/USDT:USDT"]}, "symbols_whitelist": ["ENA/USDT:USDT"]}


# equity

ts_utc: 2026-04-18T20:27:55.310552+00:00
run_id:
/var/www/vps2.happyuser.info/top/top_1/obw_platform/_reports/_live/livecfg_final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar_0.5m|bybit|0.5m


ts_utc: 2026-04-18T20:48:40.070026+00:00
run_id:
/var/www/vps2.happyuser.info/top/top_1/obw_platform/_reports/_live/livecfg_final_best_ena_1y_pack_04-14_bingx_live_bundle_open_first_bar_0.5m|bingx|0.5m


# orders

order_id: 28bfa03e-dd9c-43ef-8960-9926dced93cd
ts_utc: 2026-04-19T06:02:02.300526+00:00
bar_time_utc: 2026-04-19T06:02:00+00:00
mode: live
symbol: ENA/USDT:USDT
side: LONG
type: CLOSE
status: REJECTED
run_id: LIVE_DUAL_20260419_060105
extra: {}
reason:
bingx {"code":109400,"msg":"In the Hedge mode, the 'ReduceOnly' field can not be filled.","data":{}}


