Developer docs

Build trading bots for SteraTrader

The SteraTrader Add-Ons SDK reference: bot lifecycle, trading actions, parameters, allowed imports, backtesting, packaging, review and selling. SDK version 0.1.

Overview

An add-on is a Python package built on the stera SDK. There are three kinds: trading bots that open and close positions, trade tools that manage positions a trader opened (trailing, breakeven, risk sizing), and indicators.

You build and backtest on your own computer. You upload the package, where it gets instant automatic checks and a human review. Approved add-ons are listed in the marketplace and run in the SteraTrader cloud. Your source code never leaves SteraTrader: traders get running instances, never files.

Quick start

python3 -m venv stera-env && . stera-env/bin/activate
pip install https://steratrader.com/downloads/stera_sdk-0.1.0-py3-none-any.whl

# start from the example
curl -LO https://steratrader.com/downloads/gold-breakout-example.zip
unzip gold-breakout-example.zip -d gold_breakout

# download prices from the developer portal, then:
stera backtest ./gold_breakout --data XAUUSD_M15_30d.csv --symbol XAUUSD --contract 100 --spread 0.30
stera package ./gold_breakout

Create a free account in the developer portal to download historical prices and upload add-ons.

Project layout

gold_breakout/
├── addon.json      # manifest
├── bot.py          # entry file with your Bot class
├── signals.py      # optional: your own helper modules
└── README.md       # optional
{
  "name": "Gold Breakout",
  "version": "1.0.0",
  "entry": "bot.py",
  "class": "GoldBreakout",
  "sdk": ">=0.1",
  "requirements": []
}
FieldRequiredMeaning
nameyesDisplay name.
versionyesThree numbers, like 1.0.0. Must match the version you enter when uploading, and each upload needs a new version.
entryyesThe file that defines your bot class.
classyesYour class name. It must subclass Bot and define on_bar or on_tick.
sdknoThe SDK versions you support, e.g. >=0.1.
requirementsnoExtra packages. Only numpy and pandas are allowed.

Bot lifecycle

Subclass Bot and implement the hooks you need. The platform calls them; you never call them yourself.

from stera import Bot, Param


class GoldBreakout(Bot):
    """Buys a close above the previous N-bar high."""
    symbol = Param("XAUUSD", help="Instrument to trade")
    lots = Param(0.10, min=0.01, max=5, help="Size of each trade")
    lookback = Param(20, min=5, max=200, help="Bars in the breakout range")
    stop = Param(8.0, min=0.5, help="Stop distance in price")
    target = Param(16.0, min=0.5, help="Target distance in price")

    def on_start(self):
        self.log(f"starting on {self.symbol} with {self.lots} lots")

    def on_bar(self, bar):
        if self.positions or len(self.history(self.lookback + 1)) <= self.lookback:
            return
        if bar.close > self.highest(self.lookback):
            self.buy(self.symbol, self.lots,
                     sl=bar.close - self.stop, tp=bar.close + self.target)

    def on_fill(self, fill):
        if fill.reason != "open":
            self.log(f"{fill.reason}: {fill.profit:+.2f}")
HookWhen it runs
on_start()Once, before the first bar. Settings are already validated.
on_bar(bar)Once for every completed bar. Most strategies live here. bar is a Bar.
on_tick(bid, ask)On every price update, in the cloud. Backtests replay bars, so on_tick is not called during a backtest.
on_fill(fill)After a position opens or closes, for any reason (your close, stop loss, take profit). fill is a Fill.
on_stop()Once, when the bot is stopped or the backtest ends.

Trading actions

MethodWhat it does
buy(symbol, lots, sl=None, tp=None)Opens a buy at market. sl and tp are absolute prices, not distances.
sell(symbol, lots, sl=None, tp=None)Opens a sell at market.
close(position)Closes one position from self.positions.
close_all()Closes every position this bot holds.

Orders are market orders. Buys fill at the ask and sells at the bid. In the cloud, platform limits apply to every order (see Running in the cloud). An order over a limit is refused and logged; it never partly fills.

Account and market state

MemberReturns
self.positionsThis bot's open positions, a list of Position.
self.balanceAccount balance.
self.history(n)The last n bars, the current bar last.
self.highest(n, field="high")Highest value over the n bars before the current one.
self.lowest(n, field="low")Lowest value over the n bars before the current one.
self.sma(n, field="close")Simple average over the last n bars including the current one, or None until there are n bars.
self.log(message)Writes to the bot's log: your terminal in backtests, the instance log in the cloud.
self.<setting>The value of any Param, as the trader set it.

Data types

TypeFields
Bartime, open, high, low, close, volume. Prices are bid prices.
Fillposition_id, symbol, side, lots, price, time, reason, profit. reason is one of open, close, stop_loss, take_profit, end_of_test. profit is 0 on open.
Positionid, symbol, side (buy or sell), lots, open_price, open_time, sl, tp.

Parameters

A Param is a setting the trader can change when starting your add-on. Declare it on the class. The type comes from the default value.

