# encoding: UTF-8
"""
这里的Demo是一个最简单的策略实现,并未考虑太多实盘中的交易细节,如:
1. 委托价格超出涨跌停价导致的委托失败
2. 委托未成交,需要撤单后重新委托
3. 断网后恢复交易状态
"""
from ctaBase import*
from ctaTemplate import CtaTemplate
class EmaDemoStrategy(CtaTemplate)
"""双指数均线策略"""
className='EmaDemoStrategy'
authur=u'miaomiaomiao'
#策略参数
fastK=0.9 #快速EMA参数
slowK=0.1 #慢速EMA参数
initDays=10 #初始化数据所用的天数
#策略变量
bar=None
barMinute=EMPTY_STRING
fastMa=[] #快速EMA均线数组
fastMa0=EMPTY_FLOAT #当前最新的快速EMA
fastMa1=EMPTY_FLOAT #上一根的快速EMA
slowMa=[]
slowMa0=EMPTY_FLOAT
slowMa1=EMPTY_FLOAT
#参数列表,保存了参数的名称
paramList=['name',
'className',
'author',
'vtSymbol',
'fastK',
'slowK']
#交易列表,保存了变量的名称
varList=['inited',
'trading',
'pos',
'fastMa0',
'fastMa1',
'slowMa0',
'slowMa1']
def __init__(self, ctaEngine, setting):
"""Constructor"""
super(EmaDemoStrategy, self).__init__(ctaEngine, setting)
# 注意策略类中的可变对象属性(通常是list和dict等),在策略初始化时需要重新创建,
# 否则会出现多个策略实例之间数据共享的情况,有可能导致潜在的策略逻辑错误风险,
# 策略类中的这些可变对象属性可以选择不写,全都放在__init__下面,写主要是为了阅读
# 策略时方便(更多是个编程习惯的选择)
self.fastMa = []
self.slowMa = []
def onInit(self):
"""初始化策略"""
self.writeCtaLog(u'双EMA演示策略初始化')
initData=self.loadBar(self.initDays)
for bar in initData:
self.onBar(bar)
self.putEvent()
def onStart(self):
"""启动策略"""
self.writeCtaLog(u'双EMA演示策略启动')
self.putEvent()
def onStop(self):
"""停止策略"""
self.writeCtaLog(u'双EMA演示策略')
self.putEvent()
def onTick(self,tikc):
"""收到行情TICK推送"""
#计算K线
tickMinute=tick.datetime.minute
if tickMinute !=self.barMinute:
if self.bar:
self.onBar(self.bar)
bar=CteBarData()
bar.vtSymbol=tick.vtSymbol
bar.symbol=tick.symbol
bar.exchange=tick.exchange
bar.open=tick.lastPrice
bar.high=tick.lastPrice
bar.low=tick.lastPrice
bar.close=tick.lastPrice
bar.date=tick.date
bar.time=tick.time
bar.datetime=tick.datetime #K线的时间设为第一个Tick的时间
#实盘中用不到的数据可以选择不算,从而加快速度
#bar.volume=tick.volume
#bar.openInterest=tick.openInterest
self.bar=bar #这种写法为了减少一层访问,加快速度
self.barMinute=tickMinute #更新当前的分钟
else:
bar=self.bar #否则继续累加新的K线
#写法同样为了加快速度
bar.high=max(bar.high,tick.lastPrice)
bar.low=min(bar.low,tick.lastPrice)
bar.close=tick.lastPrice
def onBar(self,bar):
"""收到Bar推送"""
#计算快慢均线
if not self.fastMa0:
self.fastMa0=bar.close
self.fastMa.append(self.fastMa0)
else:
self.fastMa1=self.fastMa0
self.fastMa0=bar.close*self.fastK+self.fastMa0*(1-self.fastK)
self.fastMa.append(self.fastMa0)
#判断买卖
CrossOver=sell.fastMa0>self.Ma0 and self.fastMa1<self.slowMa1
CrossBelow=self.fastMa0<self.slowMa0 and self.fastMa1>self.slowMa1
#金叉和死叉的条件是互斥
#所有的委托均一K线收盘价委托
if crossOver:
#如果金叉是手头没有持仓,则直接做多
if self.pos==o:
self.buy(bar.close,1)
#如果有空头持仓,则先平空,再做多
elif self.pos<0:
self.cover(bar.close,1)
self.buy(bar.close,1)
#死叉和金叉相反
elfi crossBelow:
if self.pos==0:
self.short(bar.close,1)
elif self.pos>0:
self.sell(bar,close,1)
self.short(bar.close,1)
#发出状态更新事件
self.putEvent()
def onOrder(self,order):
"""收到委托变化推送"""
pass
def onTrade(self,trade):
"""收到成交推送"""
pass