This commit is contained in:
2025-06-20 18:06:04 -04:00
parent 95b25eddd7
commit 6cd82b3621
6 changed files with 114 additions and 65 deletions
+44 -45
View File
@@ -10,7 +10,7 @@ from typing import Any, Dict, List, Optional
import pandas as pd
from tools.data_loader import load_market_data
from tools.data_loader import get_available_instruments_from_db, load_market_data
from tools.trading_pair import TradingPair
from results import BacktestResult, create_result_database, store_results_in_database, store_config_in_database
@@ -21,40 +21,40 @@ def load_config(config_path: str) -> Dict:
return config
def get_available_instruments_from_db(datafile: str, config: Dict) -> List[str]:
"""
Auto-detect available instruments from the database by querying distinct instrument_id values.
Returns instruments without the configured prefix.
"""
try:
conn = sqlite3.connect(datafile)
# def get_available_instruments_from_db(datafile: str, config: Dict) -> List[str]:
# """
# Auto-detect available instruments from the database by querying distinct instrument_id values.
# Returns instruments without the configured prefix.
# """
# try:
# conn = sqlite3.connect(datafile)
# Query to get distinct instrument_ids
query = f"""
SELECT DISTINCT instrument_id
FROM {config['db_table_name']}
WHERE exchange_id = ?
"""
# # Query to get distinct instrument_ids
# query = f"""
# SELECT DISTINCT instrument_id
# FROM {config['db_table_name']}
# WHERE exchange_id = ?
# """
cursor = conn.execute(query, (config["exchange_id"],))
instrument_ids = [row[0] for row in cursor.fetchall()]
conn.close()
# cursor = conn.execute(query, (config["exchange_id"],))
# instrument_ids = [row[0] for row in cursor.fetchall()]
# conn.close()
# Remove the configured prefix to get instrument symbols
prefix = config.get("instrument_id_pfx", "")
instruments = []
for instrument_id in instrument_ids:
if instrument_id.startswith(prefix):
symbol = instrument_id[len(prefix) :]
instruments.append(symbol)
else:
instruments.append(instrument_id)
# # Remove the configured prefix to get instrument symbols
# prefix = config.get("instrument_id_pfx", "")
# instruments = []
# for instrument_id in instrument_ids:
# if instrument_id.startswith(prefix):
# symbol = instrument_id[len(prefix) :]
# instruments.append(symbol)
# else:
# instruments.append(instrument_id)
return sorted(instruments)
# return sorted(instruments)
except Exception as e:
print(f"Error auto-detecting instruments from {datafile}: {str(e)}")
return []
# except Exception as e:
# print(f"Error auto-detecting instruments from {datafile}: {str(e)}")
# return []
def resolve_datafiles(config: Dict, cli_datafiles: Optional[str] = None) -> List[str]:
@@ -100,13 +100,13 @@ def run_backtest(
config: Dict,
datafile: str,
price_column: str,
bt_result: BacktestResult,
strategy,
instruments: List[str],
) -> None:
) -> BacktestResult:
"""
Run backtest for all pairs using the specified instruments.
"""
bt_result: BacktestResult = BacktestResult(config=config)
def _create_pairs(config: Dict, instruments: List[str]) -> List[TradingPair]:
nonlocal datafile
@@ -141,13 +141,14 @@ def run_backtest(
# Check if result_list has any data before concatenating
if len(pairs_trades) == 0:
print("No trading signals found for any pairs")
return None
return bt_result
result = pd.concat(pairs_trades, ignore_index=True)
result["time"] = pd.to_datetime(result["time"])
result = result.set_index("time").sort_index()
bt_result.collect_single_day_results(result)
return bt_result
def main() -> None:
@@ -201,7 +202,6 @@ def main() -> None:
# Initialize a dictionary to store all trade results
all_results: Dict[str, Dict[str, Any]] = {}
bt_results = BacktestResult(config=config)
# Store configuration in database for reference
if args.result_db.upper() != "NONE":
@@ -232,9 +232,6 @@ def main() -> None:
for datafile in datafiles:
print(f"\n====== Processing {os.path.basename(datafile)} ======")
# Clear the trades for the new file
bt_results.clear_trades()
# Determine instruments to use
if args.instruments:
# Use CLI-specified instruments
@@ -251,11 +248,12 @@ def main() -> None:
# Process data for this file
try:
run_backtest(
strategy.reset()
bt_results = run_backtest(
config=config,
datafile=datafile,
price_column=price_column,
bt_result=bt_results,
strategy=strategy,
instruments=instruments,
)
@@ -270,17 +268,18 @@ def main() -> None:
print(f"Successfully processed {filename}")
except Exception as e:
print(f"Error processing {datafile}: {str(e)}")
except Exception as err:
print(f"Error processing {datafile}: {str(err)}")
import traceback
traceback.print_exc()
# Calculate and print results
# Calculate and print results using a new BacktestResult instance for aggregation
if all_results:
bt_results.calculate_returns(all_results)
bt_results.print_grand_totals()
bt_results.print_outstanding_positions()
aggregate_bt_results = BacktestResult(config=config)
aggregate_bt_results.calculate_returns(all_results)
aggregate_bt_results.print_grand_totals()
aggregate_bt_results.print_outstanding_positions()
if args.result_db.upper() != "NONE":
print(f"\nResults stored in database: {args.result_db}")