Blog · Python trading bots

How to build a trading bot in Python

If you can write your trading rules down clearly enough to explain them to a colleague, you can automate them. Python is the language most people reach for to do it, and it's a good choice. The data libraries are mature, most brokers have a usable API, and the code stays readable when you come back to it months later.

This is the whole path, start to finish: writing your rules down, pulling in market data, testing against history, and finally placing real orders through a broker. We build systems like this for a living, so along the way we'll point out the parts that look trivial in a tutorial and turn out to be where live trading actually breaks.

One thing up front. This is a technology guide. Trade Vectors builds trading software to a strategy you supply and control. We don't give trading advice, we don't hand out strategies or signals, and we make no claim about what any strategy will earn. The RSI example below is a well-known teaching example, used to show the mechanics. It is not a recommendation to trade it.

What a trading bot actually is

A trading bot is just a program that places buy and sell orders for you, following rules you've written down in advance, without you sitting there clicking. That's the whole idea. Its value isn't magic. It's discipline and speed. It does exactly what the rules say, every time, without second-guessing itself at 2pm, and it can watch far more instruments than you can.

It also does exactly what the rules say when the rules are wrong, at full speed, without flinching. That cuts both ways, which is why most of this guide is about testing and risk rather than the fun part of placing orders. Automated trading is a large and growing share of volume on exchanges like the NSE, and the tooling to do it well has never been more accessible.

What you'll need

A recent Python (3.9 or newer) and a handful of libraries do most of the work:

  • pandas, handling price data and time series
  • numpy, the numerical work underneath
  • yfinance, free historical data to get started
  • requests / websocket-client, talking to REST and streaming APIs
  • ib_insync, a friendly wrapper for the Interactive Brokers API
  • kiteconnect, Zerodha's Kite API, for Indian markets

Install the essentials to follow along:

pip install pandas numpy yfinance requests

Step 1: Write your strategy down

Before a single line of code, you need answers to plain questions. What are you trading? On what timeframe? What has to be true for you to enter, and what gets you out? How much are you willing to lose on one trade, and where's the stop? If you can't answer those in one or two sentences each, the bot isn't the problem yet. The strategy is.

For this guide we'll use a simple, textbook example so the code has something to do: a plain RSI mean-reversion rule. Buy when the 14-period RSI drops below 30, sell when it climbs back above 70. It's one of the first things people automate because it's easy to state. Whether it's any good is a separate question, and not one this article answers. The point is the machinery around it, which is the same whatever your actual rules are.

Step 2: Get the market data

Your bot needs history to test against and live prices to act on. yfinance is the quickest way to get free daily data while you're building:

import yfinance as yf

# One year of daily bars for Apple
data = yf.download("AAPL", period="1y", interval="1d")
print(data.tail())
# columns: Open  High  Low  Close  Volume

Free end-of-day data is fine for learning and for slower, positional strategies. It is not fine for anything fast. A broker feed at a couple of hundred milliseconds will quietly flatter an intraday backtest and mislead you. For Indian markets you'd move to the Zerodha or Angel One feeds; for global instruments, the Interactive Brokers feed. Getting the right data, and cleaning the gaps and bad ticks that arrive with it, is a real part of the job, and a big part of our broker and data integration work.

Step 3: Turn the rules into signals

With data in hand, you calculate whatever your rules depend on and mark each bar as buy, sell or do-nothing. Here's the RSI and a signal column:

import pandas as pd

def rsi(close, period=14):
    delta = close.diff()
    gain = delta.clip(lower=0)
    loss = -delta.clip(upper=0)
    avg_gain = gain.rolling(period).mean()
    avg_loss = loss.rolling(period).mean()
    rs = avg_gain / avg_loss
    return 100 - (100 / (1 + rs))

data["RSI"] = rsi(data["Close"])

# Turn your rules into a signal column: 1 = your buy rule, -1 = your sell rule, 0 = do nothing
data["Signal"] = 0
data.loc[data["RSI"] < 30, "Signal"] = 1
data.loc[data["RSI"] > 70, "Signal"] = -1

Nothing here is specific to RSI. Swap in your own indicators or your own formula, and the shape stays the same: compute what you need, then reduce it to a clear decision the rest of the system can act on.

Step 4: Test it against history first

This is the step people skip and regret. Before any real money is involved, run the rules over past data and see what they would have done. A minimal backtest is just a loop that walks through the bars, follows the signals, and keeps a tally:

starting_cash = 100_000
cash = starting_cash
shares = 0
entry = 0.0
trades = []

for i in range(1, len(data)):
    signal = data["Signal"].iloc[i]
    price = float(data["Close"].iloc[i])

    if signal == 1 and shares == 0:            # enter
        shares = int((cash * 0.02) / price)    # commit 2% of cash to this position
        entry = price
        cash -= shares * price
    elif signal == -1 and shares > 0:          # exit
        cash += shares * price
        trades.append(price - entry)
        shares = 0

ending_value = cash + shares * float(data["Close"].iloc[-1])
print(f"Trades taken: {len(trades)}")
print(f"Result on this sample: {(ending_value / starting_cash - 1) * 100:.1f}%")

That final number is what these rules would have done on one slice of history. Nothing more. It is not a prediction, and a strategy that looks wonderful on one sample can fall apart on the next. Past results don't tell you what happens next. A serious backtest also accounts for slippage, real costs, and look-ahead bias, and reports things like drawdown rather than a single flattering percentage, which is exactly the difference between a toy loop and a proper backtesting engine.

Step 5: Connect to your broker

Once you trust the logic, you wire it to a live account. Two of the most common, in the two markets we're asked about most:

Interactive Brokers for global markets

from ib_insync import IB, Stock, MarketOrder

