使用tushare的数据用Python 写一个 使用Dynamic Time Warping作为算法的关于中证1000指数和上证50指数的配对交易策略,然后用backtrader平台回测,最后画出图形
时间: 2024-05-13 09:13:50 浏览: 64
基于python实现的模拟股票交易程序,可设定策略进行模拟交易
由于tushare的数据更新比较频繁,本次代码仅供参考,具体数据需要根据实际情况进行调整。
首先,需要导入需要使用的库:
```python
import tushare as ts
import numpy as np
import pandas as pd
from scipy.spatial.distance import euclidean
from fastdtw import fastdtw
import backtrader as bt
```
接下来,我们需要获取中证1000指数和上证50指数的历史数据,并计算它们的DTW距离:
```python
# 获取中证1000指数和上证50指数的历史数据
start_date = '2016-01-01'
end_date = '2021-12-31'
index_000905 = ts.get_k_data('000905', start_date, end_date, ktype='D', autype='qfq', index=True, retry_count=5)
index_000016 = ts.get_k_data('000016', start_date, end_date, ktype='D', autype='qfq', index=True, retry_count=5)
# 将数据按照日期排序,并设置日期为索引
index_000905 = index_000905.sort_values('date')
index_000905 = index_000905.set_index('date')
index_000016 = index_000016.sort_values('date')
index_000016 = index_000016.set_index('date')
# 计算两个指数的DTW距离
distance, path = fastdtw(index_000905['close'], index_000016['close'], dist=euclidean)
print('DTW距离为:', distance)
```
接下来,我们需要定义交易信号函数。在本例中,我们会设定一个阈值,当两个指数之间的DTW距离小于阈值时,视为出现配对交易信号。当出现交易信号时,我们会同时买入中证1000指数和卖出上证50指数,当两个指数的DTW距离回到正常水平时,即可以平仓。
```python
class DTWStrategy(bt.Strategy):
params = (
('min_distance', 500),
('max_distance', 1000),
('size', 100),
('printlog', False),
)
def __init__(self):
self.index_000905 = self.datas[0]
self.index_000016 = self.datas[1]
self.distance = None
self.distance_history = []
self.buy_price = None
self.sell_price = None
def log(self, txt, dt=None, doprint=False):
if self.params.printlog or doprint:
dt = dt or self.datas[0].datetime.date(0)
print('%s, %s' % (dt.isoformat(), txt))
def notify_data(self, data, status, *args, **kwargs):
if status == data.LIVE:
self.log('Data Live')
def next(self):
if len(self.distance_history) >= self.params.size:
self.distance_history.pop(0)
self.distance, _ = fastdtw(self.index_000905.close.get(size=self.params.size),
self.index_000016.close.get(size=self.params.size),
dist=euclidean)
self.distance_history.append(self.distance)
if len(self.distance_history) == self.params.size and \
self.distance < self.params.min_distance and \
self.buy_price is None:
self.log('Buy Signal: distance %.2f' % self.distance)
self.buy_price = self.index_000905.close[0]
self.sell_price = self.index_000016.close[0]
self.order_target_percent(self.index_000905, target=0.5)
self.order_target_percent(self.index_000016, target=-0.5)
elif self.buy_price is not None and self.distance > self.params.max_distance:
self.log('Sell Signal: distance %.2f' % self.distance)
self.order_target_percent(self.index_000905, target=0)
self.order_target_percent(self.index_000016, target=0)
self.sell_price = None
self.buy_price = None
self.log('Distance %.2f' % self.distance)
```
接下来,我们需要使用backtrader平台进行回测。为了方便,我们可以先将历史数据转换成backtrader所需要的格式:
```python
data_000905 = bt.feeds.PandasData(dataname=index_000905)
data_000016 = bt.feeds.PandasData(dataname=index_000016)
```
然后,我们可以创建backtrader的Cerebro对象,并将指数数据添加到Cerebro中:
```python
cerebro = bt.Cerebro()
cerebro.adddata(data_000905)
cerebro.adddata(data_000016)
```
接下来,我们可以将交易策略添加到Cerebro中:
```python
cerebro.addstrategy(DTWStrategy, min_distance=500, max_distance=1000, size=100)
```
最后,我们可以运行Cerebro并绘制回测结果图形:
```python
cerebro.run()
cerebro.plot()
```
绘制的图形中,可以看到交易信号的出现和平仓时机。根据回测结果,可以对交易策略进行优化和调整,以提高交易效果。
阅读全文