-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtest_strategy_load.py
More file actions
134 lines (112 loc) · 4.49 KB
/
test_strategy_load.py
File metadata and controls
134 lines (112 loc) · 4.49 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
#!/usr/bin/env python3
"""Test: verify strategy loading and backtest execution for built-in templates."""
import sys
import traceback
from pathlib import Path
# Add backend to path
sys.path.insert(0, str(Path(__file__).parent / "src" / "backend"))
import backtrader as bt
def test_load_strategy(strategy_id: str = "002_dual_ma"):
"""Test loading a single strategy from templates."""
from app.services.strategy_service import STRATEGIES_DIR, get_template_by_id
print(f"\n{'='*60}")
print(f"Testing strategy: {strategy_id}")
print(f"STRATEGIES_DIR: {STRATEGIES_DIR}")
print(f"STRATEGIES_DIR exists: {STRATEGIES_DIR.is_dir()}")
# 1) Check template exists
template = get_template_by_id(strategy_id)
if not template:
print(f"FAIL: Template '{strategy_id}' not found in STRATEGY_TEMPLATES")
return False
print(f"Template found: {template.name}")
# 2) Check strategy file exists
strategy_dir = STRATEGIES_DIR / strategy_id
code_files = list(strategy_dir.glob("strategy_*.py"))
print(f"Strategy dir: {strategy_dir}")
print(f"Code files: {code_files}")
# 3) Try loading via _load_strategy_from_code logic
import types as _types
module_name = f"strategy_{strategy_id}"
import builtins
module = _types.ModuleType(module_name)
module.__dict__['__builtins__'] = builtins
# Register in sys.modules so backtrader metaclass can find it
sys.modules[module_name] = module
if code_files:
real_file = str(code_files[0])
module.__dict__['__file__'] = real_file
str_dir = str(strategy_dir)
if str_dir not in sys.path:
sys.path.insert(0, str_dir)
print(f"Injected __file__: {real_file}")
code = template.code
print(f"Code length: {len(code)} chars")
print(f"Code first 200 chars:\n{code[:200]}")
print(f"\n--- Executing code ---")
try:
compiled = compile(code, module.__dict__.get('__file__', '<strategy>'), 'exec')
exec(compiled, module.__dict__)
except Exception as e:
print(f"FAIL during exec: {type(e).__name__}: {e}")
traceback.print_exc()
return False
# 4) Find Strategy subclass
strategy_class = None
for name, obj in module.__dict__.items():
if isinstance(obj, type) and issubclass(obj, bt.Strategy) and obj is not bt.Strategy:
strategy_class = obj
print(f"Found strategy class: {name} -> {obj}")
break
if not strategy_class:
print("FAIL: No bt.Strategy subclass found")
# Show all classes defined
for name, obj in module.__dict__.items():
if isinstance(obj, type):
print(f" class: {name} bases={obj.__bases__}")
return False
# 5) Quick backtest smoke test
print(f"\n--- Running mini backtest with {strategy_class.__name__} ---")
try:
cerebro = bt.Cerebro()
cerebro.addstrategy(strategy_class)
# Create minimal synthetic data
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
dates = pd.date_range(start='2024-01-01', periods=100, freq='B')
np.random.seed(42)
price = 100 + np.cumsum(np.random.randn(100) * 0.5)
df = pd.DataFrame({
'open': price,
'high': price + abs(np.random.randn(100) * 0.3),
'low': price - abs(np.random.randn(100) * 0.3),
'close': price + np.random.randn(100) * 0.2,
'volume': np.random.randint(1000, 10000, 100).astype(float),
}, index=dates)
data = bt.feeds.PandasData(dataname=df)
cerebro.adddata(data)
cerebro.broker.setcash(100000)
cerebro.broker.setcommission(commission=0.001)
results = cerebro.run()
final = cerebro.broker.getvalue()
print(f"SUCCESS: Backtest completed. Final value: {final:.2f}")
return True
except Exception as e:
print(f"FAIL during backtest: {type(e).__name__}: {e}")
traceback.print_exc()
return False
if __name__ == "__main__":
# Test a few strategies
test_ids = ["002_dual_ma", "029_macd_kdj", "025_boll"]
results = {}
for sid in test_ids:
try:
results[sid] = test_load_strategy(sid)
except Exception as e:
print(f"UNEXPECTED ERROR for {sid}: {e}")
traceback.print_exc()
results[sid] = False
print(f"\n{'='*60}")
print("RESULTS:")
for sid, ok in results.items():
print(f" {sid}: {'PASS' if ok else 'FAIL'}")