均线策略python代码_Python版商品期货多品种均线策略

'''backtest

start: 2019-07-01 09:00:00

end: 2020-03-25 15:00:00

period: 1d

exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]'''

importjsonimportreimporttime

_bot=ext.NewPositionManager()classManager:'策略逻辑控制类'ACT_IDLE=0

ACT_LONG= 1ACT_SHORT= 2ACT_COVER= 3ERR_SUCCESS=0

ERR_SET_SYMBOL= 1ERR_GET_ORDERS= 2ERR_GET_POS= 3ERR_TRADE= 4ERR_GET_DEPTH= 5ERR_NOT_TRADING= 6errMsg= ["成功", "切换合约失败", "获取订单失败", "获取持仓失败", "交易下单失败", "获取深度失败", "不在交易时间"]def __init__(self, needRestore, symbol, keepBalance, fastPeriod, slowPeriod):#获取symbolDetail

symbolDetail =_C(exchange.SetContractType, symbol)if symbolDetail["VolumeMultiple"] == 0 or symbolDetail["MaxLimitOrderVolume"] == 0 or symbolDetail["MinLimitOrderVolume"] == 0 or symbolDetail["LongMarginRatio"] == 0 or symbolDetail["ShortMarginRatio"] ==0:

Log(symbolDetail)raise Exception("合约信息异常")else:

Log("合约", symbolDetail["InstrumentName"], "一手", symbolDetail["VolumeMultiple"], "份,最大下单量", symbolDetail["MaxLimitOrderVolume"], "保证金率:", _N(symbolDetail["LongMarginRatio"]), _N(symbolDetail["ShortMarginRatio"]), "交割日期", symbolDetail["StartDelivDate"])#初始化

self.symbol =symbol

self.keepBalance=keepBalance

self.fastPeriod=fastPeriod

self.slowPeriod=slowPeriod

self.marketPosition=None

self.holdPrice=None

self.holdAmount=None

self.holdProfit=None

self.task={"action": Manager.ACT_IDLE,"amount": 0,"dealAmount": 0,"avgPrice": 0,"preCost": 0,"preAmount": 0,"init": False,"retry": 0,"desc" : "空闲","onFinish": None

}

self.lastPrice=0

self.symbolDetail=symbolDetail#持仓状态信息

self.status ={"symbol": symbol,"recordsLen": 0,"vm": [],"open": 0,"cover": 0,"st": 0,"marketPosition": 0,"lastPrice": 0,"holdPrice": 0,"holdAmount": 0,"holdProfit": 0,"symbolDetail": symbolDetail,"lastErr" : "","lastErrTime" : "","isTrading": False

}#对象构造时其他处理工作

vm =Noneif RMode ==0:

vm=_G(self.symbol)else:

vm=json.loads(VMStatus)[self.symbol]ifvm:

Log("准备恢复进度,当前合约状态为", vm)

self.reset(vm[0])else:ifneedRestore:

Log("没有找到" + self.symbol + "的进度恢复信息")

self.reset()def setLastError(self, err=None):if err isNone:

self.status["lastErr"] = ""self.status["lastErrTime"] = ""

returnt=_D()

self.status["lastErr"] =err

self.status["lastErrTime"] =tdef reset(self, marketPosition=None):if marketPosition is notNone:

self.marketPosition=marketPosition

pos= _bot.GetPosition(self.symbol, PD_LONG if marketPosition > 0 elsePD_SHORT)if pos is notNone:

self.holdPrice= pos["Price"]

self.holdAmount= pos["Amount"]

Log(self.symbol,"仓位", pos)else:raise Exception("恢复" + self.symbol + "的持仓状态出错,没有找到仓位信息")

Log("恢复", self.symbol, "持仓均价:", self.holdPrice, "持仓数量:", self.holdAmount)

self.status["vm"] =[self.marketPosition]else:

self.marketPosition=0

self.holdPrice=0

self.holdAmount=0

self.holdProfit=0

self.holdProfit=0

self.lastErr= ""self.lastErrTime= ""

defStatus(self):

self.status["marketPosition"] =self.marketPosition

self.status["holdPrice"] =self.holdPrice

self.status["holdAmount"] =self.holdAmount

self.status["lastPrice"] =self.lastPriceif self.lastPrice > 0 and self.holdAmount > 0 and self.marketPosition !=0:

self.status["holdProfit"] = _N((self.lastPrice - self.holdPrice) * self.holdAmount * self.symbolDetail["VolumeMultiple"], 4) * (1 if self.marketPosition > 0 else -1)else:

self.status["holdProfit"] =0returnself.statusdef setTask(self, action, amount = None, onFinish =None):

