Skip to main content
Program strategies are Python scripts that run in a WASM sandbox. They provide deterministic, backtestable logic for systematic trading — complementing the flexibility of prompt-based strategies.

How it works

Your Python code implements a should_trade function that receives market data and returns a trading decision. The function runs inside Eryx (CPython 3.14 compiled to WASM) with restricted access for security.

Writing a strategy

A minimal strategy class:
class Strategy:
    def should_trade(self, data):
        price = data.get_price("BTC")
        rsi = data.get_indicator("BTC", "rsi", 14)

        if rsi < 30:
            return Decision(
                operation="long",
                symbol="BTC",
                leverage=3,
                take_profit_pct=5.0,
                stop_loss_pct=2.0,
                reasoning="RSI oversold"
            )

        if rsi > 70:
            return Decision(
                operation="short",
                symbol="BTC",
                leverage=3,
                take_profit_pct=5.0,
                stop_loss_pct=2.0,
                reasoning="RSI overbought"
            )

        return Decision(operation="hold")

MarketData API

The data parameter passed to should_trade provides these methods:
MethodParametersReturns
get_price(symbol)Symbol nameCurrent price as float
get_klines(symbol, interval, limit)Symbol, timeframe (1m, 5m, 1h, 4h, 1d), countList of OHLCV candles
get_indicator(symbol, name, period)Symbol, indicator name, lookback periodIndicator value(s)
get_positions()List of open positions
get_balance()Available account balance
get_regime(symbol)Symbol nameCurrent market regime string
get_factor(symbol, factor_name)Symbol, factor expression nameFactor value as float

Supported indicators

data.get_indicator("BTC", "rsi", 14)        # Relative Strength Index
data.get_indicator("BTC", "macd", 26)       # MACD line, signal, histogram
data.get_indicator("BTC", "bbands", 20)     # Bollinger Bands (upper, mid, lower)
data.get_indicator("BTC", "ema", 50)        # Exponential Moving Average
data.get_indicator("BTC", "sma", 200)       # Simple Moving Average
data.get_indicator("BTC", "atr", 14)        # Average True Range

Decision fields

The Decision object returned by should_trade:
FieldTypeRequiredDescription
operationstringYes"long", "short", or "hold"
symbolstringIf not holdTrading pair symbol
leveragefloatIf not holdPosition leverage multiplier
take_profit_pctfloatNoTake-profit percentage from entry
stop_loss_pctfloatNoStop-loss percentage from entry
size_pctfloatNoPercentage of available balance to use
reasoningstringNoHuman-readable explanation of the decision

Security sandbox

Programs run inside a restricted WASM environment with multiple safety layers:

Forbidden imports

os, sys, subprocess, socket, http, urllib, and other system/network modules are blocked.

Restricted builtins

exec, eval, compile, __import__, open, and file I/O builtins are removed.

Execution timeout

Each execution is capped at 30 seconds. Strategies that exceed this limit are terminated.

No filesystem access

The WASM sandbox has no access to the host filesystem. All data comes through the MarketData API.
The sandbox prevents arbitrary code execution. If your strategy needs external data, fetch it through the platform’s market data endpoints or factor engine rather than attempting network calls.

Creating and binding a program

1

Create the program

curl -X POST https://api.hyperoru.com/api/programs \
  -H "Content-Type: application/json" \
  -d '{
    "name": "RSI Mean Reversion",
    "code": "class Strategy:\n    def should_trade(self, data):\n        rsi = data.get_indicator(\"BTC\", \"rsi\", 14)\n        if rsi < 30:\n            return Decision(operation=\"long\", symbol=\"BTC\", leverage=3, take_profit_pct=5.0, stop_loss_pct=2.0)\n        return Decision(operation=\"hold\")",
    "user_id": "your-user-id"
  }'
2

Bind to a trader

curl -X POST https://api.hyperoru.com/api/bindings \
  -H "Content-Type: application/json" \
  -d '{
    "trader_id": "trader-uuid",
    "program_id": "program-uuid",
    "trigger_type": "scheduled",
    "interval_minutes": 5,
    "symbols": ["BTC", "ETH"]
  }'
3

Backtest

Validate your strategy against historical data before going live. See Backtesting.