-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathBacktest.py
139 lines (118 loc) · 4.78 KB
/
Backtest.py
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
135
136
137
138
139
# -*- coding: utf-8 -*-
"""
Created on Fri May 18 21:41:19 2018
@author: mai1346
"""
import queue
import time
import pandas as pd
import Performance as pf
import Plot
class Backtest(object):
'''
回测类,
'''
def __init__(
self, symbol_list, initial_capital,
heartbeat, start_date, end_date, data_handler,
execution_handler, portfolio, risk_manager, strategy, benchmark
):
'''
初始化回测,
symbol_list - 应用策略的标的资产列表
intial_capital - 初始资金
heartbeat - 等待间隔,回测中默认为0,实盘系统则按需求进行调整
start_date - 回测开始日期
end_date - 回测结束日期
data_handler - 数据源类
execution_handler - 执行类
portfolio - Portfolio类
strategy - 策略类
'''
self.symbol_list = symbol_list
self.initial_capital = initial_capital
self.heartbeat = heartbeat
self.start_date = start_date
self.end_date = end_date
self.benchmark = benchmark
self.data_handler_cls = data_handler
self.execution_handler_cls = execution_handler
self.portfolio_cls = portfolio
self.strategy_cls = strategy
self.risk_manager_cls = risk_manager
self.events = queue.Queue()
self.signals = 0
self.orders = 0
self.fills = 0
self.num_strats = 1
self._create_trading_instances()
def _create_trading_instances(self):
'''
根据输入信息实例化所有类
'''
print(
"Creating DataHandler, Strategy, Portfolio and ExecutionHandler"
)
self.data_handler = self.data_handler_cls(self.events, self.symbol_list, self.start_date,
self.end_date)
self.strategy = self.strategy_cls(self.data_handler, self.events)
self.portfolio = self.portfolio_cls(self.data_handler, self.events, self.start_date,
self.initial_capital)
self.execution_handler = self.execution_handler_cls(self.events, self.data_handler)
self.risk_manager = self.risk_manager_cls(self.events, self.portfolio, self.data_handler)
def _run_backtest(self):
'''
回测主循环
'''
# Handle the events
while True:
try:
event = self.events.get(False)
except queue.Empty:
self.data_handler.update_bars()
else:
if not self.data_handler.continue_backtest:
break
elif event is not None:
if event.type == 'MARKET':
self.strategy.generate_signal(event)
self.portfolio.update_timeindex()
elif event.type == 'SIGNAL':
self.signals += 1
self.risk_manager.update_signal(event)
elif event.type == 'ORDER':
self.orders += 1
self.execution_handler.execute_order(event)
elif event.type == 'FILL':
self.fills += 1
self.portfolio.update_fill(event)
time.sleep(self.heartbeat)
def _output_performance(self):
'''
输出所有Performance
'''
print ("Creating equity curve...")
df= pf.create_equity_curve_dataframe(self.portfolio.all_holdings)
print (df.head(40))
bench = pf.create_benchmark_dataframe(self.benchmark, self.start_date, self.end_date)
print ("Creating summary stats...")
stats, strategy_drawdown, bench_drawdown = pf.output_summary_stats(df, bench)
print (stats)
print ("Signals: %s" % self.signals)
print ("Orders: %s" % self.orders)
print ("Fills: %s" % self.fills)
output_df = pd.DataFrame({'strategy_equity':df['equity_curve'], 'bench_equity':bench['bench_curve'],
'strategy_drawdown':strategy_drawdown, 'bench_drawdown':bench_drawdown})
output_df.fillna(method = 'ffill', inplace = True)
Plot.plot_equity_performance(output_df)
print ("Creating trade statistics...")
trade_log = self.portfolio.Tradelog
trade_log.create_trade_summary()
trade_plot_data = pf.create_trade_plot_dataframe(self.symbol_list, self.data_handler)
Plot.plot_trade(trade_log.get_Tradelog(), trade_plot_data)
def simulate_trading(self):
'''
进行模拟回测
'''
self._run_backtest()
self._output_performance()