mirror of
https://github.com/BrentNeale1/fx-quant.git
synced 2026-08-06 07:07:45 +00:00
39a6536284
- S7 Liquidity Sweep: built, tested across 6 pairs, tight SL (1.0 ATR) on GBP_JPY is Phase 2 candidate (107 trades, OOS PF 1.39, gen ratio 1.81) - S8 Order Block: built, tested on GBP_JPY (watchlist, 32 trades, OOS PF 1.55) - S9 London Session: built, tested across 8 pairs with filter experiments GBP_USD (OOS PF 1.45) and GBP_AUD filtered (OOS PF 1.94) advance to Phase 2 - Added OBV indicator to technical.py - Added GBP_NZD to engine spread/pip config - Standalone OANDA fetcher (bypasses Supabase dependency) - Fetched EUR_GBP, EUR_USD, GBP_NZD H1 data (2021-2023) - Consolidated STRATEGY_LEARNINGS.md with full Phase 1 scorecard and 11 design principles - Phase 2 roster: S7/GBP_JPY, S9/GBP_USD, S9F/GBP_AUD, S4-F/EUR_AUD, S3/GBP_JPY Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
62 lines
2.4 KiB
Python
62 lines
2.4 KiB
Python
"""S7 Tight — Full dataset validation for GBP_USD and EUR_USD."""
|
|
import os, sys, io, time
|
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
|
|
|
|
import pandas as pd
|
|
from src.indicators.technical import compute_all_indicators
|
|
from src.backtester.engine import Backtester
|
|
from src.strategies_pkg.s7_liquidity_sweep import S7_Liquidity_Sweep
|
|
|
|
PROCESSED_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "data", "processed")
|
|
RESULTS_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "results", "phase1")
|
|
os.makedirs(RESULTS_DIR, exist_ok=True)
|
|
|
|
TRAIN_RATIO = 0.70
|
|
|
|
for pair in ["GBP_USD", "EUR_USD"]:
|
|
print(f"\n{'#' * 70}")
|
|
print(f"# S7 Tight — {pair} FULL DATASET")
|
|
print(f"{'#' * 70}")
|
|
|
|
fp = os.path.join(PROCESSED_DIR, f"{pair}_H1.csv")
|
|
df = pd.read_csv(fp, index_col=0, parse_dates=True)
|
|
df.index.name = "timestamp"
|
|
df = compute_all_indicators(df)
|
|
htf = df.copy()
|
|
print(f" Data: {len(df)} H1 bars, {df.index[0].date()} to {df.index[-1].date()}")
|
|
|
|
split_idx = int(len(df) * TRAIN_RATIO)
|
|
splits = {
|
|
"FULL": (df, htf),
|
|
"TRAIN": (df.iloc[:split_idx], htf.iloc[:split_idx]),
|
|
"TEST": (df.iloc[split_idx:], htf.iloc[split_idx:]),
|
|
}
|
|
|
|
for phase, (d, h) in splits.items():
|
|
t0 = time.time()
|
|
bt = Backtester(data=d, strategy=S7_Liquidity_Sweep(), pair=pair,
|
|
starting_equity=100_000.0, htf_data=h)
|
|
r = bt.run()
|
|
tl = bt.get_trade_log_df()
|
|
elapsed = time.time() - t0
|
|
|
|
n = r.get("total_trades", 0)
|
|
wr = r.get("win_rate_pct", 0)
|
|
pf = r.get("profit_factor", 0)
|
|
pnl = r.get("total_pnl_pips", 0)
|
|
pnl_d = r.get("total_pnl_dollars", 0)
|
|
dd = r.get("max_drawdown_pct", 0)
|
|
aw = r.get("avg_win_pips", 0)
|
|
al = r.get("avg_loss_pips", 0)
|
|
rr = aw / al if al > 0 else 0
|
|
exp = pnl / n if n > 0 else 0
|
|
|
|
print(f" {phase:>5}: {n:>3} trades | WR {wr:>5.1f}% | PF {pf:>5.2f} | "
|
|
f"PnL {pnl:>+8.1f}p (${pnl_d:>+10,.2f}) | DD {dd:>6.2f}% | "
|
|
f"AvgW {aw:>5.1f} / AvgL {al:>5.1f} | RR {rr:>4.2f} | "
|
|
f"Exp {exp:>+6.2f}p ({elapsed:.0f}s)")
|
|
|
|
if len(tl) > 0:
|
|
tl.to_csv(os.path.join(RESULTS_DIR, f"S7T_{pair}_FULL_{phase}_trades.csv"), index=False)
|