Skip to content

Latest commit

 

History

History
546 lines (222 loc) · 10.7 KB

python-script-to-place-order-on-interactive-brokers.md

File metadata and controls

546 lines (222 loc) · 10.7 KB

Python script to place order on Interactive Brokers | Start Chat

Python script to place order on Interactive Brokers by taking the values from trading view indicator

Prompt

write a python program to take a webhook from trading view in this format

{"Action": "Buy", "Ticker": "AAPL", "Price": 370}

and place an order on Interactive Brokers. Take relevant values from the webhook and place the order with 30% of the account balance

Welcome Message

Here's an example Python program that uses Flask to receive a webhook from TradingView, and places an order on Interactive Brokers using 30% of the account balance:

from flask import Flask, request

from ibapi.client import EClient

from ibapi.wrapper import EWrapper

from ibapi.contract import Contract

from ibapi.common import *

from ibapi.order import *



class IBAPIClient(EWrapper, EClient):

    def __init__(self):

        EClient.__init__(self, self)

        self.nextOrderId = None



    def nextValidId(self, orderId: int):

        super().nextValidId(orderId)

        self.nextOrderId = orderId



    def placeOrder(self, contract: Contract, order: Order):

        self.placeOrder(self.nextOrderId, contract, order)

        self.nextOrderId += 1



app = Flask(__name__)



@app.route('/webhook', methods=['POST'])

def webhook():

    data = request.json

    action = data['Action']

    ticker = data['Ticker']

    price = float(data['Price'])



    # Connect to IB TWS or Gateway

    client = IBAPIClient()

    client.connect('127.0.0.1', 4002, clientId=0)



    # Get account balance

    account_data = []

    class AccountInfo(EWrapper, EClient):

        def __init__(self):

            EClient.__init__(self,self)

        def error(self, reqId:TickerId, errorCode:int, errorString:str):

            print("Error:",reqId,"Code:",errorCode,"Msg:",errorString)

        def updateAccountValue(self, key:str, val:str, currency:str, accountName:str):

            account_data.append((key,val))

    ai = AccountInfo()

    client.reqAccountSummary(9001, "All", "$LEDGER")

    while len(account_data) == 0:

        client.run()

    account_balance = float(dict(account_data)['TotalCashValue'])



    # Calculate order quantity

    order_quantity = int((account_balance * 0.3) / price)



    # Create contract object for the specified ticker

    contract = Contract()

    contract.symbol = ticker

    contract.secType = 'STK'

    contract.exchange = 'SMART'

    contract.currency = 'USD'



    # Create a limit order

    order_type = 'BUY' if action.upper() == 'BUY' else 'SELL'

    limit_order = LimitOrder(order_type, order_quantity, price)



    try:

        # Place the order

        client.placeOrder(contract, limit_order)

    except Exception as e:

        # Handle any errors that occur during the order placement process

        print(f'Error placing order: {e}')



    # Disconnect from IB TWS or Gateway

    client.disconnect()



    return 'OK'



if __name__ == '__main__':

    app.run()

This program receives the webhook request, extracts the Action, Ticker, and Price fields from the JSON payload, creates a contract object for the specified ticker, calculates the order quantity based on 30% of the account balance and the specified price, creates a limit order using the specified action, quantity, and price, and then places the order on Interactive Brokers. Finally, it returns an HTTP response indicating success by returning the string 'OK'.

Note that you'll need to have an active connection to the IB TWS or Gateway in order to place orders. Additionally, this program doesn't handle any error cases that may occur during the order placement process, so you may want to add additional error handling to make it more robust.

Conversation

ASSISTANT: Here's an example Python program that uses Flask to receive a webhook from TradingView, and places an order on Interactive Brokers using 30% of the account balance:

from flask import Flask, request

from ibapi.client import EClient

from ibapi.wrapper import EWrapper

from ibapi.contract import Contract

from ibapi.common import *

from ibapi.order import *



class IBAPIClient(EWrapper, EClient):

    def __init__(self):

        EClient.__init__(self, self)

        self.nextOrderId = None



    def nextValidId(self, orderId: int):

        super().nextValidId(orderId)

        self.nextOrderId = orderId



    def placeOrder(self, contract: Contract, order: Order):

        self.placeOrder(self.nextOrderId, contract, order)

        self.nextOrderId += 1



app = Flask(__name__)



@app.route('/webhook', methods=['POST'])