self.task["init"] =False

self.task["retry"] =0

self.task["action"] =action

self.task["preAmount"] =0

self.task["preCost"] =0

self.task["amount"] = 0 if amount is None elseamount

self.task["onFinish"] =onFinishif action ==Manager.ACT_IDLE:

self.task["desc"] = "空闲"self.task["onFinish"] =Noneelse:if action !=Manager.ACT_COVER:

self.task["desc"] = ("加多仓" if action == Manager.ACT_LONG else "加空仓") + "(" + str(amount) + ")"

else:

self.task["desc"] = "平仓"Log("接收到任务", self.symbol, self.task["desc"])

self.Poll(True)defprocessTask(self):

insDetail=exchange.SetContractType(self.symbol)if notinsDetail:returnManager.ERR_SET_SYMBOL

SlideTick= 1ret=Falseif self.task["action"] ==Manager.ACT_COVER:

hasPosition=FalsewhileTrue:if notext.IsTrading(self.symbol):returnManager.ERR_NOT_TRADING

hasPosition=False

positions=exchange.GetPosition()if positions isNone:returnManager.ERR_GET_POS

depth=exchange.GetDepth()if depth isNone:returnManager.ERR_GET_DEPTH

orderId=Nonefor i inrange(len(positions)):if positions[i]["ContractType"] !=self.symbol:continueamount= min(insDetail["MaxLimitOrderVolume"], positions[i]["Amount"])if positions[i]["Type"] == PD_LONG or positions[i]["Type"] ==PD_LONG_YD:

exchange.SetDirection("closebuy_today" if positions[i].Type == PD_LONG else "closebuy")

orderId= exchange.Sell(_N(depth["Bids"][0]["Price"] - (insDetail["PriceTick"] * SlideTick), 2), min(amount, depth["Bids"][0]["Amount"]), self.symbol, "平今" if positions[i]["Type"] == PD_LONG else "平昨", "Bid", depth["Bids"][0])

hasPosition=Trueelif positions[i]["Type"] == PD_SHORT or positions[i]["Type"] ==PD_SHORT_YD:

exchange.SetDirection("closesell_today" if positions[i]["Type"] == PD_SHORT else "closesell")

orderId= exchange.Buy(_N(depth["Asks"][0]["Price"] + (insDetail["PriceTick"] * SlideTick), 2), min(amount, depth["Asks"][0]["Amount"]), self.symbol, "平今" if positions[i]["Type"] == PD_SHORT else "平昨", "Ask", depth["Asks"][0])

hasPosition=TrueifhasPosition:if notorderId:returnManager.ERR_TRADE

Sleep(1000)whileTrue:

orders=exchange.GetOrders()if orders isNone:returnManager.ERR_GET_ORDERSif len(orders) ==0:break

for i inrange(len(orders)):

exchange.CancelOrder(orders[i]["Id"])

Sleep(500)if nothasPosition:breakret=Trueelif self.task["action"] == Manager.ACT_LONG or self.task["action"] ==Manager.ACT_SHORT:whileTrue:if notext.IsTrading(self.symbol):returnManager.ERR_NOT_TRADING

Sleep(1000)whileTrue:

orders=exchange.GetOrders()if orders isNone:returnManager.ERR_GET_ORDERSif len(orders) ==0:break

for i inrange(len(orders)):

exchange.CancelOrder(orders[i]["Id"])

Sleep(500)

positions=exchange.GetPosition()if positions isNone:returnManager.ERR_GET_POS

pos=Nonefor i inrange(len(positions)):if positions[i]["ContractType"] == self.symbol and (((positions[i]["Type"] == PD_LONG or positions[i]["Type"] == PD_LONG_YD) and self.task["action"] == Manager.ACT_LONG) or ((positions[i]["Type"] == PD_SHORT) or positions[i]["Type"] == PD_SHORT_YD) and self.task["action"] ==Manager.ACT_SHORT):if notpos:

pos=positions[i]

pos["Cost"] = positions[i]["Price"] * positions[i]["Amount"]else:

pos["Amount"] += positions[i]["Amount"]

pos["Profit"] += positions[i]["Profit"]

pos["Cost"] += positions[i]["Price"] * positions[i]["Amount"]#records pre position

if not self.task["init"]:

self.task["init"] =Trueifpos:

self.task["preAmount"] = pos["Amount"]

self.task["preCost"] = pos["Cost"]else:

self.task["preAmount"] =0

self.task["preCost"] =0

remain= self.task["amount"]ifpos:

self.task["dealAmount"] = pos["Amount"] - self.task["preAmount"]

