Fix node.py sync (previous commit had broken file from failed upload)

Properly synced live/node.py with the _load_key() function
that reads from env var or .env file as fallback.
This commit is contained in:
ramseshk
2026-08-04 02:47:53 +00:00
parent b43b54fd6a
commit 1d836307f5
2 changed files with 193 additions and 0 deletions
+190
View File
@@ -0,0 +1,190 @@
"""
Live trading node for Hyperliquid Testnet.
Runs all five quant strategies against the Hyperliquid testnet
using NautilusTrader's event-driven architecture. Strategies share
a risk manager and portfolio tracker.
Usage:
export HYPERLIQUID_TESTNET_PK=0x...
python live/node.py
"""
import os
import sys
import asyncio
from pathlib import Path
from nautilus_trader.config import TradingNodeConfig
from nautilus_trader.config import LiveDataEngineConfig
from nautilus_trader.config import LiveRiskEngineConfig
from nautilus_trader.config import LiveExecEngineConfig
from nautilus_trader.model.identifiers import TraderId
from nautilus_trader.common.enums import Environment
from nautilus_trader.live.node import TradingNode
from nautilus_trader.adapters.hyperliquid.config import (
HyperliquidDataClientConfig,
HyperliquidExecClientConfig,
)
from nautilus_trader.adapters.hyperliquid.factories import (
HyperliquidLiveDataClientFactory,
HyperliquidLiveExecClientFactory,
)
def build_node(private_key: str) -> TradingNode:
"""Build and configure the trading node with all strategies."""
data_config = HyperliquidDataClientConfig(
environment="testnet",
http_timeout_secs=30,
)
exec_config = HyperliquidExecClientConfig(
private_key=private_key,
environment="testnet",
normalize_prices=True,
http_timeout_secs=30,
)
node_config = TradingNodeConfig(
trader_id=TraderId("FTDT-QUANT-001"),
environment=Environment.LIVE,
data_engine=LiveDataEngineConfig(),
risk_engine=LiveRiskEngineConfig(),
exec_engine=LiveExecEngineConfig(),
data_clients={
"HYPERLIQUID": data_config,
},
exec_clients={
"HYPERLIQUID": exec_config,
},
timeout_connection=30.0,
timeout_reconciliation=15.0,
timeout_portfolio=15.0,
timeout_disconnection=15.0,
timeout_post_stop=5.0,
)
node = TradingNode(config=node_config)
# Register the Hyperliquid client factories
node.add_data_client_factory("HYPERLIQUID", HyperliquidLiveDataClientFactory)
node.add_exec_client_factory("HYPERLIQUID", HyperliquidLiveExecClientFactory)
return node
def register_strategies(node: TradingNode) -> None:
"""Register all five strategies with the trading node."""
# Import strategies here to avoid circular imports
from strategies.orderbook_imbalance import (
OrderBookImbalance, OrderBookImbalanceConfig,
)
from strategies.iceberg_detection import (
IcebergDetector, IcebergDetectorConfig,
)
from strategies.funding_rate_arb import (
FundingRateArb, FundingRateArbConfig,
)
from strategies.pairs_trading import (
PairsTrading, PairsTradingConfig,
)
from strategies.avellaneda_stoikov import (
AvellanedaStoikov, AvellanedaStoikovConfig,
)
# 1. Order Book Imbalance
node.add_strategy(
OrderBookImbalance,
OrderBookImbalanceConfig(
instrument_id="BTC-USD-PERP",
),
)
# 2. Iceberg / TWAP Detection
node.add_strategy(
IcebergDetector,
IcebergDetectorConfig(
instrument_id="BTC-USD-PERP",
),
)
# 3. Funding Rate Arbitrage
node.add_strategy(
FundingRateArb,
FundingRateArbConfig(
spot_instrument="BTC-SPOT",
perp_instrument="BTC-USD-PERP",
),
)
# 4. Pairs Trading (BTC/ETH)
node.add_strategy(
PairsTrading,
PairsTradingConfig(
pair=("BTC-USD-PERP", "ETH-USD-PERP"),
),
)
# 5. Avellaneda-Stoikov Market Making
node.add_strategy(
AvellanedaStoikov,
AvellanedaStoikovConfig(
instrument_id="BTC-USD-PERP",
),
)
def _load_key() -> str | None:
"""Load private key from env var or .env file."""
key = os.getenv("HYPERLIQUID_TESTNET_PK")
if key:
return key
# Fallback: read from .env file
env_file = Path(__file__).resolve().parent.parent / ".env"
if env_file.exists():
for line in env_file.read_text().splitlines():
if line.startswith("HYPERLIQUID_TESTNET_PK="):
return line.split("=", 1)[1].strip()
return None
async def main():
private_key = _load_key()
if not private_key:
print("ERROR: Set HYPERLIQUID_TESTNET_PK environment variable")
print(" or create a .env file in the project root.")
sys.exit(1)
print("=" * 55)
print(" FTDT Quant Lab - Live Trading Node")
print(" Hyperliquid Testnet")
print("=" * 55)
print()
print("Strategies:")
print(" 1. Order Book Imbalance (OFI)")
print(" 2. Iceberg / TWAP Detection")
print(" 3. Funding Rate Arbitrage")
print(" 4. Pairs Trading (BTC/ETH)")
print(" 5. Avellaneda-Stoikov Market Making")
print()
node = build_node(private_key)
register_strategies(node)
print("Connecting to Hyperliquid Testnet...")
try:
await node.start()
print("Node started. Running strategies...")
print("Press Ctrl+C to stop.")
await node.run_until_stopped()
except KeyboardInterrupt:
print("\nShutting down...")
finally:
await node.stop()
print("Node stopped. Goodbye.")
if __name__ == "__main__":
asyncio.run(main())