双均线策略示例

策略简介

均线,即移动平均线(Moving Average),是指最近n天收市价格的算术平均线,在计算中,始终采用最近n天的价格数据,随着新的交易日的更迭,逐日向前推移。均线理论是当今应用最普遍的技术指标之一,它帮助交易者确认现有趋势、判断将出现的趋势、发现过度延生即将反转的趋势。我们这里探讨的双均线策略即是对均线理论的一项简单应用。

所谓双均线,是指考察短期、长期两条均线,例如5天和10天、或者20天和40天的移动平均线,当两条均线相交时,若短期均线向上穿过长期均线,即视为买入信号;反之若短期均线向下穿过长期均线,则视为卖出信号。其内在的经济学逻辑在于,当短期均线上穿并高过长期均线时,意味着该股票在近期表现好于之前,显示上涨趋势,因此选择买入。可以看出,我们这里使用的双均线策略是一个简单的趋势跟随型策略。

双均线策略逻辑清晰,易于实现,且在市场的检测中确有其效果,下面我们将使用云宽客平台实现该策略并对其结果略作检视。

收益曲线

收益归因

关于回测平台、历史数据,可以在这里下载:http://www.链接失效或指向广告已经被屏蔽.com/# /introduce
这个平台的数据都是经过清洗的,而且策略不会外露,有保密系统,还是比较安全的。
想学习更多量化策略,也可以来这里看看:http://www.链接失效或指向广告已经被屏蔽.com/# /lzClass
想学习更多关于量化投资策略相关内容的,可以关注微信:量化投资与金融科技(微信号:QuantumFintech)
微信二维码:

小结

从回测结果看,这一策略的表现还是不错的。在2006.1.1-2017.1.1这个时间段实现了34.2%的年化收益率(复合年化收益率15.5%)。当然这里只是一个简单的单股票择时策略,波动率和最大回撤都不小,收益并不稳定。

双均线交叉只是双均线策略的其中一种应用,除此之外,我们还可以考虑更严格的双移动均线策略:把两条均线的中间看作某种中性区。那么,仅当收市价格同时向上越过了两条平均线之后,才构成买入信号。然后,如果价格再跌回中性区,则上述信号被取消。同样,仅当收市价格同时向下穿越了两条平均线之后,才构成卖出信号。然后,如果价格在涨回两条平均线之间的中性区,我们就平仓了结上述空头头寸。只要价格维持于中性区内,我们就袖手静观。依此方法设计的系统,也有一些其他系统所不及的长处。

既然两条移动平均线似乎比一条更好,那么,如果把三条平均线相组合,是否能胜过两条平均线的组合呢?基于这样的设想,就有了三重交叉方法。最常用的三重交叉法系统,要数4-9-18天移动平均线的组合。在商品行业,5天、10天和20天移动平均线是使用得最广泛的几种。4-9-18天系统其实只是它的一种变化。在使用中,当短期的移动平均线从下往上穿过中期和长期移动平均线时,就构成了买入信号,而中期移动平均线也上穿长期移动平均线时买入信号得到确认;反之,当短期的移动平均线从上往下穿过中期和长期移动平均线时,就构成了卖出信号,而中期移动平均线也下穿长期移动平均线时卖出信号得到确认。

除了对双均线系统的分析研判,我们还可以对均线本身加以操作,例如我们可以选择使用更复杂的均线计算方式,如加权平均;或是结合其他选股类策略,对多股票进行操作,都有可能创造出更加稳健而有效的策略。

Code:

= LONG_PERIOD:
temp=0
for i in range(LONG_PERIOD):
temp+=priceList[stock][-i-1].close
temp=temp/LONG_PERIOD
longMA.append(temp)
else:
return

for stock in TRADE_LIST: # 计算短期均线
if len(priceList[stock]) >= SHORT_PERIOD:
temp=0
for i in range(SHORT_PERIOD):
temp+=priceList[stock][-i-1].close
temp=temp/SHORT_PERIOD
shortMA.append(temp)
else:
return

buyList=[]
sellList=[]

flag=sdk.getGlobal("flag") # 从全局变量获取现在均线状态
for i,stock in enumerate(TRADE_LIST): # 判断是否买卖
if shortMA[i]>longMA[i] and flag==-1: # 短期均线上穿长期均线,买入
buyList.append(stock)
if shortMA[i]longMA[i] else -1 # 更新均线状态

sdk.setGlobal("flag",flag)

if sellList: # 卖出应售股票
for stock in sellList:
pos=sdk.getPositions(code=stock) # 检查股票持有情况
if pos:
quote=sdk.getQuote(stock)
sdk.makeOrder(stock,quote.current,pos[0].optPosition,-1) # 卖出所有可交易持仓
sdk.sdklog([stock,quote.current,pos[0].optPosition,-1],'sell') # 记入日志

