Backtrader Community

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Live Trading / Ibbroker / Load Trades at start

    General Code/Help
    3
    4
    472
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Alexandre Durand
      Alexandre Durand last edited by

      Hi,

      I use Backtrader in live mode with IB.

      Each time cerebro start, the trades are not initialized. So when the strategy place an order a new trade will be open.

      Is there a way to initialized the trades with the position already open ?

      Thanks for the help.

      Alexandre


      Alex

      1 Reply Last reply Reply Quote 0
      • A
        ab_trader last edited by

        By default bt works only with positions open by itself. You can search for discussions on this topic on the forum, maybe somebody already implemented this.

        • If my answer helped, hit reputation up arrow at lower right corner of the post.
        • Python Debugging With Pdb
        • New to python and bt - check this out
        1 Reply Last reply Reply Quote 0
        • Alexandre Durand
          Alexandre Durand last edited by

          My goal is to load the positions open by backtrader in a previous run/session.
          The previous positions are also opened by bt.
          But the previous trades are not recognized by bt as "bt position".

          Thanks for the help,


          Alex

          mics 1 Reply Last reply Reply Quote 0
          • mics
            mics @Alexandre Durand last edited by

            @Alexandre-Durand

            I have a system that provides some functionality that you are after by storing all critical variables, trade data, account data in an *.ini file which is updated on each loop of next(). While this is not exactly what you might be after, it may overcome your problem until a better solution can be found.

            How my system works on initial start:

            • Parent program
              • Creates *.ini file
              • Runs BT as subprocess
              • BT starts normally

            When connection fails

            • notify_store receives error
            • wait for connection to be restored (but BT does not resume)
              • send sms alerting me of restart
              • try send close position and try cancel stop loss (if any are open). API still receives these commands even when BT cannot resume.
              • runstop BT
            • write variable to ini file signalling shutdown (this is for the parent program to read and action)

            When shutdown recognised by parent program

            • kill BT
              -reload BT

            When BT reloads

            • check if fresh start or reload.
              • If reload, then init with variables from last loop of next() prior to shutdown
              • If fresh start, init with normal defaults
              • [Option here to recreate the positions that had to been closed when BT failed so that the strategy can continue depending on how much time and price has moved]

            Here is some sample code:

            NOTIFY_STORE

            def notify_store(self, msg, *args, **kwargs):
            
                print('*' * 5, 'STORE NOTIF:', msg)
                
                try:
                    if 'external transaction MARKET_ORDER' in msg:
                        print('msg = external transaction')
                        
                        self.hitstoploss = 0
                        
                        try:
                            cancel = self.cancel(self.stop_ord) #CANCEL STOP LOSS
                            print('CANCEL STOP LOSS')
                            return
                            
                        except AttributeError:
                            print('NO STOP LOSS TO CANCEL')
                            return
                            
                        else:
                        
                            print('NOT SURE IF STOP LOSS CURRENTLY OPEN')
                            try:
                                message = SendSMS.client.messages.create(
                                    from_='+xxxxxxxxxx',
                                    to='+xxxxxxxxxx',
                                    body=(self.productcode + ' FAILED TO CANCEL STOP LOSS: CHECK ON PLATFORM'))
                            except:
                                pass
                            return
            
                except:
                        
                    print('CONNECTION FAILED')
                    
                    print('SEND SMS')
                                
                    x = 1
                    while True: #IF INTERNET CONNECTION DOWN. WAIT UNTIL ABLE TO SEND SMS BEFORE COMMENCING RELOAD
                        try:
                            
                            message = SendSMS.client.messages.create(
                                from_='+xxxxxxxxxx',
                                to='+xxxxxxxxxx',
                                body=('SHUT DOWN: CLOSING POSITIONS & RELOADING'))
            #                        body=(self.productcode + ' SHUT DOWN: CLOSING POSITIONS & RELOADING: {}'.format(msg)))
            
                            print('SMS SENT')
                            break
                        except:
                            print('!!! CONNECTION BROKEN !!! - FAILED TO SEND SMS. RETRYING #' + str(x))
                            time.sleep(2)
                            x = x + 1
                            pass
                    
                    print('GET POSITION SIZE FROM INI FILE')
                    #READ INI TO GET POSTION SIZE. CANNOT GET POSITION SIZE FROM BROKER IF CONNECTION INTERUPTED
                    bt_file.read_trade_ini(self)
                    time.sleep(2)
                    print('INI FILE READ')
                    print('POSITION SIZE: ' + str(self.position_size)) #self.position_size IS READ FROM THE INI FILE AND GETS UPDATED ON EACH next()
                   
                    print('TRY TO CLOSE POSITION')
                    time.sleep(10)
                    try:
                       self.close(size=self.position_size) #SEND A CLOSE ORDER. THIS WILL WORK IF API CONNECTION RE-ESTABLISHED, EVEN IF BT HAS STALLED
                    except:
                        pass
            #            time.sleep(2)
                    print('POSITION CLOSED. TRY TO CANCEL STOP LOSS')
                    try:
                        self.cancel(self.stop_ord) #SEND A CANCEL STOP LOSS ORDER. THIS WILL WORK IF API CONNECTION RE-ESTABLISHED, EVEN IF BT HAS STALLED
                    except:
                        pass
                    print('CANCEL STOP LOSS')
            
                    time.sleep(2)
                    bt_file.reload_write(self)    #CREATE SHUTDOWN TRIGGER IN INI FILE FOR PARENT PROGRAM TO RECEIVE
                    time.sleep(2)
                    print('STOPPING BACKTRADER')
                    self.env.runstop()  #SHUT DOWN BACKTRADER
                    time.sleep(1)
                    press('enter')  #MUST KEEP CURSOR ACTIVE ON THE TERMINAL FOR THIS TO WORK
                    return
            

            PARENT PROGRAM

            
            ***FRESH START***
            
                #----- ESTABLISH INI FILE -----#
            
                config = configparser.ConfigParser()
                home = os.path.expanduser('~') #USER DIRECTORY
                filename = pc + '.ini'
                
                if not os.path.exists(home + '/00_config/' + filename):
                    print('CREATING NEW INI FILE')
                    f = open(home + '/00_config/' + filename, 'w')
                else:
                    print('EXISTING INI FILE')
                    pass
                
                myfile = Path(home + '/00_config/' + filename)
                
                config.read(myfile)
                section_00 = pc
                section_01 = pc + '-01'
                section_02 = pc + '-02'
                
                time.sleep(1)
                
                #----- CLEAR INI FILE -----#
                print('PREPARING INI FILE')
                with open(myfile,'r+') as s:
                    config.read_file(s)
                    config.remove_section(section_00)
                    config.remove_section(section_01)
                    config.remove_section(section_02)
                    s.seek(0)
                    config.write(s)
                    s.truncate()
                    
                time.sleep(1)
                #----- CREATE RELOAD SECTIONS IF THEY DO NOT EXIST -----#
                try:
                    config.get(section_01, 'override')
                except:
            #    except configparser.NoSectionError:
                    config.add_section(section_01)   #ADD NEW SECTION
                
                #CREATE ACCOUNT SECTION IF IT DOES NOT EXIST
                try:
                    config.get(section_02, 'account')
                except:
            #    except configparser.NoSectionError:
                    config.add_section(section_02)
                    
                #CREATE TRADE DATA SECTION IF IT DOES NOT EXIST
                try:
                    config.get(pc, 'tradeid')
                except:
            #    except configparser.NoSectionError:
                    config.add_section(pc)
                
                #----- RELOAD DEFAULT VALUES -----#
                config.set(section_01, 'override','0')
                config.set(section_01, 'reload','0')
                config.set(section_02, 'account','0')
                config.write(myfile.open('w'))
            
              
                #----- LOAD CEREBRO -----#
                cerebro(pc) #LOADS BT ('pc' refers to product code that is passed to BT from the parent)
            
            ***LOOP CHECKS ON INI FILE***
            
                while True:
            
            #----- CONNECTION FAILURE - RELOAD -----#
            
                    config.read(myfile)
                    reload_sc = config.get(section_01,'reload')
            
                    if reload_sc == 'SHUTDOWN': #IF INI FILE SAYS 'SHUTDOWN' (WHICH IS SET BY NOTIFY_STORE), THEN...
                    
                        print('KILL CEREBRO')
                        #use to have a kill.subprocess command in here but it seemed redundant but might be useful if running multiple instances on one machine
                        time.sleep(1)
                        print('RELOAD CEREBRO')
                        time.sleep(2)
                        cerebro(pc)
            
                    else:
                        pass
            
            

            BT

            ***FRESH START***
            
            def __init__():
            
                    ini_transfer.reload_read(self) #Loads ini file
            
                    if self.reload_sc == 'SHUTDOWN': #If reloaded set as'SHUTDOWN' then init with last values, not default
                        ini_transfer.read_restart_data(self) 
                    else:
                        vars(self) #This is just a method contain a group of variables
            
            

            SAMPLE CODE FROM INI_TRANSFER

                def read_restart_data(self):
                    args = parse_args()
                    config = configparser.ConfigParser()
                    home = os.path.expanduser('~')
                    myfile = Path(home + '/00_config/' + args.data0 + '.ini')
                    config.read(myfile) #path of your .ini file
                    
                    self.tradeid = config.get(args.data0,'tradeid')
                    self.position_size = float(config.get(args.data0,'position_size'))
                    self.freezebar = float(config.get(args.data0,'freezebar'))
                    self.enter_price = float(config.get(args.data0,'enter_price'))
                    self.retracement = float(config.get(args.data0,'retracement'))
                    self.hitstoploss = int(config.get(args.data0,'hitstoploss'))
                    self.high_2 = float(config.get(args.data0,'high_2'))
                    self.low_2 = float(config.get(args.data0,'low_2'))
                    self.high_3 = float(config.get(args.data0,'high_3'))
                    self.pos_long = int(config.get(args.data0,'pos_long'))
                    self.pos_short = int(config.get(args.data0,'pos_short'))
                    self.stop_position = float(config.get(args.data0,'stop_position'))
                    self.trend_backflip = float(config.get(args.data0,'trend_backflip'))
                    self.trend_exit_trigger = float(config.get(args.data0,'trend_exit_trigger'))
                    self.false_signal = float(config.get(args.data0,'false_signal'))
                    self.RTH = int(config.get(args.data0,'RTH'))
                    self.trend_exit_price = float(config.get(args.data0,'trend_exit_price'))
                    self.break_out_long = float(config.get(args.data0,'break_out_long'))
                    self.break_out_short = float(config.get(args.data0,'break_out_short'))
            
            

            Perhaps some of this might assist you with new ideas to tackle your problem.

            Also appreciate if anyone has ideas on how to improve or simplify this?

            Not being from a coding background, I am making this up as I go. No doubt there are more efficient ways of achieving some of the things I am doing.

            1 Reply Last reply Reply Quote 1
            • 1 / 1
            • First post
              Last post
            Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors