@@ -13,15 +13,42 @@ def requires_derivatives_account_configuration(*, market_type: str, reduce_only:
1313 return market in {"swap" , "future" , "futures" , "perp" , "perpetual" } and not bool (reduce_only )
1414
1515
16- def _is_binance_unknown_timeout (exc : BaseException | str ) -> bool :
16+ def _is_binance_ambiguous_configuration_error (exc : BaseException | str ) -> bool :
1717 text = str (exc or "" ).lower ()
1818 return (
19- "-1007" in text
19+ "-1000" in text
20+ or "unknown error occurred while processing the request" in text
21+ or "-1006" in text
22+ or "-1007" in text
2023 or "execution status unknown" in text
2124 or ("http 408" in text and "timeout" in text )
2225 )
2326
2427
28+ def resolve_derivatives_margin_mode (
29+ * ,
30+ payload : Dict [str , Any ],
31+ strategy_config : Dict [str , Any ],
32+ exchange_config : Dict [str , Any ] | None = None ,
33+ ) -> str :
34+ """Resolve the persisted strategy margin mode for order dispatch."""
35+ trading_config = strategy_config .get ("trading_config" ) or {}
36+ if not isinstance (trading_config , dict ):
37+ trading_config = {}
38+ venue_config = exchange_config or {}
39+ if not isinstance (venue_config , dict ):
40+ venue_config = {}
41+ return normalize_margin_mode (
42+ payload .get ("margin_mode" )
43+ or payload .get ("marginMode" )
44+ or trading_config .get ("margin_mode" )
45+ or trading_config .get ("marginMode" )
46+ or venue_config .get ("margin_mode" )
47+ or venue_config .get ("marginMode" )
48+ or "cross"
49+ )
50+
51+
2552def _confirm_binance_configuration (
2653 client : Any ,
2754 * ,
@@ -39,12 +66,12 @@ def _confirm_binance_configuration(
3966 observed_leverage = 0
4067 if require_margin and observed_mode != margin_mode :
4168 raise LiveTradingError (
42- f"Binance configuration timeout could not be confirmed: "
69+ f"Binance configuration outcome could not be confirmed: "
4370 f"margin_mode expected={ margin_mode } , observed={ observed_mode } "
4471 )
4572 if require_leverage and observed_leverage != int (leverage ):
4673 raise LiveTradingError (
47- f"Binance configuration timeout could not be confirmed: "
74+ f"Binance configuration outcome could not be confirmed: "
4875 f"leverage expected={ int (leverage )} , observed={ observed_leverage } "
4976 )
5077 return observed
@@ -92,40 +119,66 @@ def configure_derivatives_account(
92119 }
93120
94121 if isinstance (client , BinanceFuturesClient ):
95- margin_confirmed_after_timeout = False
122+ observed_before : Dict [str , Any ] | None = None
123+ try :
124+ observed_before = client .get_symbol_configuration (symbol = symbol ) or None
125+ except Exception :
126+ observed_before = None
127+ if observed_before :
128+ details ["configuration_before" ] = observed_before
129+
130+ observed_mode = ""
131+ if observed_before :
132+ try :
133+ observed_mode = normalize_margin_mode (
134+ str (observed_before .get ("margin_mode" ) or "" )
135+ )
136+ except LiveTradingError :
137+ observed_mode = ""
138+ margin_changed = observed_mode != mode
139+ observed_after_margin : Dict [str , Any ] | None = None
140+ if margin_changed :
141+ try :
142+ client .set_margin_type (symbol = symbol , margin_mode = mode )
143+ except Exception as exc :
144+ text = str (exc ).lower ()
145+ if "-4046" not in text and "no need to change margin type" not in text :
146+ if not _is_binance_ambiguous_configuration_error (exc ):
147+ raise LiveTradingError (f"Binance margin mode setup failed: { exc } " ) from exc
148+ observed_after_margin = _confirm_binance_configuration (
149+ client ,
150+ symbol = symbol ,
151+ margin_mode = mode ,
152+ leverage = target_leverage ,
153+ require_margin = True ,
154+ require_leverage = False ,
155+ )
156+ details ["readback_after_margin_error" ] = observed_after_margin
157+ else :
158+ details ["margin_mode_already_configured" ] = True
159+
160+ effective_observed = observed_after_margin or observed_before or {}
96161 try :
97- client .set_margin_type (symbol = symbol , margin_mode = mode )
98- except Exception as exc :
99- text = str (exc ).lower ()
100- if "-4046" not in text and "no need to change margin type" not in text :
101- if not _is_binance_unknown_timeout (exc ):
102- raise LiveTradingError (f"Binance margin mode setup failed: { exc } " ) from exc
162+ effective_leverage = int (float (effective_observed .get ("leverage" ) or 0 ))
163+ except (TypeError , ValueError ):
164+ effective_leverage = 0
165+ if margin_changed or effective_leverage != target_leverage :
166+ try :
167+ client .set_leverage (symbol = symbol , leverage = target_leverage )
168+ except Exception as exc :
169+ if not _is_binance_ambiguous_configuration_error (exc ):
170+ raise
103171 observed = _confirm_binance_configuration (
104172 client ,
105173 symbol = symbol ,
106174 margin_mode = mode ,
107175 leverage = target_leverage ,
108176 require_margin = True ,
109- require_leverage = False ,
177+ require_leverage = True ,
110178 )
111- details ["readback_after_margin_timeout" ] = observed
112- margin_confirmed_after_timeout = True
113- try :
114- client .set_leverage (symbol = symbol , leverage = target_leverage )
115- except Exception as exc :
116- if not _is_binance_unknown_timeout (exc ):
117- raise
118- observed = _confirm_binance_configuration (
119- client ,
120- symbol = symbol ,
121- margin_mode = mode ,
122- leverage = target_leverage ,
123- require_margin = True ,
124- require_leverage = True ,
125- )
126- details ["readback_after_leverage_timeout" ] = observed
127- if margin_confirmed_after_timeout :
128- details ["margin_mode_confirmed_after_timeout" ] = True
179+ details ["readback_after_leverage_error" ] = observed
180+ else :
181+ details ["leverage_already_configured" ] = True
129182 return details
130183
131184 if isinstance (client , OkxClient ):
0 commit comments