DEV Community

Market Masters
Market Masters

Posted on

Python Trading Bot Tutorial: Real-Time Prices, Technical Analysis, and Portfolio Tracking

Python Trading Bot Tutorial: Real-Time Prices, Technical Analysis, and Portfolio Tracking

Binance processes 1.4 million orders per second. Your bot needs data just as fast, or it loses.

Retail traders lose 70-80% of the time because they trade manually on stale charts. Build a bot that fetches live prices, runs technical analysis, and tracks a portfolio. This uses CCXT for exchange data, TA-Lib for indicators, and basic risk rules. No fluff: full runnable code, gotchas included.

Tested on BTC/USDT. Scales to any pair.

Prerequisites

  • Python 3.10+
  • Binance API key (paper trading: set sandbox=True)
  • Install deps:
pip install ccxt pandas numpy TA-Lib
Enter fullscreen mode Exit fullscreen mode

TA-Lib needs binaries: Ubuntu sudo apt install ta-lib libta-lib-dev; macOS brew install ta-lib; Windows grab wheel from unofficial repo.

Step 1: Live Data Fetch

CCXT unifies 100+ exchanges. Fetch tickers without rate limit headaches.

import ccxt

import pandas as pd
import numpy as np
import talib

exchange = ccxt.binance({
    'apiKey': 'YOUR_API_KEY',
    'secret': 'YOUR_SECRET',
    'sandbox': True,  # Paper trading
})

symbol = 'BTC/USDT'

# Fetch OHLCV (1m candles, limit 100)
def fetch_ohlcv(symbol, timeframe='1m', limit=100):
    ohlcv = exchange.fetch_ohlcv(symbol, timeframe, limit=limit)
    df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
    df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
    return df

latest = fetch_ohlcv(symbol)
print(latest.tail())
Enter fullscreen mode Exit fullscreen mode

Gotcha: fetch_ohlcv rate limits at 1200/min on Binance. Sleep 500ms between calls or batch symbols.

Step 2: Technical Analysis

RSI oversold <30, overbought >70. MACD crossovers signal momentum.

def compute_ta(df):
    df['rsi'] = talib.RSI(df['close'], timeperiod=14)
    macd, signal, hist = talib.MACD(df['close'])
    df['macd'] = macd
    df['macd_signal'] = signal
    df['macd_hist'] = hist
    return df

latest = compute_ta(latest)
print(latest[['close', 'rsi', 'macd', 'macd_signal']].tail())
Enter fullscreen mode Exit fullscreen mode

Tradeoff: TA-Lib is C-fast but fixed periods. Pandas-TA allows custom funcs if you need ML overlays.

Step 3: Trading Logic

Buy: RSI <30 and MACD > signal. Sell: RSI >70 or stop 2% loss. Position size: 1% risk.

class TradingBot:
    def __init__(self, symbol, stake_usd=1000):
        self.symbol = symbol
        self.stake = stake_usd
        self.position = 0  # qty
        self.entry_price = 0

    def signal(self, df):
        latest = df.iloc[-1]
        prev = df.iloc[-2]

        if (latest['rsi'] < 30 and latest['macd'] > latest['macd_signal'] and
            prev['macd'] <= prev['macd_signal']):
            return 'buy'
        elif latest['rsi'] > 70 or (self.position > 0 and 
                                    latest['low'] < self.entry_price * 0.98):
            return 'sell'
        return 'hold'

    def execute(self, signal, price):
        if signal == 'buy' and self.position == 0:
            qty = (self.stake * 0.01) / price  # 1% risk
            # order = exchange.create_market_buy_order(self.symbol, qty)
            self.position = qty
            self.entry_price = price
            print(f'Bought {qty:.6f} @ {price}')
        elif signal == 'sell' and self.position > 0:
            # order = exchange.create_market_sell_order(self.symbol, self.position)
            print(f'Sold {self.position:.6f} @ {price}')
            self.position = 0

bot = TradingBot(symbol)
while True:
    df = fetch_ohlcv(symbol)
    df = compute_ta(df)
    signal = bot.signal(df)
    price = df['close'].iloc[-1]
    bot.execute(signal, price)
    time.sleep(60)  # 1m loop
Enter fullscreen mode Exit fullscreen mode

Warning: Uncomment orders only after backtesting. Paper trade first.

Step 4: Portfolio Tracker

Track PnL, win rate across symbols.

def track_portfolio(bots):
    total_pnl = 0
    trades = []
    for bot in bots:
        unrealized = (current_price - bot.entry_price) * bot.position if bot.position else 0
        total_pnl += unrealized
        if bot.entry_price > 0:
            trades.append({'symbol': bot.symbol, 'pnl_pct': unrealized / (bot.entry_price * bot.position) * 100})
    print(f'Total PnL: ${total_pnl:.2f}')
    print(pd.DataFrame(trades))
Enter fullscreen mode Exit fullscreen mode

Full Script

Combine above. Run python bot.py. Logs to console/file.

Gotchas:

  • Latency: CCXT WebSocket for <100ms updates (see watch_ticker).
  • Fees: Binance 0.1%, factor into stops.
  • Slippage: Market orders on illiquid pairs.
  • Backtest: Use backtrader or vectorbt on historical data first.

Scale It

Multi-symbol: Loop ETH/USDT, SOL/USDT. Add OI/liquidation via Bybit API.

For pro signals: Market Masters API gives conviction scores (-100 to +100) from 15 indicators, chart patterns, Elliott Waves. Free tier screens 2500+ coins/stocks.

Start your 30-day free trial - no CC. Build smarter.

Code: GitHub repo (fork and run). Questions? Comments below.

Top comments (0)