lots = Param(0.10, min=0.01, max=5, help="Size of each trade")   # float
lookback = Param(20, min=5, max=200)                               # int
symbol = Param("EURUSD")                                           # str
trail = Param(False, help="Trail the stop")                        # bool
ArgumentMeaning
defaultThe starting value. Its type (int, float, str or bool) is the setting's type.
min / maxOptional numeric limits. Values outside them are refused when the bot starts.
helpOne line shown to traders next to the setting.

Values are converted to the setting's type and checked before on_start. An unknown setting name, a wrong type or a value out of range stops the bot with a clear message instead of trading on bad input. Your settings, defaults and ranges are listed automatically on your marketplace page, read straight from your code. In backtests, set them with --param name=value.

What your code can use

Add-ons run in a sealed sandbox. They receive prices and send orders through the SDK, and nothing else. Uploads are checked for these rules before review, and the sandbox enforces them again at run time.

Rule
Imports allowedstera, math, statistics, datetime, collections, itertools, functools, dataclasses, typing, decimal, enum, random, numpy, pandas, and your own modules in the package.
Not allowedos, sys, subprocess, socket, network libraries, file access, threads and anything else not listed above.
Calls not allowedeval, exec, compile, __import__, open, input, globals, locals, vars, breakpoint, getattr, setattr, delattr.
AttributesNo double-underscore attributes such as __class__, except __init__ and __name__.
PackageA .zip up to 5 MB, 20 MB unpacked, at most 200 files, only .py, .json, .txt, .md and .csv.

Backtesting

Download bars for any symbol and timeframe from the developer portal: the same prices SteraTrader brokers trade on. Any CSV with time, open, high, low, close columns (and optionally volume) also works.

FlagMeaning
--dataCSV of bars (required).
--symbolSymbol the data is for (required). Orders on other symbols are refused.
--balanceStarting balance. Default 10000.
--spreadSpread in price units, e.g. 0.30 for gold or 0.00010 for EURUSD. Default 0.
--contractContract size: 100 for gold, 100000 for FX majors. Default 100000.
--commissionCommission per lot, round turn. Default 0.
--param name=valueOverride a setting. Repeatable.
--logs NPrint the last N log lines.
--jsonPrint the report as JSON.

How fills are modelled, on purpose on the cautious side: an order placed during a bar fills at the next bar's open, never at the close that triggered it. When one bar touches both your stop and your target, the stop counts first. Positions still open at the end are closed at the last price. The report shows net profit, return, trade count, win rate, profit factor and maximum drawdown.

Packaging and upload

stera package ./gold_breakout      # → gold_breakout/dist/gold-breakout-1.0.0.zip

In the developer portal, create the add-on once, then upload each version with a short note on what changed. Checks run immediately.

Checks and review

CheckWhat it confirms
filesAllowed file types, safe paths, at most 200 files.
sizeUnpacked size within 20 MB.
manifestaddon.json is valid and complete, and requirements are allowed.
codeEvery file parses, and imports and calls follow the rules above. Failures give the exact file and line.
entryThe class exists, subclasses Bot and defines on_bar or on_tick.
versionThe upload version matches addon.json.

Versions that pass go to SteraTrader review. Reviewers read the code and check that it does what the description says. They reject hidden behaviour, obfuscation, and undisclosed martingale or grid position sizing. A rejection always comes with a note. Approved versions appear in the marketplace. Automatic backtests across several symbols and timeframes will also run on every uploadcoming soon

Running in the cloudcoming soon

Approved add-ons run in isolated sandboxes on SteraTrader's own servers, next to the market, with no VPS. Traders start them from their terminal on their own accounts. Every running instance has limits enforced by the platform, not by your code:

LimitEffect
Maximum lotsOrders above it are refused.
Maximum daily lossWhen reached, the instance pauses for the rest of the day.
Orders per minuteProtects against runaway loops. Over it, orders are refused and the instance pauses.
Trade-only accessAdd-ons can trade. They can never deposit, withdraw or change account settings.
Demo firstBrokers decide whether add-ons may run on live accounts at all.
Kill switchThe trader, their broker and SteraTrader can each stop any instance instantly.

Selling

Listings can be free, a one-time price or a monthly subscription, with an optional free trial of up to 30 days on a demo account. Paid listings require identity verification. Because add-ons only run in the cloud, there is no copy protection to build and no piracy: buyers get running instances, never your files. Payments, payouts and the revenue share are published before paid sales opencoming soon

Your listing must describe honestly what the add-on trades and how. It may not promise profits, and any backtest you quote must be reproducible with the SDK. Live performance on your marketplace page is measured by SteraTrader and cannot be edited.

FAQ

Can I use my own indicators? Yes. Put helper modules in your package and import them, or compute with numpy and pandas.

Can my bot call an external API or signal service? No. Add-ons have no network access, which keeps traders' accounts and your bot's behaviour predictable and reviewable.

Can I trade several symbols? In the cloud, yes. A local backtest uses one data file, so it tests one symbol at a time.

Who sees my code? SteraTrader reviewers, to approve it. Nobody else: not traders and not brokers.

Ready to build?

Create a developer account, download prices and upload your first add-on.

Open the developer portal