if buyList: # 买入应购股票
budget=sdk.getAccountInfo().availableCash/len(buyList) # 将可用资金平均分配至每一支要买入的股票
for stock in buyList:
quote = sdk.getQuote(stock)
volume = (int(budget /(quote.current(1+config['feeRate'])))//100)100 # 计算交易量,取100整数倍
sdk.makeOrder(stock, quote.current, volume, 1) # 买入
sdk.sdklog([stock, quote.current, volume, 1], 'buy') # 记入日志

def main():

将策略函数加入

config['initial'] = initial
config['strategy'] = strategy
config['preparePerDay'] = initPerDay

启动SDK

SDKCoreEngine(**config).run()

if name == "main":
main()
">

-- coding:utf-8 --

from CloudQuant import SDKCoreEngine # 导入量子金服SDK
from CloudQuant import AssetType
from CloudQuant import QuoteCycle
from CloudQuant import OrderType
import numpy as np # 使用numpy
np.seterr(invalid='ignore')

config = {
'username': 'username', # 用户名
'password': 'password', # 密码
'rootpath': 'c:/cStrategy', # 客户端所在路径
'assetType': AssetType.Stock, # 交易资产类型
'initCapitalStock': 100000000, # 初始资金
'startDate': 20060101, # 交易开始日期
'endDate': 20170101, # 交易结束日期
'cycle': QuoteCycle.D, # 回放粒度为日线
'feeRate': 0.001, # 设定费率
'feeLimit': 5, # 设定最低费用为5
'strategyName': 'dualMA', # 策略名

-- coding:utf-8 --

from CloudQuant import SDKCoreEngine # 导入量子金服SDK
from CloudQuant import AssetType
from CloudQuant import QuoteCycle
from CloudQuant import OrderType
import numpy as np # 使用numpy
np.seterr(invalid='ignore')

config = {
'username': 'username', # 用户名
'password': 'password', # 密码
'rootpath': 'c:/cStrategy', # 客户端所在路径
'assetType': AssetType.Stock, # 交易资产类型
'initCapitalStock': 100000000, # 初始资金
'startDate': 20060101, # 交易开始日期
'endDate': 20170101, # 交易结束日期
'cycle': QuoteCycle.D, # 回放粒度为日线
'feeRate': 0.001, # 设定费率
'feeLimit': 5, # 设定最低费用为5
'strategyName': 'dualMA', # 策略名
"logfile": "dualMA.log", # 设定日志文件名
'dealByVolume': False # 撮合是否考虑实际交易量
}

TRADE_LIST=['000001'] # 设定要交易的股票,可以结合选股策略进行选择,这里用平安银行做示范
LONG_PERIOD=40 # 设定长期均线时长
SHORT_PERIOD=20 # 设定短期均线时长

def initial(sdk): # 整个回测前需要的操作
flag=[0]*len(TRADE_LIST) # 标记现在均线的状态
sdk.setGlobal("flag",flag) # 将flag设为全局变量

def initPerDay(sdk): # 每天回测前需要的操作
pass

def strategy(sdk): # 交易策略
priceList=sdk.getLatest(TRADE_LIST,count=LONG_PERIOD,timefreq="D") # 获取股票池中股票历史价格
longMA=[]
shortMA=[]
for stock in TRADE_LIST: # 计算长期均线
if len(priceList[stock]) >= LONG_PERIOD:
temp=0
for i in range(LONG_PERIOD):
temp+=priceList[stock][-i-1].close
temp=temp/LONG_PERIOD
longMA.append(temp)
else:
return

for stock in TRADE_LIST: # 计算短期均线
if len(priceList[stock]) >= SHORT_PERIOD:
temp=0
for i in range(SHORT_PERIOD):
temp+=priceList[stock][-i-1].close
temp=temp/SHORT_PERIOD
shortMA.append(temp)
else:
return

buyList=[]
sellList=[]

flag=sdk.getGlobal("flag") # 从全局变量获取现在均线状态
for i,stock in enumerate(TRADE_LIST): # 判断是否买卖
if shortMA[i]>longMA[i] and flag==-1: # 短期均线上穿长期均线,买入
buyList.append(stock)
if shortMA[i]longMA[i] else -1 # 更新均线状态

sdk.setGlobal("flag",flag)

if sellList: # 卖出应售股票
for stock in sellList:
pos=sdk.getPositions(code=stock) # 检查股票持有情况
if pos:
quote=sdk.getQuote(stock)
sdk.makeOrder(stock,quote.current,pos[0].optPosition,-1) # 卖出所有可交易持仓
sdk.sdklog([stock,quote.current,pos[0].optPosition,-1],'sell') # 记入日志

if buyList: # 买入应购股票
budget=sdk.getAccountInfo().availableCash/len(buyList) # 将可用资金平均分配至每一支要买入的股票
for stock in buyList:
quote = sdk.getQuote(stock)
volume = (int(budget /(quote.current(1+config['feeRate'])))//100)100 # 计算交易量,取100整数倍
sdk.makeOrder(stock, quote.current, volume, 1) # 买入
sdk.sdklog([stock, quote.current, volume, 1], 'buy') # 记入日志

def main():

将策略函数加入

config['initial'] = initial
config['strategy'] = strategy
config['preparePerDay'] = initPerDay

启动SDK

SDKCoreEngine(**config).run()

if name == "main":
main()

-- coding:utf-8 --

from CloudQuant import SDKCoreEngine # 导入量子金服SDK
from CloudQuant import AssetType
from CloudQuant import QuoteCycle
from CloudQuant import OrderType
import numpy as np # 使用numpy
np.seterr(invalid='ignore')

config = {
'username': 'username', # 用户名
'password': 'password', # 密码
'rootpath': 'c:/cStrategy', # 客户端所在路径
'assetType': AssetType.Stock, # 交易资产类型
'initCapitalStock': 100000000, # 初始资金
'startDate': 20060101, # 交易开始日期
'endDate': 20170101, # 交易结束日期
'cycle': QuoteCycle.D, # 回放粒度为日线
'feeRate': 0.001, # 设定费率
'feeLimit': 5, # 设定最低费用为5
'strategyName': 'dualMA', # 策略名

关键字:交易策略, 理论基础, 程序化交易, 金融工程

原文发布于宽客论坛,点击阅读原文

风险提示及免责条款

市场有风险,投资需谨慎。本文不构成个人投资建议,也未考虑到个别用户特殊的投资目标、财务状况或需要。用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击下方“内容举报”进行投诉反馈!
立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部