TickAtlas
Guide 10 min read · March 28, 2026

From Free Tier to Pro: Scaling Your Trading Bot as It Grows

A practical guide to scaling your trading bot from prototype to production. Covers when to upgrade your API plan, optimize performance, and add monitoring as usage grows.

CG
By the TickAtlas team

The Growth Path

Every successful trading bot starts as a simple script and evolves into a production system. At each stage, your API needs change. Here is what the typical growth path looks like and when to upgrade.

Stage 1: Prototype (Free Tier)

1-3

Pairs monitored

H1/H4

Timeframes

~100

API calls/day

You are testing your strategy logic against live data. The free tier (1,000 calls/day) is more than enough. Focus on getting the strategy right, not on optimization.

python
# Stage 1: Simple and direct
import requests

API_KEY = "your_api_key_here"
BASE_URL = "https://tickatlas.com/v1"

def check_signal(symbol: str) -> str:
    resp = requests.get(f"{BASE_URL}/indicators", params={
        "symbol": symbol,
        "timeframe": "H1",
        "indicators": "RSI_14,MACD"
    }, headers={"X-API-Key": API_KEY})

    data = resp.json()["data"]["indicators"]
    rsi = data["RSI_14"]["value"]
    macd = data["MACD"]["histogram"]

    if rsi < 30 and macd > 0:
        return "BUY"
    return "HOLD"

Stage 2: Paper Trading (Free/Starter)

5-10

Pairs monitored

H1

Primary timeframe

~2,000

API calls/day

You are running 24/7, logging signals, and tracking hypothetical P&L. Time to add caching and error handling.

python
# Stage 2: Add caching and logging
import time
import logging

logging.basicConfig(level=logging.INFO, filename="bot.log")
logger = logging.getLogger("trading_bot")

class TradingBot:
    def __init__(self, api_key: str, symbols: list[str]):
        self.api_key = api_key
        self.symbols = symbols
        self.cache = {}
        self.cache_time = {}

    def get_data(self, symbol: str, ttl: int = 300) -> dict:
        """Cached API call — only fetches when stale."""
        now = time.time()
        if symbol in self.cache and now - self.cache_time[symbol] < ttl:
            return self.cache[symbol]

        resp = requests.get(f"{BASE_URL}/indicators", params={
            "symbol": symbol,
            "timeframe": "H1",
            "indicators": "RSI_14,MACD,ADX_14,ATR_14"
        }, headers={"X-API-Key": self.api_key})

        if resp.status_code == 429:
            logger.warning(f"Rate limited on {symbol}. Backing off.")
            time.sleep(5)
            return self.cache.get(symbol, {})

        data = resp.json()
        self.cache[symbol] = data
        self.cache_time[symbol] = now
        return data

Stage 3: Live Trading (Starter)

10-20

Pairs monitored

M15-H4

Multiple timeframes

~15,000

API calls/day

Real money is at stake. Add monitoring, alerts, and multi-timeframe analysis. The Starter plan (50,000/day) provides comfortable headroom.

Stage 4: Multi-Strategy (Pro)

20+

Pairs + crypto

M5-D1

All timeframes

~100,000

API calls/day

Running multiple strategies concurrently, a scanner, a dashboard, and an AI analyst. Pro plan (500,000/day) handles it all. Time for proper architecture.

python
# Stage 4: Multi-strategy architecture
from concurrent.futures import ThreadPoolExecutor
from queue import Queue

class MultiStrategyBot:
    def __init__(self, api_key: str):
        self.client = CachedClient(api_key)
        self.strategies = []
        self.signal_queue = Queue()

    def add_strategy(self, strategy, symbols, timeframe):
        self.strategies.append({
            "strategy": strategy,
            "symbols": symbols,
            "timeframe": timeframe
        })

    def run_all(self):
        """Run all strategies in parallel."""
        with ThreadPoolExecutor(max_workers=4) as pool:
            futures = []
            for strat_config in self.strategies:
                for symbol in strat_config["symbols"]:
                    future = pool.submit(
                        self._evaluate,
                        strat_config["strategy"],
                        symbol,
                        strat_config["timeframe"]
                    )
                    futures.append(future)

            for future in futures:
                result = future.result()
                if result and result["signal"] != "HOLD":
                    self.signal_queue.put(result)

    def _evaluate(self, strategy, symbol, timeframe):
        data = self.client.get_indicators(symbol, timeframe,
                                          "RSI_14,MACD,ADX_14,BBANDS_20")
        return strategy.evaluate(symbol, data)

When to Upgrade: The Decision Framework

Upgrade when usage exceeds 70% of your limit

If you are consistently using more than 70% of your daily quota, upgrade before you start hitting limits. Running out of API calls during volatile markets is the worst time to be throttled.

Upgrade when you need faster polling

Moving from H1 to M15 timeframes multiplies your API usage by 4x. If your strategy needs shorter timeframes, you need more quota.

Upgrade when you add instruments

Monitoring 20 pairs instead of 5 increases usage 4x. Each new pair or crypto you add consumes proportionally more calls.

Optimization Checklist

Before upgrading, make sure you have optimized:

  • Batch all indicators into single API calls (rate limiting guide)
  • Cache responses with TTL matched to your timeframe
  • Use exponential backoff on 429 errors
  • Track usage with a counter so you know exactly where calls go
  • Only poll at the minimum necessary frequency

Further Reading

Try this with live data

Every account gets $2.50 in free PAYG credits. No card required — paste your API key and run the code above against live broker data.