Files
ftdt-quant-lab/framework/config.py
T
ramseshk f5ffe4baee feat: NautilusTrader + VectorBT unified framework for Hyperliquid
Add complete framework for testing and deploying quant strategies:

Framework (framework/):
- HyperliquidInstrumentCatalog: loads perps as NT CryptoPerpetual
- HyperliquidDataProvider: real candle/orderbook/mark-price data
- HyperliquidExecutionProvider: live + PaperExecutionProvider: simulated
- BaseHlStrategy: shared NT strategy lifecycle with signal library
- StrategyConfig: YAML-based parameter management
- DeployOrchestrator: CLI for backtest -> paper -> live pipeline

Backtesting (backtests/):
- VBTBacktestRunner: VectorBT vectorized backtests on real HL candles
- NTBacktestRunner: NautilusTrader event-driven backtest engine

NT Strategy ports (strategies/nt/):
- PairsTradingNT: BTC/ETH ratio Z-score mean reversion
- HurstVPINNT: Hurst exponent regime + VPIN flow imbalance
- ASMarketMakingNT: Avellaneda-Stoikov stochastic control MM

E2E verified: real HL candles fetch, VectorBT backtest (Sharpe 5.2
on Hurst/VPIN), instrument catalog, deploy CLI --list, strategy signals.
Existing live/node.py and paper_trader.py unchanged.
2026-08-06 17:23:49 +08:00

69 lines
2.2 KiB
Python

"""
Strategy configuration — YAML-based parameter management.
Each strategy gets a YAML file in config/ with its parameters for
backtest, paper, and live environments. The StrategyConfig class
loads and validates these configs.
"""
from __future__ import annotations
import yaml
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any
CONFIG_DIR = Path(__file__).resolve().parent.parent / "config"
@dataclass
class StrategyConfig:
"""Unified strategy configuration across backtest / paper / live."""
name: str
instrument: str
asset: str # Base currency (BTC, ETH, etc.)
allocation: float = 10000.0 # Capital allocated
order_size: float = 0.001 # Default order size (in base units)
maker_fee: float = 0.0002
taker_fee: float = 0.0005
slippage_bps: float = 1.0
testnet: bool = True
# Signal parameters (strategy-specific)
params: dict[str, Any] = field(default_factory=dict)
# Risk
max_position: float = 0.0 # 0 = based on allocation / price
max_drawdown: float = 0.10
stop_loss_pct: float = 0.0 # 0 = no stop
# Derived
fee_model: str = "taker" # taker or maker
@classmethod
def from_yaml(cls, path: str | Path) -> StrategyConfig:
with open(path) as f:
data = yaml.safe_load(f)
return cls(**data)
def to_yaml(self, path: str | Path) -> None:
with open(path, "w") as f:
yaml.safe_dump(self.__dict__, f, default_flow_style=False)
def effective_fee(self) -> float:
return self.maker_fee if self.fee_model == "maker" else self.taker_fee
@classmethod
def load_by_name(cls, name: str, env: str = "paper") -> StrategyConfig:
"""Load a strategy config from config/{name}.yaml."""
config_path = CONFIG_DIR / f"{name}.yaml"
if not config_path.exists():
raise FileNotFoundError(f"Config not found: {config_path}")
cfg = cls.from_yaml(config_path)
if env == "testnet":
cfg.testnet = True
elif env in ("mainnet", "live"):
cfg.testnet = False
return cfg