ib = IB()
ib.connect("127.0.0.1", 7497, clientId=1)   # TWS or IB Gateway must be running

contract = Stock("AAPL", "SMART", "USD")
ib.qualifyContracts(contract)

trade = ib.placeOrder(contract, MarketOrder("BUY", 10))
ib.sleep(1)
print(trade.orderStatus.status)

Zerodha Kite for Indian markets (NSE/BSE)

from kiteconnect import KiteConnect

kite = KiteConnect(api_key="your_api_key")
kite.set_access_token("your_access_token")   # obtained from the login flow

order_id = kite.place_order(
    variety=kite.VARIETY_REGULAR,
    exchange=kite.EXCHANGE_NFO,
    tradingsymbol="NIFTY25AUGFUT",
    transaction_type=kite.TRANSACTION_TYPE_BUY,
    quantity=50,
    product=kite.PRODUCT_MIS,
    order_type=kite.ORDER_TYPE_MARKET,
)
print("Order placed:", order_id)

The order-placing call is the easy five minutes. The weeks go into what happens around it: partial fills, rejections, rate limits, and reconnecting after a dropped connection without accidentally sending the same order twice. That reliability layer is most of what separates a demo from something you'd trust with a live account. We do this across IBKR, Zerodha, Angel One, MetaTrader 5 and a dozen other platforms as part of our broker API integration work.

Step 6: Add risk controls before anything else

A bot with no risk management is a fast way to lose money. At a minimum you want a stop on every position, a cap on how much any single trade can risk, a daily loss limit that halts trading, and a check that you actually have the margin before an order goes out. A small manager class keeps this in one place:

class RiskManager:
    def __init__(self, capital, risk_per_trade=0.01, max_daily_loss=0.03):
        self.capital = capital
        self.risk_per_trade = risk_per_trade      # e.g. 1% of capital at risk per trade
        self.max_daily_loss = max_daily_loss      # e.g. stop for the day at 3%
        self.daily_pnl = 0.0

    def position_size(self, price, stop_distance_pct=0.01):
        risk_amount = self.capital * self.risk_per_trade
        return int(risk_amount / (price * stop_distance_pct))

    def can_trade(self):
        return self.daily_pnl > -self.capital * self.max_daily_loss

Wire can_trade() in front of every entry and update daily_pnl as positions close. It's unglamorous code, and it's the code that saves the account on a bad day.

Step 7: Deploy it somewhere it can actually run

Your laptop works for testing, but it's a poor place for a bot that needs to be awake through a whole session, it sleeps, updates restart it, the Wi-Fi drops. For anything real, a small VPS (DigitalOcean, AWS or Azure) running around the clock is the usual answer. A sensible starter setup:

  • A modest Linux VPS (Ubuntu), sized to your latency needs
  • Python in a virtual environment, dependencies pinned
  • systemd or supervisor to keep the process alive and restart it if it crashes
  • Proper logging to a file, plus alerts, a Telegram or email ping, when something breaks

For a setup that has to stay up no matter what, failover, redundancy, a dashboard to watch it, the infrastructure becomes a real project of its own. That's the kind of thing our custom trading software builds are usually about.

The short version

  1. Write your rules down until they're unambiguous.
  2. Pull in market data, free to learn, proper feeds when it counts.
  3. Compute your indicators and reduce them to clear signals.
  4. Backtest honestly, and distrust a single good-looking number.
  5. Connect to your broker's API, and handle the failure cases.
  6. Put risk controls in front of everything.
  7. Run it on a machine that stays awake, and watch it.

None of the steps are mysterious. The difficulty is in the details, the edge cases that only appear when your code meets a live market. If you'd rather have a team that has hit those edge cases many times build the system to your rules, that's exactly what we do. You keep the strategy; we build what runs it.

Frequently asked questions

What is the best programming language for building a trading bot?
For most people, Python. The data libraries (pandas, NumPy) are mature, nearly every broker has a Python API or a well-maintained wrapper, and the code stays readable months later when you have to change it. C++ earns its place only at the fast end, high-frequency work where microseconds decide the trade. If you are not doing that, Python is the sensible default.
How much does it cost to build a trading bot in Python?
There is no price list, and any figure quoted before we understand your requirement would be made up. A single strategy on one broker with clear rules is a small job; a multi-broker, multi-account platform with a dashboard is a large one. Tell us what you want built and we will come back with a real estimate.
Can a Python trading bot trade stocks, futures and crypto?
Yes. The bot itself does not care about the asset class. That is decided by the broker or exchange you connect to. Interactive Brokers covers global stocks, futures and options; Zerodha and Angel One cover Indian markets; crypto exchanges have their own APIs. You bring the market; the same structure applies.
Do I need to know how to code to build a trading bot?
A little Python helps you understand and trust what your bot is doing, and we would encourage it. But you do not have to write it yourself. If you can describe your rules clearly, a development team can build the system to that specification and hand you something you can run and maintain.
How do I connect a Python trading bot to my broker?
Almost every broker exposes a REST or WebSocket API. For Interactive Brokers, the ib_insync library is the friendliest way in. For Zerodha, it is Kite Connect. For MetaTrader 5, the official MetaTrader5 Python package. The connection is rarely the hard part. Handling what the API does when something goes wrong is.
Is algorithmic trading legal in India?
Yes. Algorithmic trading is legal in India and regulated by SEBI. Retail traders automate through broker-provided APIs, and SEBI has a framework governing how those retail algos are registered and approved through the broker. The rules have been evolving, so check the current SEBI and exchange requirements (or ask your broker) before you go live. This is general information, not legal or investment advice.
start here

Want a team to build it with you?

Tell us the rules you want automated and the broker you use. We'll come back with honest questions, then a real plan, you own the strategy, we build the system.

Book a consultation