Dual Thrust 策略包含完整的图表显示, 图表动态更新,模板引用等功能, 可做学习模板使用.
import time class Error_noSupport(BaseException): def __init__(self): Log("只支持OKCoin期货!#FF0000") class Error_AtBeginHasPosition(BaseException): def __init__(self): Log("启动时有期货持仓! #FF0000") ChartCfg = { '__isStock': True, 'title': { 'text': 'Dual Thrust 上下轨图' }, 'yAxis': { 'plotLines': [{ 'value': 0, 'color': 'red', 'width': 2, 'label': { 'text': '上轨', 'align': 'center' }, }, { 'value': 0, 'color': 'green', 'width': 2, 'label': { 'text': '下轨', 'align': 'center' }, }] }, 'series': [{ 'type': 'candlestick', 'name': '当前周期', 'id': 'primary', 'data': [] }, { 'type': 'flags', 'onSeries': 'primary', 'data': [] }] } STATE_IDLE = 0 STATE_LONG = 1 STATE_SHORT = 2 State = STATE_IDLE LastBarTime = 0 UpTrack = 0 BottomTrack = 0 chart = None InitAccount = None LastAccount = None Counter = { 'w': 0, 'l': 0 } def GetPosition(posType): # if the positions has no this posType ,will return [] ,Another case is return a dict of object positions = exchange.GetPosition() return [{'Price': position['Price'], 'Amount': position['Amount']} for position in positions if position['Type'] == posType] def CancelPendingOrders(): while True: orders = exchange.GetOrders() [exchange.CancelOrder(order['Id']) for order in orders if not Sleep(500)] if len(orders) == 0: break def Trade(currentState,nextState): global InitAccount,LastAccount,OpenPrice,ClosePrice ticker = _C(exchange.GetTicker) slidePrice = 1 pfn = exchange.Buy if nextState == STATE_LONG else exchange.Sell if currentState != STATE_IDLE: Log(_C(exchange.GetPosition)) # ceshi exchange.SetDirection("closebuy" if currentState == STATE_LONG else "closesell") while True: ID = pfn( (ticker['Last'] - slidePrice) if currentState == STATE_LONG else (ticker['Last'] + slidePrice), AmountOP) # xiugai 限价单 # ID = pfn(-1, AmountOP) # xiugai 市价单 # ID = pfn(AmountOP) # xiugai 市价单 Sleep(Interval) Log(exchange.GetOrder(ID)) # xiugai ClosePrice = (exchange.GetOrder(ID))['AvgPrice'] # CancelPendingOrders() if len(GetPosition(PD_LONG if currentState == STATE_LONG else PD_SHORT)) == 0: break account = exchange.GetAccount() if account['Stocks'] > LastAccount['Stocks']: Counter['w'] += 1 else: Counter['l'] += 1 # Log("ceshi account:",account,InitAccount) #ceshi Log(account) # xiugai LogProfit((account['Stocks'] - InitAccount['Stocks']),"收益率:", ((account['Stocks'] - InitAccount['Stocks']) * 100 / InitAccount['Stocks']),'%') Cal(OpenPrice,ClosePrice) LsatAccount = account exchange.SetDirection("buy" if nextState == STATE_LONG else "sell") Log(_C(exchange.GetAccount)) while True: ID = pfn( (ticker['Last'] + slidePrice) if nextState == STATE_LONG else (ticker['Last'] - slidePrice), AmountOP) # 限价单 # ID = pfn(-1, AmountOP) # 市价单 # ID = pfn(AmountOP) # 市价单 Sleep(Interval) Log(exchange.GetOrder(ID)) # xiugai CancelPendingOrders() pos = GetPosition(PD_LONG if nextState == STATE_LONG else PD_SHORT) if len(pos) != 0: Log("持仓均价",pos[0]['Price'],"数量:",pos[0]['Amount']) OpenPrice = (exchange.GetOrder(ID))['AvgPrice'] # pos[0]['Price'] Log("now account:",exchange.GetAccount()) break def onTick(exchange): global LastBarTime,chart,State,UpTrack,DownTrack,LastAccount records = exchange.GetRecords() if not records or len(records) <= NPeriod: return Bar = records[-1] if LastBarTime != Bar['Time']: HH = TA.Highest(records, NPeriod, 'High') HC = TA.Highest(records, NPeriod, 'Close') LL = TA.Lowest(records, NPeriod, 'Low') LC = TA.Lowest(records, NPeriod, 'Close') Range = max(HH - LC, HC - LL) UpTrack = _N(Bar['Open'] + (Ks * Range)) DownTrack = _N(Bar['Open'] - (Kx * Range)) if LastBarTime > 0: PreBar = records[-2] chart.add(0, [PreBar['Time'], PreBar['Open'], PreBar['High'], PreBar['Low'], PreBar['Close']], -1) else: for i in range(len(records) - min(len(records), NPeriod * 3), len(records)): b = records[i] chart.add(0,[b['Time'], b['Open'], b['High'], b['Low'], b['Close']]) chart.add(0,[Bar['Time'], Bar['Open'], Bar['High'], Bar['Low'], Bar['Close']]) ChartCfg['yAxis']['plotLines'][0]['value'] = UpTrack ChartCfg['yAxis']['plotLines'][1]['value'] = DownTrack ChartCfg['subtitle'] = { 'text': '上轨' + str(UpTrack) + '下轨' + str(DownTrack) } chart.update(ChartCfg) chart.reset(PeriodShow) LastBarTime = Bar['Time'] else: chart.add(0,[Bar['Time'], Bar['Open'], Bar['High'], Bar['Low'], Bar['Close']], -1) LogStatus("Price:", Bar["Close"], "up:", UpTrack, "down:", DownTrack, "wins:", Counter['w'], "losses:", Counter['l'], "Date:", time.time()) msg = "" if State == STATE_IDLE or State == STATE_SHORT: if Bar['Close'] >= UpTrack: msg = "做多,触发价:" + str(Bar['Close']) + "上轨" + str(UpTrack) Log(msg) Trade(State, STATE_LONG) State = STATE_LONG chart.add(1,{'x': Bar['Time'], 'color': 'red', 'shape': 'flag', 'title': '多', 'text': msg}) if State == STATE_IDLE or State == STATE_LONG: if Bar['Close'] <= DownTrack: msg = "做空,触发价:" + str(Bar['Close']) + "下轨" + str(DownTrack) Log(msg) Trade(State, STATE_SHORT) State = STATE_SHORT chart.add(1,{'x': Bar['Time'], 'color': 'green', 'shape': 'circlepin', 'title': '空', 'text': msg}) OpenPrice = 0 ClosePrice = 0 def Cal(OpenPrice, ClosePrice): global AmountOP,State if State == STATE_SHORT: Log(AmountOP,OpenPrice,ClosePrice,"策略盈亏:", (AmountOP * 100) / ClosePrice - (AmountOP * 100) / OpenPrice, "个币, 手续费:", - (100 * AmountOP * 0.0003), "美元,折合:", _N( - 100 * AmountOP * 0.0003/OpenPrice,8), "个币") Log(((AmountOP * 100) / ClosePrice - (AmountOP * 100) / OpenPrice) + (- 100 * AmountOP * 0.0003/OpenPrice)) if State == STATE_LONG: Log(AmountOP,OpenPrice,ClosePrice,"策略盈亏:", (AmountOP * 100) / OpenPrice - (AmountOP * 100) / ClosePrice, "个币, 手续费:", - (100 * AmountOP * 0.0003), "美元,折合:", _N( - 100 * AmountOP * 0.0003/OpenPrice,8), "个币") Log(((AmountOP * 100) / OpenPrice - (AmountOP * 100) / ClosePrice) + (- 100 * AmountOP * 0.0003/OpenPrice)) def main(): global LoopInterval,chart,LastAccount,InitAccount if exchange.GetName() != 'Futures_OKCoin': raise Error_noSupport exchange.SetRate(1) exchange.SetContractType(["this_week","next_week","quarter"][ContractTypeIdx]) exchange.SetMarginLevel([10,20][MarginLevelIdx]) # Log("Fee:",exchange.GetFee()) if len(exchange.GetPosition()) > 0: raise Error_AtBeginHasPosition CancelPendingOrders() InitAccount = LastAccount = exchange.GetAccount() LoopInterval = min(1,LoopInterval) Log("交易平台:",exchange.GetName(), InitAccount) LogStatus("Ready...") LogProfitReset() chart = Chart(ChartCfg) chart.reset() LoopInterval = max(LoopInterval, 1) while True: onTick(exchange) Sleep(LoopInterval * 1000)
outlawjk def onTick: ................ if State == STATE_IDLE or State == STATE_SHORT: if Bar['Close'] >= UpTrack: msg = "做多,触发价:" + str(Bar['Close']) + "上轨" + str(UpTrack) Log(msg) Trade(State, STATE_LONG) State = STATE_LONG chart.add(1,{'x': Bar['Time'], 'color': 'red', 'shape': 'flag', 'title': '多', 'text': msg}) 如果订单未成交,这边state=state_long,改变了state的值,会不会对策略造成影响
wangyj1 我想借用这个模板的图形功能,但图中上下轨的显示明显有问题
wangyj1 上下轨都变成一条直线了,大神能否修复一下
wangyj1 上下轨都变成一条线了,大神能否修复一下
发明者量化-小小梦 应该不会 ,下的是 市价单, Trade 函数 检测到有持仓 才返回的。这个策略 逻辑是 移植 自 JS 版 OK期货 DT 策略的。
发明者量化-小小梦 你看我贴出的 ,是哪里有问题呢 ^^
发明者量化-小小梦 这个 策略 要使用 日周期的 K线 ,周期太小 不行。 https://dn-filebox.qbox.me/7a2386aa71ea2fbaa8168139789e2db87d999ecd.png