import sys import os import csv import itertools from decimal import Decimal # Add project root to path current_dir = os.path.dirname(os.path.abspath(__file__)) project_root = os.path.dirname(os.path.dirname(current_dir)) sys.path.append(project_root) from tests.backtest.backtester import Backtester def main(): # Grid Parameters # We want to optimize: # 1. RANGE_WIDTH_PCT: How wide is the LP position? (e.g. 0.01 = +/-1%, 0.05 = +/-5%) # 2. BASE_REBALANCE_THRESHOLD_PCT: When do we hedge? (e.g. 0.10 = 10% delta drift, 0.20 = 20%) param_grid = { "RANGE_WIDTH_PCT": [0.005, 0.01, 0.025, 0.05], "BASE_REBALANCE_THRESHOLD_PCT": [0.01, 0.05] } keys, values = zip(*param_grid.items()) combinations = [dict(zip(keys, v)) for v in itertools.product(*values)] results = [] book_file = os.path.join(project_root, "market_data", "BNB_raw_20251230_book.csv") trades_file = os.path.join(project_root, "market_data", "BNB_raw_20251230_trades.csv") print(f"Starting Grid Search with {len(combinations)} combinations...") for idx, config in enumerate(combinations): print(f"\n--- Run {idx+1}/{len(combinations)}: {config} ---") # Initialize Backtester with overrides bt = Backtester(book_file, trades_file, config_overrides=config) try: bt.run() # Collect Metrics uni_fees = bt.state.uni_fees_collected hl_realized = bt.state.hl_realized_pnl - bt.state.hl_fees_paid # HL Unrealized hl_unrealized = sum(p['unrealized_pnl'] for p in bt.state.hl_positions.values()) # Total PnL (Yield + Hedge Result) - Ignoring IL for now (Mock limitation) total_pnl = uni_fees + hl_realized + hl_unrealized result = { **config, "UNI_FEES": float(uni_fees), "HL_REALIZED": float(hl_realized), "HL_UNREALIZED": float(hl_unrealized), "TOTAL_PNL": float(total_pnl) } results.append(result) print(f"Result: {result}") except Exception as e: print(f"Run failed: {e}") import traceback traceback.print_exc() # Save Results out_file = os.path.join(current_dir, "optimization_results.csv") keys = list(combinations[0].keys()) + ["UNI_FEES", "HL_REALIZED", "HL_UNREALIZED", "TOTAL_PNL"] with open(out_file, 'w', newline='') as f: writer = csv.DictWriter(f, fieldnames=keys) writer.writeheader() writer.writerows(results) print(f"\nGrid Search Complete. Results saved to {out_file}") if __name__ == "__main__": main()