For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
SELF.CANCEL() not working as expected.
-
Re: Cancel Order
Hello @backtrader. Self.cancel() doesn't seem to work in my strategy class. Can you help me check what I have implemented wrongly.
CODE:
import backtrader as bt from backtrader import indicators as ind from collections import deque from utils.tv_functions import na, nz, ternary from indicators import StGrab, AtrTrailStop, HullSuite, Halftrend, PPS, HtfEma import random class ParthStrategy(bt.Strategy): lines = ('sl',) def __init__(self): self.data_0 = self.datas[0] self.data_240 = self.datas[1] # Indicators self.stgrab = StGrab(self.data_240) self.htfema = HtfEma(self.data_240) self.hull_suite = HullSuite(self.data_240) self.halftrend = Halftrend(self.data_0) self.pps = PPS(self.data_0) self.ats = AtrTrailStop(self.data_0) # Variables self.window_cond_hull = deque([], maxlen=500) self.window_cond_touch_line = deque(['False', 'False'], maxlen=2) self.pend_long = False self.sl = bt.LineNum(float('nan')) # Strategy Variables self.order_entry = None self.order_close = None self.order_cancel = None self.active_trade = None self.active_trail = None self.trade_count = 0 def log(self, _text, dt=None): dt = dt or self.datas[0].datetime.datetime(0) print(f'{dt.strftime("%Y-%m-%d %H:%M:%S")} : {_text}') def next(self): bar = self.data_0 # region ----- CONDITIONS # St Grab cond_above_st = bar.close[0] > self.stgrab.lines.ema_high[0] cond_below_st = bar.close[0] < self.stgrab.lines.ema_low[0] # HTF EMAs cond_ema_long = (self.htfema.lines.ema_1[0] > self.htfema.lines.ema_2[0]) and (self.htfema.lines.ema_2[0] > self.htfema.lines.ema_3[0]) # Hull Suite _hull_long = self.hull_suite.lines.hull[0] > self.hull_suite.lines.shull[0] self.window_cond_hull.appendleft(_hull_long) cond_hull_long = any(self.window_cond_hull) # Halftrend cond_ht_long = (not na(self.halftrend.lines.arrowUp[0])) and self.halftrend.lines.trend[0] == 0 and self.halftrend.lines.trend[-1] == 1 cond_ht_short = (not na(self.halftrend.lines.arrowDown[0])) and self.halftrend.lines.trend[0] == 1 and self.halftrend.lines.trend[-1] == 0 # ATR Trailing Stop cond_ats_long = self.ats.lines.cond_ats_long[0] cond_ats_short = self.ats.lines.cond_ats_short[0] sl_line = \ ternary((bar.close[0] > self.pps.l.Trailingsl[0]) and (bar.close[0] > self.ats.l.xATRTrailingStop), ternary((abs(bar.close[0] - self.pps.l.Trailingsl[0]) < abs(bar.close[0] - self.ats.l.xATRTrailingStop)), self.pps.l.Trailingsl[0], self.ats.l.xATRTrailingStop), ternary((bar.close[0] > self.pps.l.Trailingsl[0]), self.pps.l.Trailingsl[0], self.ats.l.xATRTrailingStop)) cond_touch_line = bar.high[0] >= sl_line and bar.low[0] <= sl_line self.window_cond_touch_line.append(cond_touch_line) if self.window_cond_touch_line[0] and not self.window_cond_touch_line[1]: self.sl[0] = sl_line - ((.45/100) * sl_line) # endregion # region ----- ENTRY if (not self.pend_long) and (cond_ht_long and cond_above_st ) and (self.position.size == 0) and (cond_ats_long): # Halftrend Long Signal, while Price Above Halftrend, and Halftrend above ST_GRaB self.pend_long = True self.order_entry = self.buy(bar, price=bar.high, exectype=bt.Order.Stop) # strategy.entry('Buy', strategy.long, stop=high, comment = i_message_enter) self.log(f'<--- buy order sent ({bar.high[0]})--->') if self.pend_long and self.order_entry and (self.position.size == 0): # Cancel Pending Orders if (cond_ht_short or cond_ats_short or (not cond_hull_long) or (not cond_ema_long)): # Cancel Buy Sequence If: # - Short Signal from Halftrend # - Current Price is below the ATR Line # - No Buy Signal from Hull Suite in the last 500 bars # - 4-hour EMA not in the right order, and MAPD is not within 4 and -4 self.pend_long = False self.broker.cancel(self.order_entry) # strategy.cancel('Buy') self.log(f'<--- cancel buy order sent --->') self.sell(exectype=bt.Order.Stop, price=0.1, size=0) # endregion # region ----- EXIT if self.position.size > 0: self.pend_long = False # MANUALLY MONITOR TRAILING STOP EXIT : if (bar.low[0] <= self.sl[0]) and (bar.low[-1] > self.sl[-1]): self.close() self.log('<--- exit buy order sent : trailing stop triggered --->') if cond_ats_short: self.close() self.log('<--- close buy signal sent : price below atr line --->') # endregion def notify_order(self, order): bar = self.data_0 if order.status in [order.Accepted]: self.log(f'<--- order recieved --->') return # Check if an order has been completed # Attention: broker could reject order if not enough cash if order.status in [order.Completed]: if order.isbuy(): pass elif order.issell(): pass elif order.status == order.Cancelled: self.log(f'--- Cancel Buy Signal Sent (Confirmed)') # elif order.issell(): # self.log('--- Stop Loss Updated (Confirmed)') # elif order.status in [order.Margin, order.Rejected]: # self.log('ERROR: Order Margin/Rejected') # self.pend_long = False # self.order_entry = None # self.trade_active = None def notify_trade(self, trade): if trade.justopened and trade.size > 0: self.log(f'TRADE EXECUTED at {trade.price: .2f}') if trade.isclosed: self.log(f'TRADE CLOSED at {trade.price: .2f}') self.trade_count += 1 def stop(self): print('Trades Completed : ', self.trade_count)