# encoding: UTF-8
"""
自动交易-买
"""
from __future__ import division
import talib
import math
"import win32api,win32con"
from iTraderPy.ctp_data_type import *
from iTraderPy.StrategyBase import *
from iTraderPy.mtConstant import *
from iTraderPy.exportObj import *
import datetime
########################################################################
class AutoTradeLong(StrategyBase):
""""""
name = u'自动交易-买' # 策略实例名称
# 变量列表。可将需要在管理界面显示的变量名加到此处(注意基类已在basevarList中定义显示部份变量,这些变量不需再定义)
varList = []
# 参数列表,可将需要在管理界面显示的参数名加到此处
paramList = []
#----------------------------------------------------------------------
" def __init__(self, ctaEngine, strategyid):"
"""Constructor"""
" super(AutoTradeLong, self).__init__(ctaEngine, strategyid)"
#继承修改基类变量,若不需修改,也可不继承
self.rtnAllTrade = False # 是否返回所有交易,若是,则不是本策略产生的交易也会被返回,否则,只返回本生策略提交的交易
self.autoGeneratorBar = False #不生成Bar
self.timerId = 1 # 定义timerid
self.clearBeginTime = "14:58:00"#清仓时间
self.clearEndTime = "15:00:00"
self.insInfo = None # 合约信息
self.stepTickNum = 4 # 止盈或加仓判断的价格Tick数量
self.tradeNum = 1 #每次交易的数量
self.tradeDirect = 0 #交易的方向,0:买多,卖空
self.symbol = "MA909" # 交易的合约
self.symbolList = [self.symbol]
self._InitData() #初始化数据
# ----------------------------------------------------------------------
def _InitData(self):
"""重新初始化数据。"""
self.bStartTraded = False # 是否已启动交易
self.curActivePrice = 0 # 当前交易成交的价位
self.PosRemainNum = 0 # 仓位保留的次数
self.bOpening = False # 是否正在开仓
self.forbidTrade = False # 是否已禁止交易
# ----------------------------------------------------------------------
def onInit(self):
"""在策略第一次启动时被调用。用户可继承实现。"""
pass
# ----------------------------------------------------------------------
def onStart(self):
"""在策略启动时被调用。用户可继承实现。"""
self._InitData() #初始化数据
self.insInfo = self.get_instrmentinfo(self.symbol)
if self.insInfo == None:
sMessageText = "获得合约信息失败,请检查配置的合约!"
" win32api.MessageBox(0, sMessageText, ""提示"", win32con.MB_ICONWARNING)"
return START_FAILD
" self.setTimer(self.timerId, 1000, self._onTimerFun)#启动计时器"
self.subSymbol(self.symbol) # 订阅行情
# ----------------------------------------------------------------------
def onStop(self):
"""在策略停止时被调用。用户可继承实现。"""
pass
# ----------------------------------------------------------------------
" def onTick(self, tickInfo):"
"""收到tick推送的处理函数,用户可继承实现。
tickInfo为TickInfo类型数据"""
if self.forbidTrade or self.bOpening:#开仓还未返回,则不加新的仓
return
if not self.bStartTraded: #第一次开仓
self.bStartTraded = True
marketPrice = tickInfo.upperLimit if self.tradeDirect == 0 else tickInfo.lowerLimit#以涨跌停价模拟市价
self.logs('第一次开仓,价格='+str(marketPrice))
self._sendOpenOrder(marketPrice) #以市价开新仓
" elif not math.isclose(self.curActivePrice, 0.0): # 新仓已开成功"
addPrice = self.curActivePrice - self.insInfo.priceTick * self.stepTickNum if self.tradeDirect == 0 else self.curActivePrice + self.insInfo.priceTick * self.stepTickNum
needAddOrder = tickInfo.last<=addPrice if self.tradeDirect == 0 else tickInfo.last>=addPrice #判断是否需要加仓
if needAddOrder:
self._sendOpenOrder(addPrice) # 以加仓价开新仓
self.logs('触发加仓,加仓价为:' + str(addPrice))
# ----------------------------------------------------------------------
" def onRtnOrder(self, order):"
"""收到委托单推送,用户可继承实现。"""
pass
# ----------------------------------------------------------------------
" def onRtnTrade(self, trade):"
"""收到成交单推送,用户可继承实现。"""
if trade.offsetFlag == POSITION_EFFECT_OPEN: #开仓成功
self.bOpening = False
self.PosRemainNum += 1
self.curActivePrice = trade.price # 成交价格
self.logs('加仓成功! 成交价为=' + str(trade.price))
self.logs('加仓成功! 仓位为='+str(self.PosRemainNum))
closePrice = self.curActivePrice+self.insInfo.priceTick*self.stepTickNum if self.tradeDirect == 0 else self.curActivePrice-self.insInfo.priceTick*self.stepTickNum #止盈价
self._sendCloseOrder(closePrice) #发平仓止盈委托单
self.logs('挂止盈平仓! 挂单价为=' + str(closePrice))
else:#平仓止盈成功
self.PosRemainNum -= 1 #剩余的仓位次数
self.curActivePrice = trade.price #更新当前最新价
self.logs('止盈成功!止盈价为:' + str(trade.price))
self.logs('止盈成功!剩余仓位为=' + str(self.PosRemainNum))
if self.bOpening: # 判断是否有加新仓,有的话,撤未成交的加仓
self._cancelAllOpenOrder()#平掉未成交的加仓委托
if self.PosRemainNum <= 0:#已无持仓,用最新的平仓成交价,开新的仓
self._sendOpenOrder(trade.price) # 以最新成交价,开新仓
# ----------------------------------------------------------------------
" def onRtnOrderInsertErr(self, trade):"
"""收到报单失败推送"""
self.logs('AutoTradeLong onRtnOrderInsertErr')
# ----------------------------------------------------------------------
" def onRtnOrderActionErr(self, trade):"
"""收到撤单失败推送"""
self.logs('AutoTradeLongAutoTradeLong onRtnOrderActionErr')
# ----------------------------------------------------------------------
" def _sendOpenOrder(self, openPrice):"
"""加仓"""
try:
self.bOpening = True
openDirection = BUYSELLTYPE_BUY if self.tradeDirect == 0 else BUYSELLTYPE_SELL #交易方向为多,则开多,否则开空
orderReq = OrderReq.__from_create__(
" self.relevantAccount,"
" self.symbol,"
" self.tradeNum,"
" openDirection,"
" POSITION_EFFECT_OPEN,"
openPrice
)
self.submit_order(orderReq)
except Exception as e:
self.logs("Exception: onStart " + str(e))
" def _sendCloseOrder(self, closePrice):"
"""止赢平仓"""
try:
clsoeDirection = BUYSELLTYPE_SELL if self.tradeDirect == 0 else BUYSELLTYPE_BUY #交易方向为多,则开多,否则开空
orderReq = OrderReq.__from_create__(
" self.relevantAccount,"
" self.symbol,"
" self.tradeNum,"
" clsoeDirection,"
" POSITION_EFFECT_CLOSE,"
closePrice
)
self.submit_order(orderReq)
except Exception as e:
self.logs("Exception: onStart " + str(e))
# ----------------------------------------------------------------------
def _cancelAllOpenOrder(self):
"""撤销所有处理中的加仓单"""
self.bOpening = False
" pendingOrders = self.get_orders(self.symbol, dataType=1) #得到所有未成交的委托单"
for order in pendingOrders:
if order.offsetFlag != POSITION_EFFECT_OPEN:#判断是否是开仓单
continue
orderKey = str(order.frontID) + str(order.sessionID) + str(order.orderRef)
" self.cancelOrderByKey(self.relevantAccount, orderKey) # 撤未成交委托"
# ----------------------------------------------------------------------
def _cancelAllPendingOrder(self):
"""撤销所有处理中的委托单"""
" pendingOrders = self.get_orders(self.symbol, dataType=1)"
for order in pendingOrders:
orderKey = str(order.frontID) + str(order.sessionID) + str(order.orderRef)
" self.cancelOrderByKey(self.relevantAccount, orderKey) # 撤未成交委托"
# ----------------------------------------------------------------------
" def _onTimerFun(self, timerId):"
"""计时器响应。"""
try:
curTime = datetime.datetime.now().strftime('%H:%M:%S')
if curTime <= self.clearEndTime and curTime >= self.clearBeginTime:
self.logs('到达时间,清仓所有未成交委托')
self.forbidTrade = True #禁止新的交易
self.unSubSymbol(self.symbol) # 订阅行情
self._cancelAllPendingOrder() # 移除所有的未成交委托
self.killTimer(timerId)#移除定时器
return 0
return 1
except Exception as e:
self.logs("Exception: onStart " + str(e))