-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbacktest.py
70 lines (57 loc) · 2.14 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
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
def Sharpe(pnl:pd.Series)->float:
sharpe = np.sqrt(365*24*60) * (pnl - 3.8e-8).mean() / (pnl - 3.8e-8).std()
return sharpe
def generate_signal(df:pd.DataFrame)->pd.Series:
N = 20
k = 2
Ma = df['close'].rolling(N).mean()
Sd = df['close'].rolling(N).std()
Mb = Ma + k*Sd
Dn = Ma - k*Sd
raw_Signal = (df['close'] < Dn ) * 0.1
# raw_Signal = -(df['close'].astype(float)/df['open'].astype(float) -1)*100
# raw_Signal = raw_Signal *(raw_Signal>0)
return raw_Signal
def position_restrict(Signal:pd.Series, window):
Close_position = Signal.shift(window).fillna(0)
Position = (Signal - Close_position).cumsum()
Restrict = abs(Position) <= 1
new_Signal = (Signal * Restrict).astype(float)
return new_Signal
def calculate_pnl(Position:pd.Series, Return:pd.Series):
Return = Return.dropna()
Position = Position.reindex_like(Return)
pnl = Position * Return
return pnl
def calculate_cost(Position:pd.Series):
cost = abs(Position.diff()) * 0.00075
return cost
def main():
df = pd.read_parquet('2024.parquet')[:1000]
window = 5
df['return'] = df['close'].astype(float).diff(1).shift(-1) / df['close'].astype(float)
row_Signal = generate_signal(df)
Signal = position_restrict(row_Signal, window)
pnl = calculate_pnl(Signal, df['return'])
pnl.index = pd.to_datetime(pnl.index, unit='ms')
Position = (Signal - Signal.shift(window).fillna(0)).cumsum()
Position.index = pd.to_datetime(Position.index, unit='ms')
Position = Position.reindex_like(pnl)
cost = calculate_cost(Position)
pnl_net = pnl - cost
plt.figure(figsize=[32, 16])
p1 = plt.subplot(211)
p2 = plt.subplot(212)
p1.plot((1+pnl.fillna(0)).cumprod(), label=f"PNL, Sharpe: {Sharpe(pnl)}")
p1.plot((1+pnl_net.fillna(0)).cumprod(), label=f"PNL_Net, Sharpe: {Sharpe(pnl_net)}")
p1.grid(linestyle='--')
p1.legend(loc='upper left')
p2.plot(Position, label=f"PNL_Net")
p2.grid(linestyle='--')
p2.legend(loc='upper left')
plt.show()
if __name__ == '__main__':
main()