-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrun_earnings_backtest_fmp.py
More file actions
154 lines (132 loc) · 5.24 KB
/
run_earnings_backtest_fmp.py
File metadata and controls
154 lines (132 loc) · 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env python3
"""
Earnings backtest runner using Financial Modeling Prep API for earnings dates.
Strategy: Buy before earnings for companies with market cap > $5B,
with 5% take profit and 5% stop loss.
"""
import sys
import os
from pathlib import Path
import pandas as pd
import json
# Add the backtesting directory to the path
sys.path.insert(0, str(Path(__file__).parent / "backtesting"))
from src.data.provenance import ProvenanceLogger
from src.data.twelvedata_providers import TwelveDataBarsProvider, TwelveDataBenchmarkProvider
from src.data.yfinance_providers import WikipediaUniverseProvider
from src.engine.earnings_backtest_fmp import run_earnings_backtest
from src.engine.email_report import build_email_report, send_email_report, write_email_report
from src.utils.config import ensure_dirs
def main():
# Setup directories
data_dir = Path("backtesting/data")
report_dir = Path("backtesting/reports/latest")
ensure_dirs(data_dir, report_dir)
# Setup providers
cache_dir = data_dir / "cache"
provenance = ProvenanceLogger(Path("backtesting/logs/provenance.jsonl"))
bars_provider = TwelveDataBarsProvider(
cache_dir=cache_dir,
provenance=provenance,
timezone="America/New_York",
open_time="09:30",
close_time="16:00",
source_interval="1h",
fallback_to_sample=False,
api_key=os.getenv("TWELVEDATA_API_KEY"),
base_url="https://api.twelvedata.com",
timeout_seconds=20,
)
benchmark_provider = TwelveDataBenchmarkProvider(
cache_dir=cache_dir,
provenance=provenance,
source_interval="1h",
fallback_to_sample=False,
api_key=os.getenv("TWELVEDATA_API_KEY"),
base_url="https://api.twelvedata.com",
timeout_seconds=20,
)
universe_provider = WikipediaUniverseProvider(
cache_dir=cache_dir,
provenance=provenance,
source_url="https://en.wikipedia.org/wiki/Nasdaq-100",
as_of="2024-12-31",
)
# Get universe
universe = universe_provider.get_universe()
symbols = universe.members
# Backtest period
start_date = "2022-01-01"
end_date = "2022-06-30"
interval = "4H"
print(f"Fetching bars for {len(symbols)} symbols from {start_date} to {end_date}...")
bars = bars_provider.get_bars(symbols, start_date, end_date, interval)
print(f"Got bars for {len(bars)} symbols")
print("Fetching benchmark (SPY)...")
benchmark = benchmark_provider.get_benchmark(start_date, end_date, interval)
print(f"Got benchmark with {len(benchmark)} bars")
if not bars:
print("ERROR: No bar data loaded. Cannot run backtest.")
return
# Build config for earnings strategy
config = {
"strategy": {
"enabled": True,
"type": "earnings_event",
"earnings": {
"take_profit_pct": 0.05, # 5% take profit
"stop_loss_pct": 0.05, # 5% stop loss
"min_market_cap": 5_000_000_000, # $5B market cap
"entry_days_before": 1, # Buy 1 day before earnings
"max_hold_days": 10, # Max hold 10 days
"position_size_pct": 0.1, # 10% position size
"intraday_fill": "stop_first", # If both TP and SL hit, fill stop first
}
},
"backtest": {
"start_date": start_date,
"end_date": end_date,
"initial_capital": 100000,
},
"portfolio": {
"max_positions": 20,
},
"report": {
"title": "Earnings Strategy Backtest",
"notes": "Buy before earnings for companies with market cap > $5B, 5% TP/SL",
},
"email": {
"enabled": True,
"smtp_host": "smtp.gmail.com",
"smtp_port": 587,
"from": "rohan.santhoshkumar1@gmail.com",
"to": ["rohan.santhoshkumar@gmail.com"],
"subject_prefix": "Earnings Backtest",
"username_env": "SMTP_USERNAME",
"password_env": "SMTP_PASSWORD",
"timeout_seconds": 20,
}
}
print("\nRunning earnings backtest...")
result = run_earnings_backtest(bars, benchmark, config, report_dir)
print(f"\nBacktest completed!")
print(f"Total trades: {len(result.trades)}")
print(f"Total P&L: ${result.metrics.get('total_pnl', 0):.2f}")
print(f"Win rate: {result.metrics.get('win_rate', 0):.2%}")
print(f"CAGR: {result.metrics.get('CAGR', 0):.2%}")
print(f"Max drawdown: {result.metrics.get('max_drawdown', 0):.2%}")
print(f"Sharpe ratio: {result.metrics.get('sharpe_ratio', 0):.2f}")
print(f"Total return: {result.metrics.get('total_return', 0):.2%}")
# Generate and send email report
print("\nGenerating email report...")
subject, body = build_email_report(config, report_dir)
write_email_report(subject, body, report_dir / "email_report.txt")
print("Sending email report...")
send_email_report(config, subject, body)
print("Email sent successfully!")
print(f"\nReport saved to: {report_dir}")
print(f"Email report: {report_dir / 'email_report.txt'}")
print(f"Trades: {report_dir / 'trades.csv'}")
print(f"Metrics: {report_dir / 'metrics.json'}")
if __name__ == "__main__":
main()