remain= int(self.task["amount"] - self.task["dealAmount"])if remain <= 0 or self.task["retry"] >=MaxTaskRetry:

ret={"price" : (pos["Cost"] - self.task["preCost"]) / (pos["Amount"] - self.task["preAmount"]),"amount" : (pos["Amount"] - self.task["preAmount"]),"position": pos

}break

elif self.task["retry"] >=MaxTaskRetry:

ret=Nonebreakdepth=exchange.GetDepth()if depth isNone:returnManager.ERR_GET_DEPTH

orderId=Noneif self.task["action"] ==Manager.ACT_LONG:

exchange.SetDirection("buy")

orderId= exchange.Buy(_N(depth["Asks"][0]["Price"] + (insDetail["PriceTick"] * SlideTick), 2), min(remain, depth["Asks"][0]["Amount"]), self.symbol, "Ask", depth["Asks"][0])else:

exchange.SetDirection("sell")

orderId= exchange.Sell(_N(depth["Bids"][0]["Price"] - (insDetail["PriceTick"] * SlideTick), 2), min(remain, depth["Bids"][0]["Amount"]), self.symbol, "Bid", depth["Bids"][0])if orderId isNone:

self.task["retry"] += 1

returnManager.ERR_TRADEif self.task["onFinish"]:

self.task["onFinish"](ret)

self.setTask(Manager.ACT_IDLE)returnManager.ERR_SUCCESSdef Poll(self, subroutine =False):#判断交易时段

self.status["isTrading"] =ext.IsTrading(self.symbol)if not self.status["isTrading"]:return

#执行下单交易任务

if self.task["action"] !=Manager.ACT_IDLE:

retCode=self.processTask()if self.task["action"] !=Manager.ACT_IDLE:

self.setLastError("任务没有处理成功:" + Manager.errMsg[retCode] + "," + self.task["desc"] + ", 重试:" + str(self.task["retry"]))else:

self.setLastError()return

ifsubroutine:returnsuffix= "@" if WXPush else ""

#switch symbol

_C(exchange.SetContractType, self.symbol)#获取K线数据

records =exchange.GetRecords()if records isNone:

self.setLastError("获取K线失败")returnself.status["recordsLen"] =len(records)if len(records) < self.fastPeriod + 2 or len(records) < self.slowPeriod + 2:

self.setLastError("K线长度小于 均线周期:" + str(self.fastPeriod) + "或" +str(self.slowPeriod))returnopCode= 0 #0 : IDLE , 1 : LONG , 2 : SHORT , 3 : CoverALL

lastPrice = records[-1]["Close"]

self.lastPrice=lastPrice

fastMA=TA.EMA(records, self.fastPeriod)

slowMA=TA.EMA(records, self.slowPeriod)#策略逻辑

if self.marketPosition ==0:if fastMA[-3] < slowMA[-3] and fastMA[-2] > slowMA[-2]:

opCode= 1

elif fastMA[-3] > slowMA[-3] and fastMA[-2] < slowMA[-2]:

opCode= 2

else:if self.marketPosition < 0 and fastMA[-3] < slowMA[-3] and fastMA[-2] > slowMA[-2]:

opCode= 3

elif self.marketPosition > 0 and fastMA[-3] > slowMA[-3] and fastMA[-2] < slowMA[-2]:

opCode= 3

#如果不触发任何条件,操作码为0,返回

if opCode ==0:return

#执行平仓

if opCode == 3:defcoverCallBack(ret):

self.reset()

_G(self.symbol, None)

self.setTask(Manager.ACT_COVER, 0, coverCallBack)returnaccount=_bot.GetAccount()

canOpen= int((account["Balance"] - self.keepBalance) / (self.symbolDetail["LongMarginRatio"] if opCode == 1 else self.symbolDetail["ShortMarginRatio"]) / (lastPrice * 1.2) / self.symbolDetail["VolumeMultiple"])

unit= min(1, canOpen)#设置交易任务

defsetTaskCallBack(ret):if notret:

self.setLastError("下单失败")returnself.holdPrice= ret["position"]["Price"]

self.holdAmount= ret["position"]["Amount"]

self.marketPosition+= 1 if opCode == 1 else -1self.status["vm"] =[self.marketPosition]

_G(self.symbol, self.status["vm"])

self.setTask(Manager.ACT_LONGif opCode == 1 elseManager.ACT_SHORT, unit, setTaskCallBack)defonexit():

Log("已退出策略...")defmain():if exchange.GetName().find("CTP") == -1:raise Exception("只支持商品期货CTP")

SetErrorFilter("login|ready|流控|连接失败|初始|Timeout")

