For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Execute new Trade(buy/sell) based on the previous Trade value.



  • hi bt community,

    need help pls!
    I was able to execute my first trade (buy when close price is lower than the sma).
    Now, I need to execute my second trade based on the previous trade value.
    I got stuck in the last if statement that is located in the def 'next(self)' of my code:
    if self.dataclose[0] < self.buyprice:

    I am trying to get the buyprice, price for which the buy was executed.
    I red several articles in Backtrader Community about notify_trade or notify_order but reached a dead end due to my poor coding skills :D

    Second questions, lets assume that I executed several buy trades.
    Is there a way to get the average price of these trades while they are still active (not closed)?
    I want to be able to decide my next buy/sell based on the average price. example:

    if self.dataclose[0] > AvgPrice:
        self.sell()
    

    Thx!

    Here is my code for reference:

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    import datetime  # For datetime objects
    import os.path  # To manage paths
    import sys  # To find out the script name (in argv[0])
    import backtrader as bt
    
    
    
    
    class TestStrategy(bt.Strategy):
        params = (('maperiod', 5000),)
    
        def log(self, txt, dt=None):
            # Logging function for this strategy
            dt = dt or self.datas[0].datetime.datetime(0)
            print('%s, %s' % (dt.isoformat(), txt))
    
        def __init__(self):
            # Keep a reference to the "close" line in the data[0] dataseries
            self.dataclose = self.datas[0].close
            self.dataopen = self.datas[0].open
            self.datahigh = self.datas[0].high
            self.datalow = self.datas[0].low
            self.dataVolume = self.datas[0].volume
            self.dataOpenInterest = self.datas[0].openinterest
    
    
            self.sma = bt.indicators.SimpleMovingAverage(self.dataclose, period=self.params.maperiod)
            self.bband = bt.indicators.BBands(self.dataclose, period=self.params.maperiod)
    
    
            self.order = None
            self.buyprice = None
            self.buycomm = None
    
    
    
    
        def notify_order(self, order):
            if order.status in [order.Submitted]:
                # Buy/Sell order submitted/accepted to/by broker - Nothing to do
                self.log('Order submitted to/by broker')
    
            if order.status in [order.Accepted]:
                # Buy/Sell order submitted/accepted to/by broker - Nothing to do
                self.log('Order accepted to/by broker')
    
            # 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():
                    self.log('BUY EXECUTED, Price: %.3f, Cost: %.3f, Comm %.3f' % (order.executed.price,
                                                                                   order.executed.value, order.executed.comm))
                    self.log('@@@@@@@@@@@ Portfolio Value: %.3f' % cerebro.broker.getvalue())
                    self.buyprice = order.executed.price
                elif order.issell():
                    self.log('SELL EXECUTED, %.3f' % order.executed.price)
                    self.log('@@@@@@@@@@@ Portfolio Value: %.3f' % cerebro.broker.getvalue())
    
    
                self.bar_executed = len(self)
    
            elif order.status in [order.Rejected]:
                self.log('Order Rejected')
    
            elif order.status in [order.Canceled]:
                self.log('Order Canceled')
    
            elif order.status in [order.Margin]:
                self.log('Order cancel Margin')
    
    
            print('Buy Price: ', self.buyprice)
    
    
            # Write down: no pending order
            self.order = None
    
        def notify_trade(self, trade):
            '''if not trade.isclosed:
                return'''
    
            self.log('OPERATION PROFIT, GROSS %.3f, NET %.3f' % (trade.pnl, trade.pnlcomm ))
    
    
        def next(self):
    
    
            if self.order:
                self.log('An order is pending ---> we cannot send a 2nd one %.2f' %(self.order))
                return
    
            if not self.position:
    
    
                if self.sma[0] > self.dataclose[0]:
    
    
    
                    self.log('sma: %.2f, bband: %.2f , Close: %.2f   ' % (self.sma[0], self.bband[0], self.dataclose[0]))
                    print('\n')
                    self.log('###################BUY CREATE: %.3f' % self.dataclose[0])
                    order= self.buy(price=self.dataclose[0], size= 2)
                    self.log('order price: %.3f' % order.price)
                    self.log('@@@@@@@@@@@ Portfolio Value: %.3f' % cerebro.broker.getvalue())
    
    
    
    
            '''if self.dataclose[0] < self.buyprice:
                self.log('###################BUY CREATE: %.3f' % self.dataclose[0])
                order1 = self.buy(price=self.dataclose[0], size=1)
                self.log('order price: %.3f' % order1.price)
                self.log('@@@@@@@@@@@ Portfolio Value: %.3f' % cerebro.broker.getvalue())
    
                print('\n')'''
    
    
    if __name__ == '__main__':
    
        cerebro = bt.Cerebro()
        cerebro.addstrategy(TestStrategy)
    
        data = bt.feeds.GenericCSVData(
    
            dataname='USDT_ETH.csv',
            timeframe= bt.TimeFrame.Minutes,
            compression= 5,
    
            fromdate=datetime.datetime(2018, 10, 1),
            todate=datetime.datetime(2019, 12, 14),
    
            nullvalue=0.0,
            #dtformat=('%Y-%m-%d'),
    
            dtformat=('%Y-%m-%d %H:%M:%S'),
            #tmformat=('%H:%M:%S'),
    
            datetime=0,
            time=-1,
            high=1,
            low=2,
            open=3,
            close=4,
            volume=-1,
            openinterest=-1
        )
        cerebro.adddata(data)
    
    
    
        cerebro.broker.setcash(10000.0)
        cerebro.broker.setcommission(commission=0.005)
    
        print('Starting Portfolio Value: %.3f' % cerebro.broker.getvalue())
    
        cerebro.run()
    

  • administrators

    You obviously have a two order Trade (one order opens the trade and another order closes)

    See Docs - Order and the member attribute executed which is of type OrderData.

    By simply referencing order.executed.price, you have the price at which an order actually executed. Save the price in notify_order when you close a trade and you are there.


Log in to reply
 

});