Skip to content

TessTrade Python SDK

Write indicators and strategies in Python. The same script runs in two contexts - a historical backtest and live chart trading - under an identical contract. This documentation covers how the engine calls your code, what the SDK exposes, the set of accepted actions, and the most common pitfalls.

INFO

New here? Start with Backtest vs Chart Trading for the mental model, then jump to the Example script to write your first strategy in five minutes.

What you write

A Python file with a main(df, sdk, params) function and, optionally, a DECLARATION dictionary describing the editable parameters and the chart plots.

python
DECLARATION = {
    "type": "strategy",
    "inputs": [
        {"name": "fast_period", "type": "int", "default": 9,  "min": 1, "max": 100},
        {"name": "slow_period", "type": "int", "default": 21, "min": 2, "max": 200},
    ],
}

def main(df=None, sdk=None, params={}):
    params = params or {}
    if sdk is not None:
        # tick by tick / candle by candle execution
        return on_bar_strategy(sdk, params)
    if df is not None:
        # chart plots
        return _build_chart(df, params)
    return DECLARATION

The same function is called in three different contexts. See The main() dispatcher for details on each one.

Documentation map

Getting started

PageDescription
Backtest vs Chart TradingThe two execution contexts and why the same script runs in both
Example scriptA minimal runnable strategy to verify the editor and the pipeline
Sandbox limitsAvailable modules, builtins, and resource caps

Contract

PageDescription
The main() dispatcherThe three contexts the engine calls your script in
The DECLARATION shapeRoot-level dictionary for inputs, plots, and conditions
Script lifecycleHow the engine loads, validates, and executes your code

SDK reference

PageDescription
Candles, params and stateReading market data and persisting values across bars
Position, cash and equityPortfolio properties exposed on the SDK
Canonical actionsEvery action string the engine accepts
Order typesMarket, limit, stop, stop-limit, bracket
Stops, targets and trailingProtective stops, take-profit, and trailing stops

Indicators

PageDescription
Plots and seriesHow chart plots are declared and rendered
Implementing SMA and EMAMoving average recipes in pure Python
RSI, MACD and Bollinger BandsPure-Python implementations of the three most common oscillators
Panes: overlay vs new paneWhen to overlay on price versus use a separate pane

Ready-to-use strategies

PageDescription
SMA CrossoverDual moving-average trend-following template
RSI Mean ReversionOverbought/oversold reversal template
MACD MomentumSignal-line crossover template
Persistent state and trailing stopPatterns for sdk.state and trailing exits
Solid entry/exit patternsChecklist of robust practices

Declarative mode

PageDescription
When to use entry/exit conditionsDeclarative versus imperative mode and how to choose
Supported operatorsOperator catalog with semantics

Backtest

PageDescription
Reading the resultsInterpreting the output panel
Performance metricsSharpe, drawdown, profit factor, and which ones actually matter
TroubleshootingCommon failure modes with root cause and fix

Chart Trading

PageDescription
Live editorIn-chart development environment
Paper Trading BotsPersistent simulated bots that run without an open tab
Live vs backtest differencesSubtle execution gaps between the two contexts

Reference

PageDescription
Canonical actions tableQuick lookup for every accepted action
Operators tableQuick lookup for declarative operators
Error catalogEvery exception the engine can raise and how to fix it
GlossaryTerm definitions

What the SDK provides

  • sdk.candles - list of OHLCV candles.
  • sdk.params - the parameters defined in DECLARATION["inputs"], already typed.
  • sdk.state - dictionary persistent across candles (useful for trailing stops, flags, cooldowns).
  • sdk.position - current net position (positive = long, negative = short, zero = flat).
  • sdk.cash, sdk.equity, sdk.buy_price, sdk.sell_price - portfolio snapshot.
  • sdk.buy(...), sdk.sell(...), sdk.close(...), sdk.update_exits(...) - issue signals.

Full API in SDK reference.

Sandbox

Scripts run in a hardened Python sandbox. Available resources:

  • Injected modules (no import required): np (numpy), pd (pandas), math, json, datetime, plus safe optimized versions of ta, pandas_ta, and talib.
  • Allowed builtins: len, range, sum, abs, min, max, round, sorted, zip, enumerate, isinstance, int, float, str, list, dict, tuple, set, print.
  • Exception classes: ValueError, TypeError, KeyError, IndexError, RuntimeError, ZeroDivisionError, OverflowError.

Anything outside this surface raises SecurityError. Full detail in Sandbox limits.

Execution limits

LimitDefaultRaised if exceeded
Time per call200msTimeoutError
Memory64MBMemoryError
Code size~100KBrejected at load time
Nesting depth20 levelsrejected at load time

TIP

Quick start: copy the SMA Crossover template, adjust the parameters, and run it. From there, swap in the indicator of your choice from Implementing SMA and EMA or RSI, MACD and Bollinger Bands.