mode= exchange.IO("mode", 0)if mode isNone:raise Exception("切换模式失败,请更新到最新托管者!")while not exchange.IO("status"):

Sleep(3000)

LogStatus("正在等待与交易服务器连接," +_D())

positions=_C(exchange.GetPosition)if len(positions) >0:

Log("检测到当前持有仓位,系统将开始尝试恢复进度...")

Log("持仓信息:", positions)

initAccount=_bot.GetAccount()

initMargin= json.loads(exchange.GetRawJSON())["CurrMargin"]

keepBalance= _N((initAccount["Balance"] + initMargin) * (KeepRatio / 100), 3)

Log("资产信息", initAccount, "保留资金:", keepBalance)

tts=[]

symbolFilter={}

arr= Instruments.split(",")

arrFastPeriod= FastPeriodArr.split(",")

arrSlowPeriod= SlowPeriodArr.split(",")if len(arr) != len(arrFastPeriod) or len(arr) !=len(arrSlowPeriod):raise Exception("均线周期参数与添加合约数量不匹配,请检查参数!")for i inrange(len(arr)):

symbol= re.sub(r'/\s+$/g', "", re.sub(r'/^\s+/g', "", arr[i]))if symbol insymbolFilter.keys():raise Exception(symbol + "已经存在,请检查参数!")

symbolFilter[symbol]=True

hasPosition=Falsefor j inrange(len(positions)):if positions[j]["ContractType"] ==symbol:

hasPosition=TruebreakfastPeriod=int(arrFastPeriod[i])

slowPeriod=int(arrSlowPeriod[i])

obj=Manager(hasPosition, symbol, keepBalance, fastPeriod, slowPeriod)

tts.append(obj)

preTotalHold= -1lastStatus= ""

whileTrue:if GetCommand() == "暂停/继续":

Log("暂停交易中...")while GetCommand() != "暂停/继续":

Sleep(1000)

Log("继续交易中...")while not exchange.IO("status"):

Sleep(3000)

LogStatus("正在等待与交易服务器连接," + _D() + "\n" +lastStatus)

tblStatus={"type" : "table","title" : "持仓信息","cols" : ["合约名称", "持仓方向", "持仓均价", "持仓数量", "持仓盈亏", "加仓次数", "当前价格"],"rows": []

}

tblMarket={"type" : "table","title" : "运行状态","cols" : ["合约名称", "合约乘数", "保证金率", "交易时间", "柱线长度", "异常描述", "发生时间"],"rows": []

}

totalHold=0

vmStatus={}

ts=time.time()

holdSymbol=0for i inrange(len(tts)):

tts[i].Poll()

d=tts[i].Status()if d["holdAmount"] >0:

vmStatus[d["symbol"]] = d["vm"]

holdSymbol+= 1tblStatus["rows"].append([d["symbolDetail"]["InstrumentName"], "--" if d["holdAmount"] == 0 else ("多" if d["marketPosition"] > 0 else "空"), d["holdPrice"], d["holdAmount"], d["holdProfit"], abs(d["marketPosition"]), d["lastPrice"]])

tblMarket["rows"].append([d["symbolDetail"]["InstrumentName"], d["symbolDetail"]["VolumeMultiple"], str(_N(d["symbolDetail"]["LongMarginRatio"], 4)) + "/" + str(_N(d["symbolDetail"]["ShortMarginRatio"], 4)), "是#0000ff" if d["isTrading"] else "否#ff0000", d["recordsLen"], d["lastErr"], d["lastErrTime"]])

totalHold+= abs(d["holdAmount"])

now=time.time()

elapsed= now -ts

tblAssets=_bot.GetAccount(True)

nowAccount=_bot.Account()if len(tblAssets["rows"]) > 10:

tblAssets["rows"][0] = ["InitAccount", "初始资产", initAccount]else:

tblAssets["rows"].insert(0, ["NowAccount", "当前可用", nowAccount])

tblAssets["rows"].insert(0, ["InitAccount", "初始资产", initAccount])

lastStatus= "`" + json.dumps([tblStatus, tblMarket, tblAssets]) + "`\n轮询耗时:" + str(elapsed) + "秒,当前时间:" + _D() + ", 持有品种个数:" +str(holdSymbol)if totalHold >0:

lastStatus+= "\n手动恢复字符串:" +json.dumps(vmStatus)

LogStatus(lastStatus)if preTotalHold > 0 and totalHold ==0:

LogProfit(nowAccount.Balance- initAccount.Balance -initMargin)

preTotalHold=totalHold

Sleep(LoopInterval* 1000)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值