Home >  > Python事件化回测双均线

Python事件化回测双均线

0

事件回测的最大好处是基本上可以避免未来函数的出现。

代码如下:

# -*- coding: utf-8 -*-

from __future__ import division

# %matplotlib inline

import tushare as ts
import pandas as pd
import numpy as np

data = ts.get_hist_data("510050",start="2017-01-01",end="2017-09-08")
data = data.sort_values("date")
df = pd.DataFrame()
df['close'] = data['close']
df['change'] = df['close']- df['close'].shift(1)
df = df.dropna()  #将带有Na的去掉,返回一个新的对像

close5_array = np.zeros(5)    #缓存过去5天收盘价
close20_array = np.zeros(20)
last_signal = 0              #最近交易信号,初始化为0。因为双均线策略要使用前一天的收盘价,就需要将信号缓存下来,第2天计算仓位的时候使用
last_pos = 0                 #最近的持仓,初始化为0

dr_list = []   #每日盈亏结果列表

class DailyResult:
    """每日盈亏结果"""
    def _init__(self):
        self.date = ''
        self.close = 0
        self.change = 0
        self.pos = 0
        self.last_pos = 0     #昨日持仓

        self.pnl = 0
        self.fee = 0
        self.net_pnl = 0

    def calculate(self,date,close,change, last_signal, last_pos):
        """计算每日盈亏"""
        #赋值原始数据
        self.date = date
        self.close  = close
        self.change = change
        self.pos = last_signal
        self.last_pos = last_pos

        #计算结果数据
        self.pnl = self.change * self.pos
        self.fee = abs(self.pos-self.last_pos) * 1.5/10000
        self.net_pnl = self.pnl - self.fee

#运行回溯
#iterrows生成迭代器,enumerate在迭代过程中返回当前的变量的计数情况。df刚好有date, close, change三列。叠代过程中会以tuple的形式返回每一行,其中的第一个元素是日期,第二个元素是数值段。
for i, row in enumerate(df.iterrows()):
    date = row[0]
    close =row[1]['close']
    change = row[1]['change']

    #将数组中的数据平移一格
    close5_array[0:4] = close5_array[1:5]
    close20_array[0:19] = close20_array[1:20]

    #将新数据添加到数组末尾
    close5_array[-1] = close
    close20_array[-1] = close

    #如果尚未有20个数据点的缓存数量,则不执行后续逻辑
    if i < 20:
        continue

    #计算当日持仓盈亏
    dr = DailyResult()
    dr.calculate(date, close, change, last_signal,last_pos)

    dr_list.append(dr)

    #记录当日持仓
    last_pos = dr.pos

    #计算信号数据
    ma5 = close5_array.mean()
    ma20 = close20_array.mean()
    if ma5 > ma20:
        last_signal = 10000
    else:
        last_signal = -10000

#显示回测结果
result_df = pd.DataFrame()
result_df['net_pnl'] = [dr.net_pnl for dr in dr_list]    #将dailyresult列表中的数据转换为pandas的dataframe
result_df.index = [dr.date for dr in dr_list]              #添加日期索引

result_df['cum_pnl'] = result_df['net_pnl'].cumsum()    #累积求和
result_df['cum_pnl'].plot()

在jupyter运行结果如下:

暧昧帖

本文暂无标签

发表评论

*

*