上篇已经介绍了data的获取,此篇介绍ma5与ma10的双均线策略具体实现。双均线策略是一个趋势策略,基本思路是金叉买入,死叉卖出,也就是当ma5向上穿过ma10时,则买入,向下穿过ma10时,则卖出。

主要实现在Strategy类中,输入的变量格式如下:code_list = ['002415', '002416', '000333'],init_cash = 100000,starttime = '2014-01-01',endtime = '2017-11-30',其他几个重要成员变量如下:cash为还剩余的现金;capital_market_value为持仓的市值,按每天的收盘价计算;limit_cash为每只股票分得的仓位,双均线策略中,codelist中的股票平分持仓;position_list为持仓的情况,类型为dict,股票的code为key,持仓的数量为value;data_range为一个回测的日期list,pd.period_range的freq参数选择为B,即工作日;benchmark赋值为sh,即上证指数,以便比对策略结果。

#coding=utf-8
from trade import Trade
from data_repository import DataRepository
import tushare as ts
import pandas as pd
import numpy as np
import mathclass Strategy(object):def __init__(self, code_list, init_cash, start_time, end_time):self.start_time = start_timeself.end_time = end_timeself.data_repository = DataRepository.get_instance(code_list, self.start_time, self.end_time)self.code_list = code_listself.benchmark_code = 'sh'self.init_cash = init_cashself.cash = init_cashself.limited_cash = init_cash/len(code_list)self.position_list = {}for code in self.code_list:self.position_list[code] = 0#存储trade对象self.trade = Trade()d = list(pd.period_range(start=start_time, end=end_time, freq='B'))self.date_range = list(map(str, d))self.res_df = pd.DataFrame()self.res_df['date'] = self.date_rangeself.capital_market_value = []

实际的回测定义在run_simulation函数中,主循环框架为按天循环,通过每天的开盘价判断是否买入或者卖出( 先判断卖出信号,再判断买入信号,具体判断在后面介绍),如果卖出成功,那么将卖出的所得加入到cash变量,对应的position变量调整为0(这个策略为初级策略,都是在每只股票的额度内全买全卖,后续策略会加入仓位控制),并将操作记录下到trade变量中。买入的操作也是类似的。每天买卖判断完成后,再按收盘价计算下持仓的市值,记录到capital_market_value中,以便统计每天的涨跌,计算sharp比率等统计指标。

所有天数回测结束后,将结果记录到res_df中,该变量为pandas类型,以便分析结果。res_df中数据有每天capital_market_value,每天的涨跌幅,每天对应的benchmark的值(因为回测的date_range已经剔除了周末,节假日等情况会存在停市,故capital_market_value与benchmark的值均使用之前第一个值填充),benchmark采用先bfill,然后还可能存在最开头的值是空的情况,在ffill填充,而capital_market_value则是使用df[df['date'] <= date].tail(1)['close']获得。

    def run_simulation(self):#按天循环for date in self.date_range:for code in self.code_list:sell_signal, sell_open_price = self.get_sell_signal(code, date)direction = -1if sell_signal == 1:amount = self.get_sell_amount(code)if amount > 0:commission = self.cal_cost_function(sell_open_price, amount)#更改现金self.cash += sell_open_price*amountself.cash -= commission#更改持仓self.position_list[code] -= amount#加入trade记录self.trade.add_trade(code, sell_open_price, amount, date, direction, commission)for code in self.code_list:buy_signal, buy_open_price = self.get_buy_signal(code, date)direction = 1if buy_signal == 1:amount = self.get_buy_amount(code, buy_open_price)if amount > 0:commission = self.cal_cost_function(buy_open_price, amount)#更改现金self.cash -= buy_open_price*amountself.cash -= commission#更改持仓self.position_list[code] += amount#加入trade记录self.trade.add_trade(code, buy_open_price, amount, date, direction, commission)#计算每天的市值self.capital_market_value.append(self.get_market_value(date))#所有天循环结束后,加入到res_dfself.res_df['capital_market_value'] = pd.Series(self.capital_market_value)self.res_df['profolio_daily_return'] = round((self.res_df['capital_market_value']/\self.res_df['capital_market_value'].shift(1)-1),4)self.res_df['benchmark'] = self.get_benchmark_index()self.res_df['benchmark'].fillna(method='bfill', inplace=True)self.res_df['benchmark'].fillna(method='ffill', inplace=True)self.res_df.to_csv('./datares.csv')

