0

I am trying to download historical data from the IBAPI, and since I am not that savvy in coding I came up with the plan to write seperate files for each stock that I want data of, and let 1 main file run all those files. The problem is that I can only request 1 stock every time, so after the first one has finished downloading I want the main file to run the next program.

I have tried multiple different things the past few days but I am unable to get it to work because for some reason Python does not kill the first script.

What I have tried so far:

import AAPL
import GOOG
import sys
import sleep

AAPL.main()
time.sleep(10)
sys.exit(AAPL)
GOOG.main()


And a few different variations with functions such as

terminate, kill()

the weird thing is that, when i try the first line of code i shared, but replace

AAPL.main() & GOOG.main()

with

print("Running") & print("terminate")

I do receive "terminte" as result, which is not the case with GOOG.main()

Could anyone help me with this issue?

EDIT: Code of AAPL.py, is same as GOOG.py:

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

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


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


    Layout = "{!s:1} {!s:2} {!s:3} {!s:4} {!s:5} {!s:6} {!s:7} {!s:8} {!s:8} '\n'"
    print(Layout.format("Ticker;", "Date;", "None;", "Time;", "Open;", "High;", "Low;", "Close;", "Volume"))


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


def main():
    app = TestApp()

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

    contract = Contract ()
    contract.symbol = "AAPL"
    contract.secType = "STK"
    contract.exchange = "SMART"
    contract.currency = "USD"
    contract.primaryExchange = "NASDAQ"

    app.reqHistoricalData(0, contract, "20180201 10:00:00", "1 D", "1 min", "TRADES", 0, 1, False, [])

    app.run()

if __name__ == "__main__":
    main()

Running this as a standalone will give me the required result for just this stock, but because it does not stop the function after a few seconds it does not work when I try to run multiple

Hoogoo
  • 15
  • 1
  • 8
  • Everything depends on that the `main` functions look like. If the `AAPL.main()` doesn't return _by its own_, you won't be able to do anything with it in a single-threaded setup. – ForceBru May 10 '19 at 13:56
  • maybe the main function in your AAPL and GOOG doesn't return at all. provide us the main code of those two files. or just use thread, because threads can run simultaneously. – shadow May 10 '19 at 14:08
  • Thank you for your answer, i will update my post and add the AAPL file, which is the same as GOOG – Hoogoo May 10 '19 at 14:14
  • I have updated my post, it now contains my code. Do I have to replace my main with thread, or in the file where I want to try to run everything from? – Hoogoo May 10 '19 at 14:34

2 Answers2

1

try this:

from multiprocessing import Process
import AAPL
import GOOG

if __name__ == "__main__":
    print("run AAPL")
    proc1 = Process(target = AAPL.main())
    proc1.start()
    print("run GOOG")
    proc2 = Process(target = GOOG.main())
    proc2.start()
shadow
  • 767
  • 3
  • 8
  • 20
  • Unfortunately this does not work, it creates 2 new files at the same time (AAPL & GOOG), and than it runs AAPL (also says"run AAPL", but it does not kill "AAPL" en therefore does not start "GOOG" (also does NOT say "run GOOG"). Even if I add sleep(10) and/or sys.exit() – Hoogoo May 10 '19 at 14:28
  • i'm not familiar with IB API but after some research. calling app.run() will start a loop() which mean it will never stop. so using one process to call both files will not help because you will not be able to run the next statement unless you stop the one is running. that's why i suggested to you to use multi-thread. and of course it will create 2 files because both functions are running. and it doesn't need to kill AAPL.main() to start the GOOG.main(), both of them must run together. – shadow May 10 '19 at 14:47
  • and about how you stop AAPL or GOOG, you need to check the IB API documentation, maybe you don't need to use the app.run() (in AAPI or GOOG file) maybe they are another way to do what you trying to do, – shadow May 10 '19 at 14:48
  • as far as i have read. you can create a class call AAPI and run it as a thread this call a thread object. instead of using AAPI.main() to call a function from your AAPL file. create a class AAPL and write your code that will run the main in a run function then use a thread to run your AAPL object. and if you want to kill that thread or stop it, just call a stop function. you need to check out how to create a thread object to know what i'm talking about. i guess it's the right way to do what you are trying to do. – shadow May 10 '19 at 14:55
  • Thanks for all the research man, I will try it all out! ill report back when I know more – Hoogoo May 10 '19 at 15:02
  • @shadow the IB API does not play well with multiprocessing. In your scenario it will try a connection on the same port with same id, it will fail. – misantroop May 10 '19 at 22:10
  • you are right, you can't connect at the same time using the same port. as i said, i can't help you much about this API. but have a look at those 2 links: https://stackoverflow.com/questions/45793114/how-to-get-series-of-requests-in-ibapi-on-python https://groups.io/g/twsapi/topic/python_api_how_do_add/4968379?p=,,,20,0,0,0::recentpostdate%2Fsticky,,,20,2,20,4968379 – shadow May 10 '19 at 22:42
0

This should be enough.

import AAPL
import GOOG

AAPL.main()
time.sleep(10) # not mandatory, could be eliminated
GOOG.main()

sys.exit will exit the execution of the current python, which will not allow GOOG.main() to execute.

bracco23
  • 2,181
  • 10
  • 28
  • Thank you for your comment, unfortunately this does not work for some reason, if I do that with print(text) it does work, bet when I use AAPL.main() it does not – Hoogoo May 10 '19 at 14:15
  • What is the comment of the two main functions? what do they exactly do? – bracco23 May 10 '19 at 14:23
  • The main functions retreive data from an API and store it to a .txt file – Hoogoo May 10 '19 at 14:24