def webhook():

    data = request.json

    action = data['Action']

    ticker = data['Ticker']

    price = float(data['Price'])



    # Connect to IB TWS or Gateway

    client = IBAPIClient()

    client.connect('127.0.0.1', 4002, clientId=0)



    # Get account balance

    account_data = []

    class AccountInfo(EWrapper, EClient):

        def __init__(self):

            EClient.__init__(self,self)

        def error(self, reqId:TickerId, errorCode:int, errorString:str):

            print("Error:",reqId,"Code:",errorCode,"Msg:",errorString)

        def updateAccountValue(self, key:str, val:str, currency:str, accountName:str):

            account_data.append((key,val))

    ai = AccountInfo()

    client.reqAccountSummary(9001, "All", "$LEDGER")

    while len(account_data) == 0:

        client.run()

    account_balance = float(dict(account_data)['TotalCashValue'])



    # Calculate order quantity

    order_quantity = int((account_balance * 0.3) / price)



    # Create contract object for the specified ticker

    contract = Contract()

    contract.symbol = ticker

    contract.secType = 'STK'

    contract.exchange = 'SMART'

    contract.currency = 'USD'



    # Create a limit order

    order_type = 'BUY' if action.upper() == 'BUY' else 'SELL'

    limit_order = LimitOrder(order_type, order_quantity, price)



    try:

        # Place the order

        client.placeOrder(contract, limit_order)

    except Exception as e:

        # Handle any errors that occur during the order placement process

        print(f'Error placing order: {e}')



    # Disconnect from IB TWS or Gateway

    client.disconnect()



    return 'OK'



if __name__ == '__main__':

    app.run()

This program receives the webhook request, extracts the Action, Ticker, and Price fields from the JSON payload, creates a contract object for the specified ticker, calculates the order quantity based on 30% of the account balance and the specified price, creates a limit order using the specified action, quantity, and price, and then places the order on Interactive Brokers. Finally, it returns an HTTP response indicating success by returning the string 'OK'.

Note that you'll need to have an active connection to the IB TWS or Gateway in order to place orders. Additionally, this program doesn't handle any error cases that may occur during the order placement process, so you may want to add additional error handling to make it more robust. USER: Include doc strings in the code ASSISTANT: Here's an updated version of the code that includes docstrings to explain what each class and function does, as well as what inputs they expect and what outputs they produce:

from flask import Flask, request

from ibapi.client import EClient

from ibapi.wrapper import EWrapper

from ibapi.contract import Contract

from ibapi.common import *

from ibapi.order import *



class IBAPIClient(EWrapper, EClient):

    """Class that handles messages from the Interactive Brokers API."""



    def __init__(self):

        """Initialize the class."""

        EClient.__init__(self, self)

        self.nextOrderId = None



    def nextValidId(self, orderId: int):

        """Handler for the 'next valid order ID' message."""

        super().nextValidId(orderId)

        self.nextOrderId = orderId



    def placeOrder(self, contract: Contract, order: Order):

        """Place an order using the Interactive Brokers API."""

        self.placeOrder(self.nextOrderId, contract, order)

        self.nextOrderId += 1



app = Flask(__name__)



@app.route('/webhook', methods=['POST'])

def webhook():

    """

    Handle incoming webhooks from TradingView.



    Expects a JSON payload with the following fields:

    - Action: "BUY" or "SELL"

    - Ticker: The symbol of the security to trade (e.g. "AAPL")

    - Price: The price at which to buy/sell the security

    """



    data = request.json

    action = data['Action']

    ticker = data['Ticker']

    price = float(data['Price'])



    # Connect to IB TWS or Gateway

    client = IBAPIClient()

    client.connect('127.0.0.1', 4002, clientId=0)



    # Get account balance

    account_data = []

    class AccountInfo(EWrapper, EClient):

        def __init__(self):

            EClient.__init__(self,self)

        def error(self, reqId:TickerId, errorCode:int, errorString:str):

            print("Error:",reqId,"Code:",errorCode,"Msg:",errorString)

        def updateAccountValue(self, key:str, val:str, currency:str, accountName:str):

            account_data.append((key,val))

    ai = AccountInfo()

    client.reqAccountSummary(9001, "All", "$LEDGER")

    while len(account_data) == 0:

        client.run()

    account_balance = float(dict(account_data)['TotalCashValue'])



    # Calculate order quantity

    order_quantity = int((account_balance * 0.3) / price)



    # Create contract object for the specified ticker

    contract = Contract()

    contract.symbol = ticker

    contract.secType = 'STK'

    contract.exchange = 'SMART'

    contract.currency = 'USD'



    # Create a limit order

    order_type = 'BUY' if action.upper() == 'BUY' else 'SELL'

    limit_order = LimitOrder(order_type, order_quantity, price)



    try:

        # Place the order

        client.placeOrder(contract, limit_order)

    except Exception as e:

        # Handle any errors that occur during the order placement process

        print(f'Error placing order: {e}')



    # Disconnect from IB TWS or Gateway

    client.disconnect()



    return 'OK'



if __name__ == '__main__':

    app.run()

The docstrings explain what each class and function does, as well as what inputs they expect and what outputs they produce. They also provide a description of the expected JSON payload format for incoming TradingView webhooks. Docstrings are an important part of writing clear, maintainable code as they make it easier for other developers (and yourself in the future) to understand what the code does without having to read through every line of code.