benchmark与captial_market_value的取得具体如下。

    def get_benchmark_index(self):
df = ts.get_k_data(self.benchmark_code, start=self.start_time, end=self.end_time)
benchmark_list = []
for date in self.date_range:
if df[df['date'] == date].empty:
benchmark_list.append(np.nan)
else:
benchmark_list.append(float(df[df['date'] == date]['close']))
return benchmark_list
#得到某天的持仓股票的市值,加上cash,一并返回
def get_market_value(self, date):
market_value = 0
for code in self.position_list:
df = self.data_repository.get_onecode_df(code)
if self.position_list[code] != 0:
close_price = df[df['date'] <= date].tail(1)['close']
market_value += self.position_list[code]*float(close_price)
return round(market_value+self.cash, 2)

最重要的判断买入卖出信号如下。有个小地方需要注意下,给定一个date日期,df = df[df['date'] <= date].tail(3),获取了三天的价格,即今天的价格,昨天的价格,前天的价格,通过前天与昨天的均线价格去判断买入卖出。这是因为每天的均线价格是收盘价的平均(包含当天),策略的思路是每天通过开盘价买入或者卖出,但是当天的均线价格需要等收盘才能得到,也就是当买入或者卖出时候,只能使用昨天与前天的均线价格,否则就使用了未来函数。

    def get_sell_signal(self, code, date):
df = self.data_repository.get_onecode_df(code)
sell_signal = 0
sell_open_price = 0
if df[df['date'] == date].empty:
return sell_signal, sell_open_price
df = df[df['date'] <= date].tail(3)
if len(df) == 3 and df.iloc[0]['ma5'] > df.iloc[0]['ma10'] and df.iloc[1]['ma5'] < df.iloc[1]['ma10']:
sell_signal = 1
sell_open_price = df.iloc[1]['open']
return sell_signal, sell_open_price
#以后还要加入判断止盈的方法
def get_buy_signal(self, code, date):
df = self.data_repository.get_onecode_df(code)
buy_signal = 0
buy_open_price = 0
if df[df['date'] == date].empty:
return buy_signal, buy_open_price
df = df[df['date'] <= date].tail(3)
if len(df) == 3 and df.iloc[0]['ma5'] < df.iloc[0]['ma10'] and df.iloc[1]['ma5'] > df.iloc[1]['ma10']:
buy_signal = 1
buy_open_price = df.iloc[1]['open']
return buy_signal, buy_open_pric

剩下的几个就比较简单了,判断持仓数量,计算交易手续费。

    def get_sell_amount(self, code):
return self.position_list[code]
def get_buy_amount(self, code, price):
if self.position_list[code] == 0:
amount = math.floor(self.limited_cash/(price*100))*100
return amount
else:
return 0
def cal_cost_function(self, price, amount):
commission = price*amount*0.0003
#最低5元手续费
if commission > 5:
return commission
else:
return 5

