The Sequence Automation Handbook
The Sequence Automation Handbook
Tradingale engineering notes, published July 2026. Canonical URL: https://tradingale.com/handbook/sequence-automation.md
We ran martingale sequence automation in production on Binance, Kraken Pro and Alpaca before repositioning as a pure data provider. This handbook is the engineering playbook we paid to learn, published so that your own software, and the AI agent that writes it, can apply it directly. It is engineering documentation, not investment advice. Whatever you build runs on your keys, on your account, under your sole responsibility: Tradingale never places orders, holds funds, or gives advice.
Feed this file to your coding agent (Claude, ChatGPT, Gemini, Cursor, anything that reads markdown) together with the Tradingale API or MCP server for the model parameters themselves. Better still: start from martingale-kit, the open-source engine that implements this handbook as tested TypeScript (ladder math, state machine, paper simulator); your agent then only writes the venue adapter.
The whole machine, in five sentences
Before any engineering detail, the mental model. A sequence is not adaptive; this is the entire lifecycle:
- The sequence is frozen at birth. The first market buy fixes the entry price, and every other order is computed from it at that instant: all the limit buys and all the sell templates. Nothing is ever recomputed afterward.
- Every buy can rest on the book from second one. The market entry fills immediately; the limit buys wait at their levels. There is nothing to decide later.
- Only one order ever changes: the sell. Everything else sits still until the market comes to it.
- A limit buy fills? Cancel the sell, take the next template. The replacement is that level's sell, covering the full accumulated quantity, at the previous level's buy price.
- The sell fills? The sequence is over. By construction it closed above its average cost.
That is the whole machine. Everything below is about doing these five things reliably on a real venue.
1. The database is the source of truth, never the exchange
The single most important design decision: persist the entire sequence plan before placing anything. When a sequence starts, write every order the plan will ever need to your own database first:
- the round 1 market entry,
- one limit buy per deeper level (levels 2..N, each at
entry_price * (1 - (level - 1) * delta_price)), - one sell template per level, flagged
is_template, never sent to the exchange as-is.
Every later decision reads the plan from your database and treats the exchange as a noisy mirror to reconcile against, not as the state itself. Exchanges lose orders, expire them, rename statuses and paginate history; your plan table does not. When your process crashes mid-run, recovery is a plain re-read of the plan against current exchange state.
2. From the API fields to a full ladder: the formula
Your runner receives, per instrument: martingale_score, startingale, delta_price (a fraction, e.g. 0.08), nb_rounds (4 or 5), multipliers (array of level-to-level ratios, currently between 2 and 2.5) and initial_bet_ratio (dimensionless fraction of the budget). No prices, no quantities, no amounts: the user supplies the budget, the market supplies the entry price, the formula below supplies everything else.
⚠️ The multipliers scale QUANTITIES, never dollar costs.
R2_qty = R1_qty x multipliers[0]. Because deeper levels buy at lower prices, the cost ratio between levels is smaller than the quantity multiplier. Applying the multipliers to bet amounts instead of token quantities is the single most common integration bug, and it silently breaks the whole structure.
With budget (user input) and entry_price (live market price at start):
- Level prices:
price[n] = entry_price x (1 - delta_price x (n - 1))forn = 1..nb_rounds(level 1 is the market entry). - Level 1 quantity:
qty[1] = (budget x initial_bet_ratio) / entry_price. - Deeper quantities (the multipliers):
qty[n] = qty[n-1] x multipliers[n-2]. - Scale to the budget: compute
cost[n] = qty[n] x price[n]; ifsum(cost) != budget, scale the level 2+ quantities proportionally so the total equals the budget exactly (keep level 1 as computed in step 2). - Exit levels:
tp[1] = entry_price x (1 + delta_price); forn >= 2,tp[n] = price[n-1](each deeper level exits at the previous level's buy price). Only one exit order is ever live, covering the full accumulated quantity (see the invariant below). - Snap everything to the venue's grids before placing anything: exit prices UP, buy prices DOWN, quantities floored to the step (section 5).
- Check the budget floor: level 1 must clear the venue's minimum order size and sit far enough above the quantity step that flooring stays negligible; otherwise refuse to start (see "Minimum viable capital", section 5).
A worked numeric example lives in llms.txt; the same logic is spelled out, field by field, by the MCP get_instrument tool.
3. The one-active-sell invariant
A martingale sequence exits everything at once, so at any moment there must be exactly one live sell order covering the full accumulated quantity. When a deeper buy fills:
- cancel the current sell order,
- verify the cancel actually went through,
- place the sell for that level from your stored template, recomputed for the new cumulative quantity.
Always cancel-then-place; never try to amend in place across venues (semantics differ, and partial amend failures leave you with two sells). If the cancel fails, stop and alert; placing a second sell is worse than having a stale one.
4. The reconciliation loop
Run a scheduled job (ours ran every 10 minutes) that, per active sequence:
- fetches open orders and recent fills for the pair,
- diffs them against the plan and the last known state,
- acts minimally: place the next replacement sell if a buy filled, re-place anything the venue expired, mark the sequence complete when the sell filled.
How to run it: any scheduler works as long as exactly one instance runs at a time. We used a serverless cron (Vercel, */10 * * * *) with a hard execution-time budget; GitHub Actions on schedule, a systemd timer or plain crontab do the same job. Match the cadence to the venue's rate budget and to score freshness (crypto regrades roughly every 40 minutes), and keep each run short: fetch, diff, act, exit.
Three hard-won rules:
- Guard against overlapping runs. Two concurrent reconciliations will double-place the replacement sell. Use a lock, a run marker, or idempotency keys per action.
- Expect states you did not cause. Users cancel orders manually, venues expire them, balances move. Treat "order not found" as a signal to re-derive from the plan, not as an error to retry blindly.
- Recover from downtime by replaying the plan, not by trusting your last in-memory state.
last_runtimestamps in the sequence row make gaps visible.
5. Price and quantity grids: where money leaks
Every venue constrains prices and quantities to per-asset grids. Ignore them and the venue silently rounds for you, and silent rounding is directional money loss. We learned this on sub-$1 assets, where blind 2-decimal rounding moved fills by more than 1% per level and produced completions below break-even that were impossible on paper.
- Fetch the grids: Binance
exchangeInfo(PRICE_FILTER.tickSize,LOT_SIZE.stepSize), KrakenAssetPairs(pair_decimals,lot_decimals), AlpacaGET /v2/assets/{symbol}(price_increment,min_trade_increment,min_order_size). - Snap directionally: sell prices round UP to the grid, buy prices round DOWN. A sell snapped down can land below your break-even; a buy snapped up overpays the level.
- Quantities floor to the step size; never round up a quantity you do not hold.
- Fallback when no grid is declared: scale decimals with price magnitude (about 5 significant digits) instead of a fixed decimal count, so micro-priced assets are not crushed.
- Cache the grids (they change rarely) but refresh on order-rejected errors.
Minimum viable capital
The grids also impose a floor on the budget. Level 1 carries the smallest quantity of the whole ladder (qty[1] = budget x initial_bet_ratio / entry_price), so it hits the limits first, and high-priced assets hit them hardest: on BTC, a venue whose minimum step is 0.001 BTC means level 1 alone must be worth that step, whatever your budget. Three checks before starting a sequence:
qty[1] >= min_order_size, and every level's cost above the venue's minimum notional (e.g. BinanceMIN_NOTIONAL);- flooring error must be negligible: when a quantity is only a few steps wide, flooring it to the grid distorts the level by several percent and the multiplier structure with it. Require every level's floored quantity to stay within ~1% of the theoretical one, which in practice means
qty[1] >= ~100 x qty_step; - derive the budget floor directly:
budget_min = max(min_order_size, 100 x qty_step) x entry_price / initial_bet_ratio. Example: BTC at $60,000 with a0.001step andinitial_bet_ratio = 0.03gives0.001 x 60000 / 0.03 = $2,000as the bare minimum, and comfort sits well above it.
Five-level sequences tighten every one of these: the same budget is spread across more levels, so initial_bet_ratio is smaller and level 1 is thinner. If the checks fail, refuse to start and report the computed budget_min to the user instead of silently placing a distorted ladder.
6. Per-venue field notes
Creating your API keys (the same hygiene on every venue): create a dedicated key for the bot, grant the minimum permissions (read + spot trade; Kraken: query funds, query orders, create and modify orders, cancel orders), never withdrawal, enable IP allowlisting to your runner's address, store the secret encrypted and show it nowhere. Test with a read-only call before the first order.
Binance. Rate limits are weight-based, not request-based: read X-MBX-USED-WEIGHT-* response headers and budget accordingly; batch reads, space out writes, and remember separate order-count caps per 10 seconds and per 24 hours. API keys support IP allowlisting: use it, and grant trade permission only, never withdrawal. Since the MiCA transition (2026), EEA residents face service restrictions: check what applies to your jurisdiction before wiring anything.
Kraken Pro. The API nonce must be strictly increasing per key; if more than one client shares a key, set the key's nonce window to ~60000 ms or you will chase phantom Invalid nonce errors. Asset naming has legacy quirks (XBT for BTC, XDG for DOGE); resolve pairs through AssetPairs by websocket name instead of guessing, and prefer USD-quoted pairs when both USD and USDC exist.
Alpaca. Crypto limit orders can rest gtc. US stock fractional orders must be time_in_force: day: they expire at market close, so every morning your loop must re-place the still-relevant buy levels from the persisted plan (this is exactly where the plan-in-database design pays off). Check the market clock and calendar endpoints before acting on stocks, and expect your order to sit unfilled overnight where crypto would have filled.
7. Simulate before any real key
Run the whole machine against a paper environment first: Alpaca's paper API simulates fills against real market data and exposes the same interface as production, so the entire loop (plan, entry, ladder, sell replacement, completion) can be validated with zero real exposure. That is exactly how we validate the model publicly: our track record runs on a paper account under a fixed rule, documented in the methodology. Simulated fills flatter you: real execution adds fees, slippage, queue position and partial fills.
8. Safety rails that earned their place
- Hard caps in code: per-sequence capital, maximum number of levels, one active sequence per instrument. Caps you "always respect manually" do not exist.
- A kill switch the loop checks on every run (a single boolean your database owns), so stopping everything never depends on a deploy.
- Alert on every unexpected state (missing template, failed cancel, unknown status). Silence is how small inconsistencies compound.
- Key hygiene: encrypt keys at rest, never log them, scope them to trading only, allowlist IPs, and prefer per-venue keys per bot.
- Append, never overwrite: keep every order row and every state transition. When something looks impossible, the audit trail is the only way to know whether it was the venue, the model, or you.
Where the data comes from
The model parameters your runner needs (score, startingale, delta_price, nb_rounds, level multipliers, initial_bet_ratio) are what Tradingale serves, identically for every subscriber, through the REST API and the MCP server. How you combine them with this handbook, and whether you automate at all, is your decision alone.
Engineering documentation for informational purposes only. Not investment advice. Trading involves significant risk of loss. Tradingale never places orders, holds funds, or gives advice.