0

Im at the beginning of the learing curve. Already have req historical data downloading req historical data in csv file. I want to keep this process running in the background, updating my historical data in CsV every minute. I would like it to run uninterupped in the backround untill aorted. Now I still have to update it manualy and I would love to automate this to free my mind and hands..... What is missing?

Thank you sincerly...

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract


def print_to_file(*args):
    with open('mnq.CsV', 'a') as fh:
        fh.write(' '.join(map(str,args)))
        fh.write('\n')
        fh.close()
print = print_to_file


class TestApp(EWrapper, EClient):
    def __init__(self):
      EClient.__init__(self, self)

      open('mnq.csv', 'w')
     # Layout = "{!s:1} {!s:2} {!s:3} {!s:4}}  "
     # print(Layout.format("DateTime", "High;", "Close;", "Volume "))

    def historicalData(self, reqId, bar):
          print( bar.date.replace(' ', ''),";", bar.high,";", bar.low,";", bar.volume)

def main():
    app = TestApp()

    app.connect("127.0.0.1", 7497, 0)

    # define MNQ
    contract = Contract()
    contract.symbol = "MNQ"
    contract.secType = "FUT"
    contract.exchange = "GLOBEX"
    contract.currency = "USD"
    contract.lastTradeDateOrContractMonth = "202103"

    app.reqHistoricalData(1, contract, "", "86400 S", "1 min", "TRADES", 0, 1, False, [])

    app.run()

if __name__ == "__main__":
    main()


This is my latest code. questionmark for me what comes in def historicalDataUpdate(self, reqId, bar): for only handeling csv ???????

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
#import pandas as pd

class MyWrapper(EWrapper):
    def __init__(self):
        open('mnq.csv', 'w')
        self.data = []
        self.df=None

    def nextValidId(self, orderId: int):
        print("Setting nextValidOrderId: %d", orderId)
        self.nextValidOrderId = orderId
        self.start()

    def historicalDataUpdate(self, reqId, bar):
       ???????

    def error(self, reqId, errorCode, errorString):
        print("Error. Id: ", reqId, " Code: ", errorCode, " Msg: ", errorString)

    open('mnq.csv', 'w')

    def print_to_file(*args):
        with open('mnq.csv', 'a') as fh:
            fh.write(' '.join(map(str, args)))
            fh.write('\n')
            fh.close()
    print = print_to_file

def  start(self):

    wrap = MyWrapper()
    app  = EClient(wrap)
    app.connect("127.0.0.1", 7497, 0)

    # define MNQ
    contract = Contract()
    contract.symbol = "MNQ"
    contract.secType = "FUT"
    contract.exchange = "GLOBEX"
    contract.currency = "USD"
    contract.lastTradeDateOrContractMonth = "202103"

    app.reqHistoricalData(1, contract, "", "86400 S", "1 min", "TRADES", 0, 1, True, [])

   # print(wrap.df)
   # wrap.df.to_csv("mnq.csv")
    app.disconnect()

Zostrak
  • 1
  • 1
  • I wrote an answer that does what you want by using keepUpToDate = True. https://stackoverflow.com/a/62800202/2855515 – brian Feb 17 '21 at 17:07
  • Did you forget `def historicalDataUpdate` – brian Feb 17 '21 at 21:30
  • Brain, have set KeepUpToDate = True, app keeps running but after first print in CSV no update prices printed in CSV. What to do to completely rewrite and then update the CVS with only the most recent 1440 minutes ? – Zostrak Feb 17 '21 at 21:32
  • If upToDate is set then you need to implement `def historicalDataUpdate`, note it is not the same method as `def historicalData` – brian Feb 17 '21 at 22:17

1 Answers1

0

If you want to save data continuously instead of keeping it in a data frame then the logic a bit different.

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract

from time import time, ctime

class MyWrapper(EWrapper):
    def __init__(self):
        self.bars = {} # store in a dict(map) with date->bar so you can overwrite same date 

    def nextValidId(self, id):
        self.start = time()
        print(ctime(self.start))
        # this is when IB recommends starting requests
        reqData()

    def error(self, reqId, errorCode, errorString):
        # always print errors and turn on api logging in TWS
        print("Error. Id: " , reqId, " Code: " , errorCode , " Msg: " , errorString)

    def print_to_file(self):
        with open('mnq.csv', 'a') as fh:
            for val in self.bars.values():
                fh.write("%s,%f,%f,%d\n" % (val.date, val.high, val.low, val.volume))
                
        self.bars.clear()
        
    def historicalData(self, reqId, bar):
        self.bars[bar.date] = bar #the last one will be incomplete
        
    def historicalDataEnd(self, reqId: int, start: str, end: str):
        pass  #can't write yet since last bar is incomplete
        
    def historicalDataUpdate(self, reqId, bar):
        if not self.bars.get(bar.date): 
            self.print_to_file() # a new bar has arrived so last bar is finished
            
        self.bars[bar.date] = bar # now there is only ever one bar in dict
        
        # decide when to quit, a timer would be better
        if time() - self.start > 30:
            app.disconnect()
        
wrap = MyWrapper()
app  = EClient(wrap)
def reqData():
    # define MNQ
    contract = Contract()
    contract.symbol = "MNQ"
    contract.secType = "FUT"
    contract.exchange = "GLOBEX"
    contract.currency = "USD"
    contract.lastTradeDateOrContractMonth = "202103"

    # use dateformat 2 for UTC.  Always store UTC on disk.
    app.reqHistoricalData(1, contract, "", "100 S", "5 secs", "TRADES", 0, 2, True, [])

app.connect("127.0.0.1", 7497, 123)
app.run() # blocks until disconnect()

app.disconnect() #never gets called
brian
  • 10,619
  • 4
  • 21
  • 79
  • Thank you Brian Im looking aat and playing with your ART as I write, You helped me a lot with this. I may have some questions but for now I will play with your brainchild – Zostrak Feb 18 '21 at 17:05
  • I get data but also an errors some running,: unhandled exception in EReader thread Traceback (most recent call last) File"C:\TWSAPI\source\pythonclient\ibapi\reader.py", line 34, in run data = self.conn.recvMsg() File "C:\TWS API\source\pythonclient\ibapi\connection.py", line 99, in recvMsg buf = self._recvAllMsg() File "C:\TWS API\source\pythonclient\ibapi\connection.py", line 119, in _recvAllMsg buf = self.socket.recv(4096) OSError: [WinError 10038] Er is geprobeerd een bewerking uit te voeren op iets anders dan een socket Process finished with exit code 0 – Zostrak Feb 18 '21 at 17:15
  • The file doesnt update, its stops recieving data after 26 lines , 6 more than the first batch of 20* 5 seconds( is 100), so the program gets halted. Is there a way to recieve 1440 * 1minutes , pauze the program and restart program and rewrite cvs file with most recent 1440 times 1 minute. This is what i realy want – Zostrak Feb 18 '21 at 20:37
  • I dont care so muttch about last minute if thats complete or not its the 1440 completed minutes that i wish to extract afresh true automationduring in the back ground during the day – Zostrak Feb 18 '21 at 20:40
  • I used numbers for testing like 100 seconds of history of 5 sec bars. I set it to disconnect after 30 seconds. Read the code and study up on python for what you don't understand. – brian Feb 18 '21 at 21:58