量化双均线策略:(二)判断买入卖出信号相关推荐

  1. python量化 双均线策略(金叉死叉)

    #小策略,策略逻辑是在金叉时候买进,死叉时候卖出,所谓金叉死叉是两条均线的交叉,当短期均线上穿长期均线为金叉,反之为死叉 #下面是策略代码及结构 # 导入函数库 from jqdata import ...

  2. python双均线策略,当五日均线位于十日均线上方则买入,反之卖出。(聚宽量化平台使用)

    ''' ** python双均线策略,当五日均线位于十日均线上方则买入,反之卖出.(聚宽量化平台使用) ** ''' 初始化函数,设定要操作的股票.基准等等 def initialize(contex ...

  3. 开源量化框架Catalyst中文教程(3)——双均线策略

    GitHub:https://github.com/enigmampc/catalyst 官方文档:https://enigma.co/catalyst/index.html 参考视频:网易云课堂&l ...

  4. 双均线策略(期货)——Python量化

    双均线策略 目录 双均线策略 1. 原理 均线的"前世今生" 均线理论为什么有效? 均线理论的缺陷 均线理论的改进 2. 策略逻辑 3. 策略代码 4. 回测结果与稳健性分析 1. ...

  5. 量化交易入门----双均线策略

    本文采用了聚宽平台接口进行量化策略设置: 一.效果图 双均线策略:双均线策略,当五日均线位于十日均线上方则买入,反之卖出. 二.证券知识: 策略收益(Total Returns) 最容易理解的一个概念 ...

  6. Python量化交易02——双均线策略(移动平均线)

    参考书目:深入浅出Python量化交易实战 本次带来最经典的交易策略,双均线策略的构建和其回测方法. 双均线一般采用5天均值和10天均值,如果5日均线上穿突破了10日均线,说明股价在最近的涨势很猛,买 ...

  7. Python量化交易实战-38使用开源项目回测双均线策略

    B站配套视频教程观看 使用PyAlgoTrade回测双均线策略 双均线策略:长短周期均线,通过金叉,死叉的方式买入卖出股票,获取收益的策略. 回顾上节课代码的部分,上节课完成了可视化代码的部分, 主要 ...

  8. 量化投资01----股票_贵州茅台600519_双均线策略回测

    贵州茅台 SH600519 双均线策略回测(5日均线.30日均线,金叉买入,死叉卖出) 交易从 2010年开始,2019年底结束. 10万初始资金 尽量买入(按手),尽量卖出,均以开盘价 未计算手续费 ...

  9. Python量化交易策略--双均线策略及代码

    双均线策略是比较经典的策略,股票的价格均线是投资参考的重要指标.均线有快线和慢线之分,当快线向上穿过慢线则是金叉,一般执行买入操作,当快线向下穿过慢线时则形成死叉,一般执行卖出操作.基于这个基本思路, ...

最新文章

  1. 弱网测试用什么农_弱网测试(一)
  2. java split 逗号_咦,Java拆分个字符串都这么讲究
  3. 【数字信号处理】傅里叶变换性质 ( 序列傅里叶变换共轭对称性质 | 实序列的幅频特性偶对称 | 实序列相频特性奇对称 | 示例说明 )
  4. why I need register Apache CXF as servlet
  5. 奥托尼克斯接近开关型号_萨科微SLKOR的MOS 场效应管应用范围和型号
  6. 泊松分布的分布函数_《可靠性设计》——常用的概率分布
  7. Kava将于下午2时重新启动Kava Chain
  8. 正定矩阵(positive definite matrix)
  9. 美赛、国赛数学建模优秀范文 O奖、国一
  10. 四川300家旅游企业上“云端”转型信息化
  11. Matlab实现分组检测
  12. Flutter InkWell Ink组件
  13. 基于ArcGIS JS API实现的两种距离和面积测量方式
  14. 专门为某种用途设计的计算机称为,专门为某种用途而设计的计算机,称为( )计算机。...
  15. 苹果手机如何换行打字_苹果手机备忘录如何导入到新手机?备忘录误删如何恢复?...
  16. JSVM实现可伸缩视频编码(SVC)
  17. 基于PHP的学生成绩管理系统
  18. 211计算机考研难度小,考研难度小比较好考的211名校,一共有17所,报录比也不高~...
  19. 苹果CMS V10仿韩剧TV主题模板源码 | 苹果CMS主题
  20. 电商仓储云仓储到底是什么?

热门文章

  1. 敏捷开发方法之Scrum
  2. matlab电磁场散度与旋度,梯度、散度和旋度大揭秘
  3. 2017年校园招聘ios面试题
  4. insert into select语句与select into from语句
  5. opencv图像拼接【二】
  6. 科技公司钟爱的50款开源工具--转载
  7. 微信小程序-收货地址 省市区联动 组件
  8. 华为移动wifi显示无服务器,华为移动WIFI怎么使用,随时WIFI是路由器吗?
  9. 中国网文出海:巴铁女孩写作为生 小说阅读量过千万
  10. 向量的几何意义及编程应用(1)