-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrun_backtest.py
More file actions
54 lines (42 loc) · 1.93 KB
/
Copy pathrun_backtest.py
File metadata and controls
54 lines (42 loc) · 1.93 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
#!/usr/bin/env python3
"""
Driver: run the baseline single-leg short-premium strategy on TSLA and TSLL.
This is the v1 smoke test for the engine. Once this runs cleanly we move into
Phase 4 (walk-forward optimization over the StrategyConfig knobs).
"""
import argparse
import pandas as pd
from data import build
from backtest import Backtester, compute_metrics, format_metrics, trades_to_dataframe
from strategies import StrategyConfig, pick_entry, check_exits, pick_covered_call, pick_roll, get_config
def run_one(ticker: str, period: str, cfg: StrategyConfig, dump_trades: bool):
df = build(ticker, period=period)
bt = Backtester(
df=df, config=cfg, entry_fn=pick_entry, exit_fn=check_exits, ticker=ticker,
wheel_cc_fn=pick_covered_call if cfg.wheel_enabled else None,
roll_fn=pick_roll if cfg.roll_on_max_loss else None,
)
trades = bt.run()
metrics = compute_metrics(trades)
header = f"=== {ticker} {df.index.min().date()} → {df.index.max().date()} ==="
print(f" config: long_dte={cfg.long_dte} long_target_delta={cfg.long_target_delta} wheel={cfg.wheel_enabled}")
print(format_metrics(metrics, header))
if dump_trades and trades:
out = trades_to_dataframe(trades)
path = f".cache/{ticker}_trades.csv"
out.to_csv(path, index=False)
print(f" trade log {path}")
return trades, metrics
def main():
ap = argparse.ArgumentParser()
ap.add_argument('--tickers', nargs='+', default=['TSLA', 'TSLL'])
ap.add_argument('--period', default='5y')
ap.add_argument('--dump-trades', action='store_true')
ap.add_argument('--wheel', action='store_true', help='Enable wheel mode (accept put assignment, sell covered calls)')
args = ap.parse_args()
for tkr in args.tickers:
print()
cfg = get_config(tkr, wheel_enabled=args.wheel)
run_one(tkr, args.period, cfg, args.dump_trades)
if __name__ == "__main__":
main()