using configuration file
This commit is contained in:
parent
200a1bf307
commit
671422976d
33
configuration/crypto.cfg
Normal file
33
configuration/crypto.cfg
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"security_type": "CRYPTO",
|
||||
"data_directory": "./data/crypto",
|
||||
"datafiles": [
|
||||
"20250519.mktdata.ohlcv.db"
|
||||
],
|
||||
"db_table_name": "bnbspot_ohlcv_1min",
|
||||
"exchange_id": "BNBSPOT",
|
||||
"instrument_id_pfx": "PAIR-",
|
||||
"instruments": [
|
||||
"BTC-USDT",
|
||||
"BCH-USDT",
|
||||
"ETH-USDT",
|
||||
"LTC-USDT",
|
||||
"XRP-USDT",
|
||||
"ADA-USDT",
|
||||
"SOL-USDT",
|
||||
"DOT-USDT"
|
||||
],
|
||||
"trading_hours": {
|
||||
"begin_session": "00:00:00",
|
||||
"end_session": "23:59:00",
|
||||
"timezone": "UTC"
|
||||
},
|
||||
"price_column": "close",
|
||||
"min_required_points": 30,
|
||||
"zero_threshold": 1e-10,
|
||||
"dis-equilibrium_open_trshld": 2.0,
|
||||
"dis-equilibrium_close_trshld": 0.5,
|
||||
"training_minutes": 120,
|
||||
"funding_per_pair": 2000.0,
|
||||
"strategy_class": "strategies.StaticFitStrategy"
|
||||
}
|
||||
35
configuration/equity.cfg
Normal file
35
configuration/equity.cfg
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"security_type": "EQUITY",
|
||||
"data_directory": "./data/equity",
|
||||
"datafiles": [
|
||||
# "20250508.alpaca_sim_md.db",
|
||||
"20250509.alpaca_sim_md.db",
|
||||
# "20250512.alpaca_sim_md.db",
|
||||
# "20250513.alpaca_sim_md.db",
|
||||
# "20250514.alpaca_sim_md.db",
|
||||
# "20250515.alpaca_sim_md.db",
|
||||
# "20250516.alpaca_sim_md.db",
|
||||
# "20250519.alpaca_sim_md.db",
|
||||
# "20250520.alpaca_sim_md.db"
|
||||
],
|
||||
"db_table_name": "md_1min_bars",
|
||||
"exchange_id": "ALPACA",
|
||||
"instrument_id_pfx": "STOCK-",
|
||||
"instruments": [
|
||||
"COIN",
|
||||
"GBTC"
|
||||
],
|
||||
"trading_hours": {
|
||||
"begin_session": "9:30:00",
|
||||
"end_session": "16:00:00",
|
||||
"timezone": "America/New_York"
|
||||
},
|
||||
"price_column": "close",
|
||||
"min_required_points": 30,
|
||||
"zero_threshold": 1e-10,
|
||||
"dis-equilibrium_open_trshld": 2.0,
|
||||
"dis-equilibrium_close_trshld": 1.0,
|
||||
"training_minutes": 120,
|
||||
"funding_per_pair": 2000.0,
|
||||
"strategy_class": "strategies.StaticFitStrategy"
|
||||
}
|
||||
1
prompts/20250612.testing_code_request.txt
Normal file
1
prompts/20250612.testing_code_request.txt
Normal file
@ -0,0 +1 @@
|
||||
Create python code that tests pairs trading strategy
|
||||
28
scripts/load_crypto_1min.sh
Executable file
28
scripts/load_crypto_1min.sh
Executable file
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# -------------------------------------
|
||||
# --- Given month, specific dates
|
||||
# -------------------------------------
|
||||
|
||||
# for dt in 20250528 20250529 20250530 20250531; do
|
||||
# rsync -ahvv cvtt@hs01.cvtt.vpn:/works/cvtt/md_archive/crypto/sim/2025/2025-05/${dt}.*.gz ./
|
||||
# done
|
||||
# -------------------------------------
|
||||
|
||||
# -------------------------------------
|
||||
# --- Current month - all files
|
||||
# -------------------------------------
|
||||
pushd ./data/crypto
|
||||
rsync -ahvv cvtt@hs01.cvtt.vpn:/works/cvtt/md_archive/crypto/sim/*.gz ./
|
||||
# -------------------------------------
|
||||
|
||||
for srcfname in $(ls *.db.gz); do
|
||||
dt="${srcfname:0:8}"
|
||||
tgtfile=${dt}.mktdata.ohlcv.db
|
||||
echo "${srcfname} -> ${tgtfile}"
|
||||
|
||||
gunzip -c $srcfname > temp.db
|
||||
rm -f ${tgtfile} && sqlite3 temp.db ".dump md_1min_bars" | sqlite3 ${tgtfile} && rm ${srcfname}
|
||||
done
|
||||
rm temp.db
|
||||
popd
|
||||
File diff suppressed because one or more lines are too long
@ -1,3 +1,6 @@
|
||||
import argparse
|
||||
import hjson
|
||||
import importlib
|
||||
|
||||
from typing import Any, Dict, List
|
||||
|
||||
@ -9,106 +12,15 @@ from tools.trading_pair import TradingPair
|
||||
from results import BacktestResult
|
||||
|
||||
|
||||
# ------------------------ Configuration ------------------------
|
||||
# Default configuration
|
||||
CRYPTO_CONFIG: Dict = {
|
||||
"security_type": "CRYPTO",
|
||||
# --- Data retrieval
|
||||
"data_directory": "./data/crypto",
|
||||
"datafiles": [
|
||||
"20250519.mktdata.ohlcv.db",
|
||||
# "20250520.mktdata.ohlcv.db",
|
||||
# "20250521.mktdata.ohlcv.db",
|
||||
# "20250522.mktdata.ohlcv.db",
|
||||
# "20250523.mktdata.ohlcv.db",
|
||||
# "20250524.mktdata.ohlcv.db",
|
||||
# "20250525.mktdata.ohlcv.db",
|
||||
],
|
||||
"db_table_name": "bnbspot_ohlcv_1min",
|
||||
# ----- Instruments
|
||||
"exchange_id": "BNBSPOT",
|
||||
"instrument_id_pfx": "PAIR-",
|
||||
"instruments": [
|
||||
"BTC-USDT",
|
||||
"BCH-USDT",
|
||||
"ETH-USDT",
|
||||
"LTC-USDT",
|
||||
"XRP-USDT",
|
||||
"ADA-USDT",
|
||||
"SOL-USDT",
|
||||
"DOT-USDT",
|
||||
],
|
||||
"trading_hours": {
|
||||
"begin_session": "00:00:00",
|
||||
"end_session": "23:59:00",
|
||||
"timezone": "UTC",
|
||||
},
|
||||
# ----- Model Settings
|
||||
"price_column": "close",
|
||||
"min_required_points": 30,
|
||||
"zero_threshold": 1e-10,
|
||||
|
||||
"dis-equilibrium_open_trshld": 2.0,
|
||||
"dis-equilibrium_close_trshld": 0.5,
|
||||
|
||||
# "training_minutes": 120,
|
||||
"training_minutes": 120,
|
||||
# ----- Validation
|
||||
"funding_per_pair": 2000.0, # USD
|
||||
}
|
||||
|
||||
# ========================== EQUITIES
|
||||
EQT_CONFIG: Dict = {
|
||||
# --- Data retrieval
|
||||
"security_type": "EQUITY",
|
||||
"data_directory": "./data/equity",
|
||||
"datafiles": [
|
||||
# "20250508.alpaca_sim_md.db",
|
||||
"20250509.alpaca_sim_md.db",
|
||||
# "20250512.alpaca_sim_md.db",
|
||||
# "20250513.alpaca_sim_md.db",
|
||||
# "20250514.alpaca_sim_md.db",
|
||||
# "20250515.alpaca_sim_md.db",
|
||||
# "20250516.alpaca_sim_md.db",
|
||||
# "20250519.alpaca_sim_md.db",
|
||||
# "20250520.alpaca_sim_md.db"
|
||||
],
|
||||
"db_table_name": "md_1min_bars",
|
||||
# ----- Instruments
|
||||
"exchange_id": "ALPACA",
|
||||
"instrument_id_pfx": "STOCK-",
|
||||
"instruments": [
|
||||
"COIN",
|
||||
"GBTC",
|
||||
# "HOOD",
|
||||
# "MSTR",
|
||||
# "PYPL",
|
||||
],
|
||||
"trading_hours": {
|
||||
"begin_session": "9:30:00",
|
||||
"end_session": "16:00:00",
|
||||
"timezone": "America/New_York",
|
||||
},
|
||||
# ----- Model Settings
|
||||
"price_column": "close",
|
||||
"min_required_points": 30,
|
||||
"zero_threshold": 1e-10,
|
||||
"dis-equilibrium_open_trshld": 2.0,
|
||||
"dis-equilibrium_close_trshld": 1.0, #0.5,
|
||||
"training_minutes": 120,
|
||||
# ----- Validation
|
||||
"funding_per_pair": 2000.0,
|
||||
}
|
||||
def load_config(config_path: str) -> Dict:
|
||||
with open(config_path, "r") as f:
|
||||
config = hjson.load(f)
|
||||
return config
|
||||
|
||||
|
||||
# CONFIG = CRYPTO_CONFIG
|
||||
CONFIG = EQT_CONFIG
|
||||
STRATEGY = StaticFitStrategy()
|
||||
|
||||
# CONFIG = CRYPTO_CONFIG
|
||||
# STRATEGY = SlidingFitStrategy()
|
||||
|
||||
def run_all_pairs(config: Dict, datafile: str, price_column: str, bt_result: BacktestResult) -> None:
|
||||
def run_all_pairs(
|
||||
config: Dict, datafile: str, price_column: str, bt_result: BacktestResult, strategy
|
||||
) -> None:
|
||||
|
||||
def _create_pairs(config: Dict) -> List[TradingPair]:
|
||||
nonlocal datafile
|
||||
@ -117,7 +29,7 @@ def run_all_pairs(config: Dict, datafile: str, price_column: str, bt_result: Bac
|
||||
unique_index_pairs = [(i, j) for i in all_indexes for j in all_indexes if i < j]
|
||||
pairs = []
|
||||
market_data_df = load_market_data(
|
||||
f'{config["data_directory"]}/{datafile}', config=CONFIG
|
||||
f'{config["data_directory"]}/{datafile}', config=config
|
||||
)
|
||||
for a_index, b_index in unique_index_pairs:
|
||||
pair = TradingPair(
|
||||
@ -129,10 +41,11 @@ def run_all_pairs(config: Dict, datafile: str, price_column: str, bt_result: Bac
|
||||
pairs.append(pair)
|
||||
return pairs
|
||||
|
||||
|
||||
pairs_trades = []
|
||||
for pair in _create_pairs(config):
|
||||
single_pair_trades = STRATEGY.run_pair(pair=pair, config=CONFIG, bt_result=bt_result)
|
||||
single_pair_trades = strategy.run_pair(
|
||||
pair=pair, config=config, bt_result=bt_result
|
||||
)
|
||||
if single_pair_trades is not None and len(single_pair_trades) > 0:
|
||||
pairs_trades.append(single_pair_trades)
|
||||
# Check if result_list has any data before concatenating
|
||||
@ -149,12 +62,24 @@ def run_all_pairs(config: Dict, datafile: str, price_column: str, bt_result: Bac
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="Run pairs trading backtest.")
|
||||
parser.add_argument(
|
||||
"--config", type=str, required=True, help="Path to the configuration file."
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
CONFIG = load_config(args.config)
|
||||
|
||||
# Dynamically instantiate strategy class
|
||||
strategy_class_name = CONFIG.get("strategy_class", "strategies.StaticFitStrategy")
|
||||
module_name, class_name = strategy_class_name.rsplit(".", 1)
|
||||
module = importlib.import_module(module_name)
|
||||
STRATEGY = getattr(module, class_name)()
|
||||
|
||||
# Initialize a dictionary to store all trade results
|
||||
all_results: Dict[str, Dict[str, Any]] = {}
|
||||
bt_results = BacktestResult(config=CONFIG)
|
||||
|
||||
# Initialize global PnL tracking variables
|
||||
|
||||
# Process each data file
|
||||
price_column = CONFIG["price_column"]
|
||||
for datafile in CONFIG["datafiles"]:
|
||||
@ -166,7 +91,11 @@ def main() -> None:
|
||||
# Process data for this file
|
||||
try:
|
||||
run_all_pairs(
|
||||
config=CONFIG, datafile=datafile, price_column=price_column, bt_result=bt_results
|
||||
config=CONFIG,
|
||||
datafile=datafile,
|
||||
price_column=price_column,
|
||||
bt_result=bt_results,
|
||||
strategy=STRATEGY,
|
||||
)
|
||||
|
||||
# Store results with file name as key
|
||||
@ -175,17 +104,14 @@ def main() -> None:
|
||||
|
||||
print(f"Successfully processed {filename}")
|
||||
|
||||
# No longer printing unrealized PnL since we removed that functionality
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error processing {datafile}: {str(e)}")
|
||||
|
||||
# BacktestResults.print_results_summary(all_results)
|
||||
# Calculate and print results
|
||||
bt_results.calculate_returns(all_results)
|
||||
|
||||
# Print grand totals
|
||||
bt_results.print_grand_totals()
|
||||
bt_results.print_outstanding_positions()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user