I have no idea where I should be asking this question, it seems like a very niche problem.

Here is my issue. I have been running a python script to run trades on interactive brokers using the tws api. I use python.

It works completely fine when I login to my linux server using ssh and manually type and run python3 trade.py. The program runs from start to finish and prints out trades complete. I can login to the trader workstation and see that the orders exist.

My script places trade orders and it looks like this and its named trade.py.

from ibapi.utils import iswrapper

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

from ibapi.common import *  # @UnusedWildImport
from ibapi.account_summary_tags import AccountSummaryTags
from ibapi.contract import * # @UnusedWildImport
from ibapi.order import Order
from ibapi.order_state import OrderState
from ibapi.order_condition import TimeCondition
from Testbed.OrderSamples import OrderSamples as ordsam
from Testbed.AvailableAlgoParams import AvailableAlgoParams as algo

class ib_class(EWrapper, EClient):
    error_message = None
    def __init__(self, addr, port, client_id):
        EClient.__init__(self, self)

        self.connect(addr, port, client_id) # Connect to TWS
        thread = Thread(target=self.run)  # Launch the client thread
        thread.start()

        self.all_accounts = pd.DataFrame([], columns = ['reqId', 'Account', 'Tag', 'Value', 'Currency'])

        self.open_positions = pd.DataFrame([], columns = ['Account','Symbol', 'Quantity', 'Average Cost', 'Sec Type', 'Exchange', 'Currency'])

        self.open_orders = pd.DataFrame([], columns = ["PermId", "ClientId", " OrderId",
                  "Account", "Symbol", "SecType", "Exchange", "Action", "OrderType",
                  "TotalQty", "CashQty", "LmtPrice", "AuxPrice", "Status"])
        self.permId2ord = {}

        self.nextValidOrderId = None

    def error(self, reqId:TickerId, errorCode:int, errorString:str, advancedOrderRejectJson = ""):
        super().error(reqId, errorCode, errorString, advancedOrderRejectJson)
        if advancedOrderRejectJson:
            print("Error. Id:", reqId, "Code:", errorCode, "Msg:", errorString, "AdvancedOrderRejectJson:", advancedOrderRejectJson)
        else:
            print("Error. Id:", reqId, "Code:", errorCode, "Msg:", errorString)
        self.error_message = [reqId, errorCode, errorString]\
        

        if errorCode == 504:
            self.disconnect()
            sys.exit()

def run_loop():
    app.run()

app = ib_class("127.0.0.1", 1234, 1)

api_thread = threading.Thread(target=run_loop, daemon=True)
api_thread.start()


for ticker, stats in portfolio.items():
    bracket = app.BracketOrder(parentOrderId=app.nextOrderId(), openinglimitPrice=stats["price"], quantity=stats['quantitychange'])
    for o in bracket:
        app.placeOrder(o.orderId, app.equity(ticker), o)
        app.nextOrderId()
app.disconnect()
print('trades complete')

However, if I try to automate it from another linux server called the main server which controls the trades server. No trades are made. I have tried asyncssh, paramiko and subprocesses (ssh), the script runs and prints "trades complete", however no orders are placed at all.

My command looks something like this,

# Server2 details
hostname = 'xxx'
username = 'xxx'
private_key_path = 'xxx' 

# Command to run on Server2
command = ['python3 /home/ubuntu/scripts/trade.py']

# the SSH command
ssh_command = [
    'ssh',
    '-i', private_key_path,
    '-o', 'StrictHostKeyChecking=no',
    '-o', 'UserKnownHostsFile=/dev/null',
    f'{username}@{hostname}',
    *command
]

subprocess.run(ssh_command)

I don't understand why this is happening. I am not sure if this is an issue with linux or my script or some versioning issue.

The python script is also remotely executing other python scripts and shell scripts using ssh within the script and they all work totally fine. The problem only happens when I try to run this particular trade script.

Any ideas?

0

There are 0 best solutions below