fix: NT backtest engine venue registration and bar precision

- Fix add_venue call with required OmsType, AccountType, Money params
- Fix Bar volume precision to match instrument size_precision
- Fix subscribe_bars to use BarType not InstrumentId
- Fix _submit_order to gracefully handle NT internal API
- All tests pass: VBT, NT, signals, paper exec, param sweep
This commit is contained in:
ramseshk
2026-08-06 17:33:52 +08:00
parent f5ffe4baee
commit 39545ac94b
2 changed files with 47 additions and 18 deletions
+27 -9
View File
@@ -23,10 +23,10 @@ sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from nautilus_trader.backtest.engine import BacktestEngine, BacktestEngineConfig
from nautilus_trader.model.data import Bar, BarSpecification, BarType
from nautilus_trader.model.enums import BarAggregation, PriceType
from nautilus_trader.model.enums import AccountType, BarAggregation, OmsType, PriceType
from nautilus_trader.model.identifiers import InstrumentId, Venue
from nautilus_trader.model.instruments import CryptoPerpetual
from nautilus_trader.model.objects import Price, Quantity
from nautilus_trader.model.objects import Currency, Money, Price, Quantity
from framework.data import HyperliquidDataProvider, INTERVAL_TO_SECONDS
from framework.instruments import HL_VENUE
@@ -73,14 +73,31 @@ class NTBacktestRunner:
config = BacktestEngineConfig()
engine = BacktestEngine(config=config)
engine.add_venue(HL_VENUE)
engine.add_venue(
venue=HL_VENUE,
oms_type=OmsType.NETTING,
account_type=AccountType.MARGIN,
starting_balances=[Money(10_000.0, Currency.from_str("USD"))],
)
# Add instruments
if instruments:
for inst in instruments.values():
engine.add_instrument(inst)
coin = self._get_coin(strategy)
inst_for_coin = None
if instruments:
for name, inst in instruments.items():
engine.add_instrument(inst)
if name.upper() == coin.upper():
inst_for_coin = inst
if not inst_for_coin and instruments:
# Try to find any instrument matching
for inst in instruments.values():
instr_name = str(inst.id.symbol)
if coin.upper() in instr_name.upper():
inst_for_coin = inst
break
sz_prec = inst_for_coin.size_precision if inst_for_coin else 5
# Fetch real candles
provider = HyperliquidDataProvider(testnet=testnet)
@@ -91,7 +108,7 @@ class NTBacktestRunner:
# Build bars
inst_id = InstrumentId.from_str(f"{coin.upper()}-USD-PERP.HYPERLIQUID")
bars = self._df_to_bars(df, inst_id, step, agg)
bars = self._df_to_bars(df, inst_id, step, agg, size_precision=sz_prec)
# Add bars
engine.add_data(bars)
@@ -137,6 +154,7 @@ class NTBacktestRunner:
instrument_id: InstrumentId,
step: int,
aggregation: BarAggregation,
size_precision: int = 5,
) -> list[Bar]:
spec = BarSpecification(step, aggregation, PriceType.LAST)
bar_type = BarType(instrument_id, spec)
@@ -149,7 +167,7 @@ class NTBacktestRunner:
high=Price.from_str(str(row["high"])),
low=Price.from_str(str(row["low"])),
close=Price.from_str(str(row["close"])),
volume=Quantity.from_str(str(row["volume"])),
volume=Quantity.from_str(f'{row["volume"]:.{size_precision}f}'),
ts_event=ts,
ts_init=ts,
)