The Bot class is the foundation of the trading bot system. All bots inherit from it and implement trading strategies.
When to use: Your strategy can be expressed as logic on a single data row with technical indicators, for one symbol.
How it works:
- Base class fetches data for
self.symbol(orself.tickersfor multi-asset bots) - Applies your function to each row
- Averages the last N decisions
- Executes trades automatically
- Fully backtestable via
local_backtest()/local_optimize()
Example:
class MyBot(Bot):
def __init__(self):
super().__init__("MyBot", symbol="QQQ", interval="1d", period="1y")
def decisionFunction(self, row):
if row["momentum_rsi"] < 30:
return 1 # Buy
elif row["momentum_rsi"] > 70:
return -1 # Sell
return 0 # HoldWhen to use: Same row-by-row logic applied across a basket of tickers with equal-weight sizing.
How it works:
- Pass
tickers=["SPY", "QQQ", "GLD"]to__init__instead ofsymbol= decisionFunctionis called once per ticker per bar (unchanged signature)- Buy signal: top up that ticker toward
total_value / N - Sell signal: liquidate that ticker's position
- Live trading:
makeOneIteration()routes to_run_multi_ticker_iteration()automatically - Backtesting:
backtest_bot()inner-joins all ticker DataFrames on timestamp and simulates equal-weight
Example:
class MyMultiBot(Bot):
def __init__(self):
super().__init__("MyMultiBot", tickers=["SPY", "QQQ", "GLD"],
interval="1d", period="1y")
def decisionFunction(self, row):
if row["momentum_rsi"] < 30:
return 1
elif row["momentum_rsi"] > 70:
return -1
return 0When to use:
- External APIs (e.g., Fear & Greed Index)
- Custom data processing
- Different timeframe handling
Example: See feargreedbot.py
When to use:
- Multi-asset strategies
- Portfolio rebalancing
- Complex optimization algorithms
Example: See sharpeportfoliooptweekly.py
1. Bot.__init__(name, symbol, interval="1m", period="1d")
├── Creates/retrieves bot from database
├── Initializes portfolio with {"USD": 10000} if new
├── Sets up symbol and data cache
└── Stores interval and period for data fetching
2. Bot.run()
├── Calls makeOneIteration()
├── Executes buy/sell based on decision
└── Logs result to database (RunLog)
3. Bot.makeOneIteration() [default implementation]
├── Fetches data: getYFDataWithTA(saveToDB=True, ...)
├── Gets decision: getLatestDecision(data)
└── Executes trade if decision != 0
# Raw market data
data = bot.getYFData(interval="1m", period="1d", saveToDB=True)
# With technical indicators
data = bot.getYFDataWithTA(interval="1m", period="1d", saveToDB=True)# Buy with all cash
bot.buy(symbol="QQQ")
# Buy specific amount
bot.buy(symbol="QQQ", quantityUSD=1000)
# Sell all holdings
bot.sell(symbol="QQQ")
# Rebalance portfolio
bot.rebalancePortfolio({"QQQ": 0.8, "GLD": 0.1, "USD": 0.1})cash = bot.dbBot.portfolio.get("USD", 0)
holding = bot.dbBot.portfolio.get("QQQ", 0)- Instance cache:
self.datacaches last fetched DataFrame (for single-ticker). For multi-ticker bots,self.datasis a dictionary caching DataFrames keyed by ticker. - Database persistence: Set
saveToDB=Truefor cross-run data reuse - Automatic freshness check: Stale data (>10 minutes) is refetched
- Bot API Reference - Complete method documentation
- Creating a Bot - Step-by-step guide