0%

vectorbt学习_41DMA之一基础策略

基于vectorbt的基础双均线策略

01,基础配置信息

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
#conda envs:vectorbt_env
import warnings
import vectorbt as vbt
import numpy as np
import pandas as pd
from datetime import datetime, timedelta
import pytz
from dateutil.parser import parse
import ipywidgets as widgets
from copy import deepcopy
from tqdm import tqdm
import imageio
from IPython import display
import plotly.graph_objects as go
import itertools
import dateparser
import gc
import math
from tools import dbtools

warnings.filterwarnings("ignore")

pd.set_option('display.max_rows',500)
pd.set_option('display.max_columns',500)
pd.set_option('display.width',1000)

02,行情获取和可视化

a,时间交易参数配置

1
2
3
4
5
6
7
8
9
10
11
12
13
# Enter your parameters here
seed = 42
symbol = '002594.XSHE'
metric = 'total_return'

start_date = datetime(2020, 1, 1, tzinfo=pytz.utc) # time period for analysis, must be timezone-aware
end_date = datetime(2023,1,1, tzinfo=pytz.utc)
time_buffer = timedelta(days=100) # buffer before to pre-calculate SMA/EMA, best to set to max window
freq = '1D'

vbt.settings.portfolio['init_cash'] = 10000. # 100$
vbt.settings.portfolio['fees'] = 0.0025 # 0.25%
vbt.settings.portfolio['slippage'] = 0.0025 # 0.25%

b,获取行情和行情mask

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Download data with time buffer
cols = ['Open', 'High', 'Low', 'Close', 'Volume']
# ohlcv_wbuf = vbt.YFData.download(symbol, start=start_date-time_buffer, end=end_date).get(cols)

ohlcv_wbuf=dbtools.MySQLData.download(symbol).get() # 自带工具类查询
assert(~ohlcv_wbuf.empty)
ohlcv_wbuf = ohlcv_wbuf.astype(np.float64)

print("origin ohlcv_wbuf size:",ohlcv_wbuf.shape)
print(ohlcv_wbuf.columns)


# Create a copy of data without time buffer
wobuf_mask = (ohlcv_wbuf.index >= start_date) & (ohlcv_wbuf.index <= end_date) # mask without buffer

ohlcv = ohlcv_wbuf.loc[wobuf_mask, :]

print("wobuf_mask ohlcv size:",ohlcv.shape)

# Plot the OHLC data
ohlcv.vbt.ohlcv.plot().show_svg() # 绘制蜡烛图
# remove show_svg() to display interactive chart!
origin ohlcv_wbuf size: (978, 5)
Index(['Open', 'High', 'Low', 'Close', 'Volume'], dtype='object')
wobuf_mask ohlcv size: (728, 5)

svg

03,指标计算和可视化

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
# fig.show_svg()
fast_window = 35
slow_window = 60

# Pre-calculate running windows on data with time buffer
fast_ma = vbt.MA.run(ohlcv_wbuf['Close'], fast_window)
slow_ma = vbt.MA.run(ohlcv_wbuf['Close'], slow_window)

print(fast_ma.ma.shape)
print(slow_ma.ma.shape)

# Remove time buffer
fast_ma = fast_ma[wobuf_mask]
slow_ma = slow_ma[wobuf_mask]

# there should be no nans after removing time buffer
assert(~fast_ma.ma.isnull().any())
assert(~slow_ma.ma.isnull().any())

print(fast_ma.ma.shape)
print(slow_ma.ma.shape)


fig = ohlcv['Open'].vbt.plot(trace_kwargs=dict(name='Price'))
fig = fast_ma.ma.vbt.plot(trace_kwargs=dict(name='Fast MA'), fig=fig)
fig = slow_ma.ma.vbt.plot(trace_kwargs=dict(name='Slow MA'), fig=fig)
fig.show_svg()

(978,)
(978,)
(728,)
(728,)

svg

04,信号计算,可视化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 信号计算
dmac_entries = fast_ma.ma_crossed_above(slow_ma)
dmac_exits = fast_ma.ma_crossed_below(slow_ma)

# 行情-指标-信号可视化
fig = ohlcv['Close'].vbt.plot(trace_kwargs=dict(name='Price'))
fig = fast_ma.ma.vbt.plot(trace_kwargs=dict(name='Fast MA'), fig=fig)
fig = slow_ma.ma.vbt.plot(trace_kwargs=dict(name='Slow MA'), fig=fig)
fig = dmac_entries.vbt.signals.plot_as_entry_markers(ohlcv['Close'], fig=fig)
fig = dmac_exits.vbt.signals.plot_as_exit_markers(ohlcv['Close'], fig=fig)
fig.show_svg()

