@@ -974,6 +974,78 @@ def test_sync_positions_accepts_raw_okx_position_aliases():
974974 broker .stop ()
975975
976976
977+ def test_sync_positions_accepts_raw_bybit_position_idx_in_net_mode ():
978+ """Bybit hedge snapshots may expose direction only through positionIdx."""
979+ symbol = "BTCUSDT"
980+ client = FakeBtApiClient (
981+ balance = {"cash" : 1250.0 , "value" : 1450.0 },
982+ positions = [
983+ {
984+ "symbol" : symbol ,
985+ "positionIdx" : "2" ,
986+ "size" : "0.5" ,
987+ "avgPrice" : "60125.5" ,
988+ }
989+ ],
990+ history = {symbol : [make_bar (0 , 60000.0 , 60200.0 , 59900.0 , 60100.0 )]},
991+ )
992+ store = make_store (api = client , provider = "bybit" )
993+ data = store .getdata (dataname = symbol )
994+ broker = store .getbroker (account_refresh_interval = 60.0 , positions_refresh_interval = 60.0 )
995+
996+ data ._start ()
997+ assert data .load () is True
998+ broker .start ()
999+ try :
1000+ position = broker .getposition (data )
1001+
1002+ assert position .size == pytest .approx (- 0.5 )
1003+ assert position .price == pytest .approx (60125.5 )
1004+ assert broker .positions [symbol ].size == pytest .approx (- 0.5 )
1005+ finally :
1006+ broker .stop ()
1007+
1008+
1009+ def test_sync_positions_accepts_raw_bybit_position_idx_in_dual_side_mode ():
1010+ """Bybit positionIdx=2 must hydrate the short leg in dual-side mode."""
1011+ symbol = "BTCUSDT"
1012+ client = FakeBtApiClient (
1013+ balance = {"cash" : 1250.0 , "value" : 1450.0 },
1014+ positions = [
1015+ {
1016+ "symbol" : symbol ,
1017+ "positionIdx" : "2" ,
1018+ "size" : "0.5" ,
1019+ "avgPrice" : "60125.5" ,
1020+ }
1021+ ],
1022+ history = {symbol : [make_bar (0 , 60000.0 , 60200.0 , 59900.0 , 60100.0 )]},
1023+ )
1024+ store = make_store (api = client , provider = "bybit" , supports_dual_side = True )
1025+ data = store .getdata (dataname = symbol )
1026+ broker = store .getbroker (
1027+ account_refresh_interval = 60.0 ,
1028+ positions_refresh_interval = 60.0 ,
1029+ position_mode = "dual_side" ,
1030+ )
1031+
1032+ data ._start ()
1033+ assert data .load () is True
1034+ broker .start ()
1035+ try :
1036+ net_position = broker .getposition (data )
1037+ short_position = broker .getposition (data , side = "short" )
1038+ long_position = broker .getposition (data , side = "long" )
1039+
1040+ assert net_position .size == pytest .approx (- 0.5 )
1041+ assert net_position .price == pytest .approx (60125.5 )
1042+ assert short_position .size == pytest .approx (0.5 )
1043+ assert short_position .price == pytest .approx (60125.5 )
1044+ assert long_position .size == pytest .approx (0.0 )
1045+ finally :
1046+ broker .stop ()
1047+
1048+
9771049def test_sync_positions_accepts_float_string_ctp_position_direction_codes ():
9781050 """CTP numeric-string position direction codes must not flip shorts long."""
9791051 symbol = "IF2506"
0 commit comments