"""导入常用模块"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import datetime
from jqdata import *
from environment import * # 导入大树工作室开发的回测模块
from jqlib.technical_analysis import *
"""公用函数"""
def get_dma(security, start_date=None, end_date=None, count=1, n1=10, n2=50, m=10):
price = get_price(security=security,
start_date=start_date,
end_date= end_date,
frequency='daily',
fields=None,
skip_paused=False,
count=count n2 m,
fq='pre')
ma1 = price['close'].rolling(n1).mean()
ma2 = price['close'].rolling(n2).mean()
DMA = ma1 - ma2
AMA = DMA.rolling(m).mean()
return DMA[-count:].values, AMA[-count:].values
def show_dma(DMA, AMA):
plt.figure(figsize=(16, 3))
plt.plot(DMA)
plt.plot(AMA)
plt.show()
平行线差(DMA)指标是利用两条不同期间的平均线,来判断当前买卖能量的大小和未来价格趋势。DMA指标是一种中短期指标。
trade_date = get_trade_days(end_date=datetime.datetime.now(), count=100)
DMA, AMA = get_dma('000300.XSHG', end_date=trade_date[-1], count=300)
show_dma(DMA, AMA)
DMA线向上交叉AMA线,买进;DMA线向下交叉AMA线,卖出。
"""初始化以下内容"""
context = Context() # 账户对象
order = Order(context) # 下单对象
trade = Trade(context, order) # 回测对象
context.start_date = '2005-05-01'
context.end_date = '2018-12-31'
context.universe = ['000300.XSHG']
context.base = '000300.XSHG'
"""策略主体"""
def handle(context, order):
stock = '000300.XSHG'
DMA, AMA = get_dma(stock, end_date=trade.context.current_dt, count=2)
close = get_price(security=stock,
end_date=context.current_dt,
frequency='daily',
fields=None,
skip_paused=False,
fq='pre',
count=5)['close'][-1]
if DMA[-2] < AMA[-2] and DMA[-1] > AMA[-1]:
if stock in context.position.keys():
return
else:
order.buy(stock, close, context.cash // close)
elif DMA[-2] > AMA[-2] and DMA[-1] < AMA[-1]:
if stock not in context.position.keys():
return
else:
order.sell(stock, close, context.position[stock]['count'])
"""执行策略"""
trade.trade(handle)
2019-02-23 17:49:39.306499,回测完毕,用时0:00:17.551996
上例中的金叉与死叉时间间隔只有一天,这个时间间隔可以是1~10天,因此可将这个时间间隔当作一个可被调节的参数,并回测最优的时间间隔。
date_long = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 这里只测这几个吧
trade_list = []
for long in date_long:
"""初始化以下内容"""
context = Context() # 账户对象
order = Order(context) # 下单对象
trade = Trade(context, order) # 回测对旬
context.start_date = '2005-05-01'
context.end_date = '2018-12-31'
context.universe = ['000300.XSHG']
context.base = '000300.XSHG'
"""策略主体"""
def handle(context, order):
stock = '000300.XSHG'
DMA, AMA = get_dma(stock, end_date=trade.context.current_dt, count=long 1)
close = get_price(security=stock,
end_date=context.current_dt,
frequency='daily',
fields=None,
skip_paused=False,
fq='pre',
count=long 1)['close'][-1]
if DMA[-1-long] < AMA[-2] and DMA[-1] > AMA[-1]:
if stock in context.position.keys():
return
else:
order.buy(stock, close, context.cash // close)
elif DMA[-1-long] > AMA[-2] and DMA[-1] < AMA[-1]:
if stock not in context.position.keys():
return
else:
order.sell(stock, close, context.position[stock]['count'])
"""执行策略"""
trade.trade(handle, False)
trade_list.append(trade)
# 展示
Trade.show_ratio_compare('date_long', date_long, trade_list, 3, 3)
Trade.show_result('date_long', date_long, trade_list)
2019-02-23 17:41:16.143275,回测完毕,用时0:00:17.396257
2019-02-23 17:41:33.206154,回测完毕,用时0:00:17.062726
2019-02-23 17:41:50.431428,回测完毕,用时0:00:17.225110
2019-02-23 17:42:07.762340,回测完毕,用时0:00:17.330767
2019-02-23 17:42:24.838906,回测完毕,用时0:00:17.076416
2019-02-23 17:42:42.313726,回测完毕,用时0:00:17.474663
2019-02-23 17:42:59.851819,回测完毕,用时0:00:17.537938
2019-02-23 17:43:16.871338,回测完毕,用时0:00:17.019358
2019-02-23 17:43:34.322078,回测完毕,用时0:00:17.450586
计算金叉死叉的时间间隔最优秀的是9,也就是10天之前。不过,整体回测效果并不好。看来单独使用这个指标,在金叉死叉的买卖方法上并不好使。
当发生背离时,即价格逐渐走低,而DMA逐渐走高时,买入;当价格逐渐走高,而DMA逐渐走低时,卖出。其中,判断背离需要有一个时间间隔,这里仍旧回测不同时间间隔下的效果。
date_long = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 这里只测这几个吧
trade_list = []
for long in date_long:
"""初始化以下内容"""
context = Context() # 账户对象
order = Order(context) # 下单对象
trade = Trade(context, order) # 回测对旬
context.start_date = '2005-05-01'
context.end_date = '2018-12-31'
context.universe = ['000300.XSHG']
context.base = '000300.XSHG'
"""策略主体"""
def handle(context, order):
stock = '000300.XSHG'
DMA, AMA = get_dma(stock, end_date=trade.context.current_dt, count=long 2)
close = get_price(security=stock,
end_date=context.current_dt,
frequency='daily',
fields=None,
skip_paused=False,
fq='pre',
count=long 2)['close']
close1 = close[-1-long]
close2 = close[-1]
DMA1 = DMA[-1-long]
DMA2 = DMA[-1]
# 产生买入的背离信号
if close2 < close1 and DMA2 > DMA1:
if stock in context.position.keys():
return
else:
order.buy(stock, close2, context.cash // close2)
elif close2 > close1 and DMA2 < DMA1:
if stock not in context.position.keys():
return
else:
order.sell(stock, close2, context.position[stock]['count'])
"""执行策略"""
trade.trade(handle, False)
trade_list.append(trade)
# 展示
Trade.show_ratio_compare('date_long', date_long, trade_list, 3, 3)
Trade.show_result('date_long', date_long, trade_list)
2019-02-23 18:34:52.960845,回测完毕,用时0:00:16.602134
2019-02-23 18:35:10.298780,回测完毕,用时0:00:17.337748
2019-02-23 18:35:27.256697,回测完毕,用时0:00:16.957756
2019-02-23 18:35:43.215573,回测完毕,用时0:00:15.958712
2019-02-23 18:36:00.272317,回测完毕,用时0:00:17.056580
2019-02-23 18:36:17.469745,回测完毕,用时0:00:17.197248
2019-02-23 18:36:34.328112,回测完毕,用时0:00:16.858203
2019-02-23 18:36:51.307217,回测完毕,用时0:00:16.978911
2019-02-23 18:37:08.102706,回测完毕,用时0:00:16.795313
时间间隔为4天的背离计算,得到的回测结果最优,但整体来说,效果并不是很好。看来,单独使用DMA,效果并不理想。也许,与其他指标结合使用,效果会更好。
这里只研究单一指标的择时效果,超出范围的不去涉猎,有兴趣的朋友,可以息行研究一下。
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程