For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
2 timeframes, but trade observer and buy/sell affected
-
sorry, misclicked. I really want the old trade observer back. Where the profits are in blue dots, losses in red dots. Now I only get blue dots even though they are negative pnl.
class BaseStrategy(bt.Strategy): # Strategy is a lines object params = dict(order_percentage=0.25, ticker='eurusd', fast=10, slow=30) parent_order = None # default value for a potential order stoploss = None def __init__(self): self.order = None # To keep track of pending orders, init with None self.buyprice = None self.buycomm = None self.bar_executed = None self.size = None self.lendata1 = 0 self.data = self.datas[0] self.data1 = self.datas[1] self.fast_sma = bt.indicators.SMA(self.data.close, period=self.params.fast) self.slow_sma = bt.indicators.SMA(self.data.close, period=self.params.slow) self.crossover = bt.indicators.CrossOver(self.fast_sma, self.slow_sma) self.fast1_sma = bt.indicators.SMA(self.data1.close, period=self.params.fast) self.slow1_sma = bt.indicators.SMA(self.data1.close, period=self.params.slow) self.crossover1 = bt.indicators.CrossOver(self.fast1_sma, self.slow1_sma) self.data1.plotinfo.plot = False self.fast1_sma.plotinfo.plot = False self.slow1_sma.plotinfo.plot = False self.crossover1.plotinfo.plot = False def notify_order(self, order): # called when a buy or sell is requested if order.status in [order.Submitted]: # status 1 # Buy/Sell order submitted/accepted to/by broker - Nothing to do print('Order Submitted...', order.ref) return if order.status in [order.Accepted]: # status 2 # Buy/Sell order submitted/accepted to/by broker - Nothing to do print('Order Accepted...', order.ref) return if order.status in [order.Margin, order.Rejected]: print('Order Margin/Rejected', order.ref) return # Check if an order has been completed, Attention: broker could reject order if not enough cash if order.status in [order.Completed]: # status 4 print('-'*50, 'EXECUTED ORDER', '-'*50) print('{} EXE-D, REF {}, AT {}: {:d} shares of {}, Price: {}, Value: {:.2f}, Comm: {:.2f}, PNL: {}'.format( order.info['name'], order.ref, bt.num2date(order.executed.dt), order.executed.size, self.p.ticker, order.executed.price, order.executed.value, order.executed.comm, order.executed.pnl)) print('-' * 116) def nextstart(self): self.lendata1 = len(self.data1) # if this a 240min timeframe, len of self.data1 is 2. # super(BaseStrategy, self).nextstart() -->do i even need this? # print(len(self.data1)) def next(self): # print('len self.datas:', len(self.datas)) # print('len self.data1, lendata1', len(self.data1), self.lendata1) txt = list() txt.append('Data0') txt.append('{}'.format(len(self.data))) txt.append('{}'.format(self.data.datetime.datetime(0))) txt.append('{:.5f}'.format(self.data.open[0])) txt.append('{:.5f}'.format(self.data.high[0])) txt.append('{:.5f}'.format(self.data.low[0])) txt.append('{:.5f}'.format(self.data.close[0]) # print(', '.join(txt)) if len(self.data1) > self.lendata1: self.lendata1 += 1 print('new higher TF bar') if len(self.datas) > 1 and len(self.data1): # len datas is always at 2 becasue i got min and 240 min data, len data1 is increasing from 2 to ... txt = list() txt.append('Data1') txt.append('{}'.format(len(self.data1))) txt.append('{}'.format(self.data1.datetime.datetime(0))) txt.append('{:.5f}'.format(self.data1.open[0])) txt.append('{:.5f}'.format(self.data1.high[0])) txt.append('{:.5f}'.format(self.data1.low[0])) txt.append('{:.5f}'.format(self.data1.close[0]) # print(', '.join(txt)) can_trade = check_timefx(self.data.datetime.date(0), self.data.datetime.time(0)) if self.crossover > 0 and self.crossover1 > 0: action = 'long' elif self.crossover < 0 and self.crossover1 < 0: action = 'short' else: action = 'not sure yet' # Check if we are in the market if can_trade: if action == 'long' or action == 'short': if self.position: self.cancel(self.stoploss) print('{} {} canceled.'.format(self.stoploss.info['name'], self.stoploss.ref)) self.close(name='Trend Change - take profit...') self.stoploss = None if self.parent_order: # something was pending, cancelling parent cancels stoploss too self.cancel(self.parent_order) print('{} {} canceled.'.format(self.parent_order.info['name'], self.parent_order.ref)) self.parent_order = None self.stoploss = None # Now I am no more in a position amount_to_invest = (self.p.order_percentage * self.broker.cash) self.size = math.floor(amount_to_invest / self.data.close) if action == 'long': self.parent_order = self.buy(size=self.size, exectype=bt.Order.Market, transmit=False, valid=None) self.stoploss = self.sell(price=self.data.close, exectype=bt.Order.Stop, size=self.parent_order.size, parent=self.parent_order, transmit=True, valid=None) self.parent_order.addinfo(name='Parent Long Order') self.stoploss.addinfo(name='Child Long Stop Loss Order') elif action == 'short': self.parent_order = self.sell(size=self.size, exectype=bt.Order.Market, transmit=False, valid=None) self.stoploss = self.buy(price=self.data.close, exectype=bt.Order.Stop, size=self.parent_order.size, parent=self.parent_order, transmit=True, valid=None) self.parent_order.addinfo(name='Parent Short Order') self.stoploss.addinfo(name='Child Short Stop Loss Order') print('=' * 50, 'CREATE ORDER', '=' * 50) print('{} CREATE, REF {}, CURRENT PX: {:.5f}, {} AT {:.5f}, STOPLOSS AT {:.5f}'.format( self.parent_order.info['name'], self.parent_order.ref, self.data.close[0], 'LONG' if 'Long' in self.parent_order.info['name'] else 'SHORT', self.data.close[0], self.data.close[-1])) print('=' * 114) elif action == 'not sure yet': print('not sure what action to take') else: print('no action2 - meaning regular trading') else: # past time 3pm, not trading anymore, look to close position # print('Last hour or Closed....') if self.position: if times_upfx(self.data.datetime.time(0)): # 15:46 times up look to just close. self.cancel(self.stoploss) print('{} {} canceled.'.format(self.stoploss.info['name'], self.stoploss.ref)) self.close(name='Times Up, Close final position') self.stoploss = None self.parent_order = None else: # 15:01 to 15:46 look for next turning point to sell so maximise profit if action == 'long' or action == 'short': self.cancel(self.stoploss) print('{} {} canceled.'.format(self.stoploss.info['name'], self.stoploss.ref)) self.close(name='Trend Change, Take profit') self.stoploss = None self.parent_order = None def main(): cerebro = bt.Cerebro(stdstats=True) # Add a strategy cerebro.addstrategy(BaseStrategy) df = pd.read_csv('datas\\EURUSD2019Jan.csv', sep=',', header=0, index_col=0, parse_dates=True) # Create a Data Feed and add to cerebro data = bt.feeds.PandasData(dataname=df, timeframe=bt.TimeFrame.Minutes, compression=1) cerebro.adddata(data, name='data') # cerebro.resampledata(data, timeframe=bt.TimeFrame.Minutes, compression=1) cerebro.resampledata(data, timeframe=bt.TimeFrame.Minutes, compression=240, name='data1') cerebro.broker.setcash(10000.0) cerebro.broker.setcommission(commission=0.0001) strat = cerebro.run(maxcpus=3) print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.plot(style='candlestick', barup='green', bardown='red', fmt_x_ticks='%d-%b %H:%M', fmt_x_data='%d-%b %H:%M', volume=False) # Plot the result if __name__ == '__main__': main()
This is what I get. I only need the smaller timeframe plotted with its indicators. Hope a kind soul can help me out here. Thanks.