Home / OXScript
Documentation · Strategy engineOXScript — code your own crypto trading bot strategy
Most bots lock you into their one signal. OX-ENGINE doesn't. OXScript lets you build your own entry strategy three ways — a ready-made template, the AI assistant, or a few lines of code — backtest it, and even paste a TradingView Pine Script to convert it. Here's the full reference.
Every script runs on closed candles only (non-repaint), in a sandbox with no network or file access and a bounded op budget — a buggy script logs an error and skips the candle, it can't crash the bot. And a script's trade plan can never engage more margin or a wider stop than your own money-management config. A shared or AI-generated script cannot override your limits.
What is an OXScript?
An OXScript is a small program (Rhai syntax, close to Rust) that the engine runs on every closed 5-minute candle, for each of your active pairs. It looks at the price history and answers:
"long"— open (or flip to) a LONG position"short"— open (or flip to) a SHORT position"none"— do nothing- or a full trade plan:
#{ signal: "long", size_pct: 2.0, sl_pct: 3.0, tp_pct: 9.0 }
Your existing protections (break-even, trailing stop, liquidation protection, take profit) still apply on top of whatever the script decides. The script chooses the entry; your money management keeps it in bounds.
Three ways to build a strategy
Install a ready-made one
Money → Strategy → Script → "Ready to use" → Install. Four strategies ship in the bot; installing creates a private copy you can tweak, backtest, then use.
Let the AI write it
Describe it in plain language ("MACD cross with an EMA-100 trend filter, 2% risk, SL 3%, TP 6%") or paste a TradingView Pine Script. The AI writes a compiled, server-validated script; you save and backtest it, and iterate by chatting.
Write it yourself
Money → Strategy → Script → + New. The editor is pre-filled with a working example and refuses to save anything that doesn't compile — you can't break the bot with a typo.
Quick start (by hand)
The minimal script — a two moving-average crossover:
let fast = ema(close, 9);
let slow = ema(close, 21);
if crossover(fast, slow) {
"long"
} else if crossunder(fast, slow) {
"short"
} else {
"none"
}
The last expression evaluated is the result (there's no return). Here's the same idea with embedded money management and adjustable parameters:
let fast = ema(close, params.fast);
let slow = ema(close, params.slow);
if crossover(fast, slow) && position != "long" {
#{ signal: "long", size_pct: params.size_pct, sl_pct: params.sl_pct, tp_pct: params.tp_pct }
} else if crossunder(fast, slow) && position != "short" {
#{ signal: "short", size_pct: params.size_pct, sl_pct: params.sl_pct, tp_pct: params.tp_pct }
} else {
"none"
}
with, in the Parameters (JSON) field:
{"fast": 9, "slow": 21, "size_pct": 2.0, "sl_pct": 3.0, "tp_pct": 9.0}
Parameters are editable without touching the code — and every user of a shared script can have their own values, via their cloned copy.
Language reference
Variables available
| Variable | Type | Contents |
|---|---|---|
open, high, low, close | float array | CLOSED 5m candles of the pair, most recent LAST |
time | int array | Candle open timestamps (ms) |
params | map | Your JSON parameters (e.g. params.fast) |
state | map | Persists candle to candle (like Pine var) — e.g. state.n = 1; |
position | string | "long" / "short" / "flat" — current position on the pair |
Indicator helpers (array in → aligned array out, NaN during warm-up)
| Helper | Pine equivalent |
|---|---|
sma(a, n) / ema(a, n) | ta.sma / ta.ema |
rsi(a, n) | ta.rsi |
atr(high, low, close, n) | ta.atr |
highest(a, n) / lowest(a, n) | ta.highest / ta.lowest |
change(a) | ta.change |
nwe_upper(close, bw, mult) / nwe_lower(...) | the bot's native Nadaraya-Watson envelope |
Scalar helpers
| Helper | Role |
|---|---|
last(a) | last value of the array (most recent closed candle) |
prev(a, n) | value n candles back — prev(close, 1) = Pine close[1] |
crossover(a, b) / crossunder(a, b) | bool: a cross on the LAST candle |
Rhai syntax — the classic gotchas
let x = ...;declares;if/elseare expressions (noreturnneeded).- Maps are written
#{ key: value }(with the#). - Floats: write
2.0, not2, in float math (Rhai won't auto-convert). - Warm-up NaN: indicators return NaN until they have enough candles. Idiomatic test:
if x != x { "none" }(NaN is the only float ≠ itself). - Anti-spam: guard with
position != "long"before a long signal, or the script re-signals the same direction every candle. - No
import, no network or file functions — it's a sandbox.
The trade plan (money management from the script)
#{ signal: "long", size_pct: 2.0, sl_pct: 3.0, tp_pct: 9.0 }
| Field | Meaning | Cap |
|---|---|---|
signal | "long" / "short" (required) | — |
size_pct | % of balance committed as margin on this trade | min(script, Money config) |
sl_pct | max loss as % ROE of that margin | min(script, Money SL if set) |
tp_pct | profit target as % ROE | the plan's TP takes priority |
Every field except signal is optional — a missing field means your Money config applies. The plan's SL/TP are placed on the exchange as real protective orders, with the same guarantees as your Money stops.
Ready-made strategies
Four strategies ship in the bot — install any of them as a private, editable copy:
| Strategy | Style | Idea |
|---|---|---|
| NWE Envelope (native) | Mean reversion | The bot's native strategy as a script — proven-equivalent signals, with adjustable bandwidth/mult |
| EMA Cross 9/21 + RSI | Trend following | Fast/slow EMA cross filtered by RSI, R/R 1:3 |
| Donchian Breakout 20 (Turtle) | Breakout | Break of the 20-candle high/low |
| RSI-2 Mean Reversion (Connors) | Mean reversion | Buy extreme dips inside the EMA-200 trend |
Translate a TradingView Pine Script
Easiest: paste the Pine into the AI chat. To map it by hand:
| Pine | OXScript |
|---|---|
close[1] | prev(close, 1) |
ta.ema(close, 9) | ema(close, 9) |
ta.crossover(a, b) | crossover(a, b) |
var x = 0 | state.x = 0; (persists between candles) |
strategy.entry("L", strategy.long) | result "long" |
strategy.exit(loss=…, profit=…) | sl_pct / tp_pct in the plan |
Not supported (v1): request.security (multi-timeframe), volume, and advanced strategy.* orders (pyramiding, Pine trailing, commission). The AI tells you instead of translating it wrong.
Backtest, use, share
- Backtest — replays your script over ~1,000 recent 5m candles (~3.5 days), candle by candle so it can't "see the future." Numbers differ from TradingView (different data, fills and fees) — treat them as an order of magnitude.
- Use — select the script as your entry strategy across all your pairs. The strategy preview at the top of Money then shows its estimated frequency and theoretical win rate.
- Share — tick "Share" and your script becomes clonable by other users (read-only for them; they work on their own copy). They can never exceed their own money-management caps with your script.
FAQ
What is OXScript?
OX-ENGINE's small strategy language (Rhai). The bot runs your script on every closed 5m candle; it returns "long", "short", "none", or a trade plan. It's sandboxed and can never exceed your money-management limits.
Do I need to code?
No — install a ready-made strategy in one tap, or describe it (or paste a Pine Script) to the AI assistant, which writes it for you. Coding by hand is optional.
Is it safe to run a shared or AI script?
Yes. Sandbox, no I/O, and its trade plan can never engage more margin or a wider stop than your own config. Nothing here is financial advice — backtest, start in dry-run, and size your risk.
Build your first strategy
Open the trading bot on Telegram, go to Money → Strategy → Script, and install one in a tap — or ask the AI.