feat: funding arb strategy, queue-aware paper fills, WQI live integration
- strategies/funding_arb_strategy.py: full backtestable funding rate carry module with entry/exit thresholds, position tracking, funding payment accounting, basis stop-loss, max-hold timeout. Includes backtest_funding_arb() and run_funding_discovery() for threshold optimization - live/node_v2.py: replaced naive random fills with QueueAwareFillModel (sim/fills.py) with queue-priority simulation; integrated WQI predictor and funding arb strategies; per-coin WQI signal generation every 3 ticks; funding arb metrics in dashboard - cli.py: added 'funding' command for funding rate distribution analysis and threshold backtesting - tests/test_funding_arb.py: 20 tests covering entry/exit logic, fee accounting, signal generation, backtesting, and node integration 321 tests passing (20 new).
This commit is contained in:
@@ -499,6 +499,52 @@ def cmd_discover(args):
|
||||
print(f"\nPipeline ready. Run 'python -m cli tick' to backtest strategies on this data.")
|
||||
|
||||
|
||||
def cmd_funding(args):
|
||||
"""Funding rate arb discovery — analyze historical funding rates and run backtests."""
|
||||
from strategies.funding_arb_strategy import run_funding_discovery
|
||||
import json as _json
|
||||
|
||||
result = run_funding_discovery(
|
||||
data_dir=args.data_dir,
|
||||
coin=args.coin,
|
||||
start_date=args.start_date,
|
||||
end_date=args.end_date,
|
||||
)
|
||||
|
||||
if "error" in result:
|
||||
print(f"Error: {result['error']}")
|
||||
return
|
||||
|
||||
print(f"\n{'═' * 60}")
|
||||
print(f" Funding Rate Analysis — {args.coin}")
|
||||
print(f" {result['n_observations']:,} observations")
|
||||
print(f"{'═' * 60}")
|
||||
|
||||
dist = result["rate_distribution"]
|
||||
print(f"\n Rate Distribution (annualized):")
|
||||
print(f" Mean: {dist['mean_apr_pct']:>8.2f}%")
|
||||
print(f" Std: {dist['std_apr_pct']:>8.2f}%")
|
||||
print(f" Max: {dist['max_apr_pct']:>8.2f}%")
|
||||
print(f" Min: {dist['min_apr_pct']:>8.2f}%")
|
||||
print(f"\n Absolute Rate Percentiles:")
|
||||
for k, v in dist["abs_percentiles"].items():
|
||||
print(f" {k}: {v:>8.2f}%")
|
||||
|
||||
print(f"\n{'─' * 60}")
|
||||
print(f" Backtest Results by Threshold:")
|
||||
print(f" {'Threshold':>12s} {'Trades':>7s} {'Win Rate':>9s} "
|
||||
f"{'Net PnL':>10s} {'Avg PnL':>10s} {'Avg Hold':>9s}")
|
||||
print(f" {'─' * 60}")
|
||||
for label, bt in result.get("backtests", {}).items():
|
||||
print(f" {label:>12s} {bt['total_trades']:>7d} "
|
||||
f"{bt['win_rate']:>8.1%} "
|
||||
f"${bt['total_net_pnl']:>9.4f} ${bt['avg_net_pnl']:>9.4f} "
|
||||
f"{bt['avg_hold_hours']:>8.1f}h")
|
||||
|
||||
print(f"\n Run 'python -m cli collect --mainnet' to gather data.")
|
||||
print(f" Then 'python -m cli funding --coin BTC' to re-run.")
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
p = argparse.ArgumentParser(description="FTDT Quant Lab CLI")
|
||||
@@ -578,6 +624,13 @@ def main():
|
||||
pd.add_argument("--end-date", default="2026-08-07")
|
||||
pd.add_argument("--horizons", default="100,500,1000,5000,10000", help="Comma-separated ms horizons")
|
||||
|
||||
# funding
|
||||
pf = sp.add_parser("funding", help="Funding rate arb discovery — analyze historical funding rates")
|
||||
pf.add_argument("--data-dir", default="data/raw")
|
||||
pf.add_argument("--coin", default="BTC")
|
||||
pf.add_argument("--start-date", default="2026-01-01")
|
||||
pf.add_argument("--end-date", default="2030-01-01")
|
||||
|
||||
args = p.parse_args()
|
||||
|
||||
import json as _json
|
||||
@@ -598,6 +651,8 @@ def main():
|
||||
cmd_tick_backtest(args)
|
||||
elif args.command == "discover":
|
||||
cmd_discover(args)
|
||||
elif args.command == "funding":
|
||||
cmd_funding(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user