# (单独)信号可视化
fig = dmac_entries.vbt.signals.plot(trace_kwargs=dict(name='Entries'))
dmac_exits.vbt.signals.plot(trace_kwargs=dict(name='Exits'), fig=fig).show_svg()

# 信号的统计信息
dmac_entries.vbt.signals.stats(settings=dict(other=dmac_exits))

svg

svg

Start                       2020-01-02 00:00:00+00:00
End                         2022-12-30 00:00:00+00:00
Period                                            728
Total                                               6
Rate [%]                                     0.824176
Total Overlapping                                   0
Overlapping Rate [%]                              0.0
First Index                 2020-01-08 00:00:00+00:00
Last Index                  2022-12-16 00:00:00+00:00
Norm Avg Index [-1, 1]                      -0.002751
Distance -> Other: Min                            7.0
Distance -> Other: Max                          200.0
Distance -> Other: Mean                     76.333333
Distance -> Other: Std                      66.503133
Total Partitions                                    6
Partition Rate [%]                              100.0
Partition Length: Min                             1.0
Partition Length: Max                             1.0
Partition Length: Mean                            1.0
Partition Length: Std                             0.0
Partition Distance: Min                          90.0
Partition Distance: Max                         252.0
Partition Distance: Mean                        142.6
Partition Distance: Std                     65.305436
dtype: object

05,交易统计

a,基准比对

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dmac_pf = vbt.Portfolio.from_signals(ohlcv['Close'], dmac_entries, dmac_exits)
# Print stats
print(dmac_pf.stats())

# Now build portfolio for a "Hold" strategy
# Here we buy once at the beginning and sell at the end
hold_entries = pd.Series.vbt.signals.empty_like(dmac_entries)
hold_entries.iloc[0] = True
hold_exits = pd.Series.vbt.signals.empty_like(hold_entries)
hold_exits.iloc[-1] = True
hold_pf = vbt.Portfolio.from_signals(ohlcv['Close'], hold_entries, hold_exits)

# Equity
fig = dmac_pf.value().vbt.plot(trace_kwargs=dict(name='Value (DMAC)'))
hold_pf.value().vbt.plot(trace_kwargs=dict(name='Value (Hold)'), fig=fig).show_svg()
Start                         2020-01-02 00:00:00+00:00
End                           2022-12-30 00:00:00+00:00
Period                                              728
Start Value                                     10000.0
End Value                                  56343.449364
Total Return [%]                             463.434494
Benchmark Return [%]                         433.464812
Max Gross Exposure [%]                            100.0
Total Fees Paid                             1154.406013
Max Drawdown [%]                              37.462162
Max Drawdown Duration                             319.0
Total Trades                                          6
Total Closed Trades                                   6
Total Open Trades                                     0
Open Trade PnL                                      0.0
Win Rate [%]                                  66.666667
Best Trade [%]                               192.432267
Worst Trade [%]                              -14.196623
Avg Winning Trade [%]                         72.994385
Avg Losing Trade [%]                          -9.136247
Avg Winning Trade Duration                        104.0
Avg Losing Trade Duration                          21.0
Profit Factor                                   5.95588
Expectancy                                  7723.908227
dtype: object

svg

b,交易详情和可视化

1
2
3
# Plot trades
print(dmac_pf.trades.records.head(5))
dmac_pf.trades.plot().show_svg()
   id  col        size  entry_idx  entry_price  entry_fees  exit_idx  exit_price   exit_fees           pnl    return  direction  status  parent_id
0   0    0  210.452345          4    47.398200   24.937656        66   57.775200   30.397316   2128.529014  0.213385          0       1          0
1   1    0  210.612793         94    57.443250   30.245708       294  168.547575   88.745689  23281.000774  1.924323          0       1          1
2   2    0  174.421504        346   202.505000   88.303067       430  282.621675  123.238244  13762.529659  0.389639          0       1          2
3   3    0  157.697151        448   311.035650  122.623590       483  268.327500  105.786206  -6963.363374 -0.141966          0       1          3
4   4    0  179.995892        566   233.913325  105.258594       636  327.110175  147.196219  16522.595293  0.392429          0       1          4

svg