Mercury Trading

Automated trading against Capital.com, running on Cloudflare Workers.

A strategy here is a single function. It receives sorted candles, open trades and account state, and returns typed decisions — LONG, EXIT_POSITION, ADJUST_ORDER and the rest — each with the reason it was made.

The backtester hands those decisions to a simulated broker; the cron worker hands the identical decisions to Capital.com. There is no second implementation to drift, so a backtest describes what the same code would have done live.

Open the chartsSign inCreate an accountCharts and the trainer are open without an account.

Where things live

The four sections in the sidebar, and what each one holds.

Data

Historical candles for any epic and resolution, drawn by the chart renderer the rest of the app uses.

Overlay moving averages, MACD, RSI, Bollinger bands, fair value gaps and liquidity pools. Chart settings you change here are saved to your profile.

Backtesting

Account

Replay a strategy over a date range against a simulated broker, then read back every trade and decision it made.

Groups sweep one strategy variable across several values so variants can be compared in a single run. Debug level controls how much a run records — funds, then trades, then decisions, then raw inputs.

Sign in to open

Campaigns

Account

A strategy bound to one trading account, a set of epics and the resolutions it reads.

A campaign carries its own strategy variables, so two campaigns can run the same strategy tuned differently. `demo` picks which Capital.com environment it talks to; `enact` decides whether its decisions are actually sent.

Sign in to open

Trading accounts

Account

Your linked Capital.com accounts, with balance, open positions and the trades taken against them.

Each account page carries its own chart, so a trade can be opened on the candles it was taken on, with its entry, stop and any later adjustments drawn in.

Sign in to open

What happens every five minutes

The cron worker wakes on a five-minute schedule and walks every active campaign through the same four steps.

  1. 01Context is builtOne Capital.com session is opened per user, market details are fetched once per distinct epic, and an account session is built per account. Campaigns watching the same market share that work.
  2. 02The strategy runsEach campaign's strategy function is called with its sorted candles, its open trades and the current account state. It returns a list of typed decisions and the reason for each.
  3. 03Guards are appliedOn a live account, balance must be above the floor or the whole cycle bails out, and any LONG or SHORT without a stop loss is dropped and logged. Demo campaigns skip both.
  4. 04Results are recordedEnacted decisions become orders and positions on Capital.com; the decision, its reasoning and the resulting trade are written to the ledger you can read on the campaign page.

What a strategy looks like

Strategies live in common/strategies and are registered by key. A campaign names one of those keys, so the same strategy can run on several accounts with different variables.

Nothing in the function touches the network or the database. It reads what it was given and returns decisions, which is why the backtester and the cron worker can both call it unchanged.

Every decision carries a reason, and that string is stored with the trade. Months later the record still says why the position was opened.

common/strategies/strategyNaturalv2.ts
// The same function the backtester and the live cron call.
export const strategyNaturalv2 = ({
sortedCandles,
accountDetails,
campaign,
}: DecisionParams<"naturalv2">) => {
const edges = getEdges(sortedCandles.primary);
if (!edges.confirmedLow) {
return { decisions: [doNothingDueToNothingGoingOn()] };
}
return {
decisions: [
{
type: "LONG",
tag: "LONG1",
reason: "Confirmed low, trend aligned",
size: getSize(accountDetails, campaign),
entryLevel: edges.confirmedLow.high,
stopLoss: edges.confirmedLow.low,
},
],
};
};

Before you let a campaign trade

  • A campaign only sends anything to the broker when enact is on. Leave it off and the campaign still runs, still records its decisions, and touches nothing.
  • demo selects the Capital.com demo environment. Run there until the decision log looks like the backtest did.
  • The live guards are a floor, not a strategy. They stop a live account trading below a minimum balance and refuse any entry without a stop loss — everything else about risk is the strategy's own job.
  • A backtest describes the candles it was run on. Slippage, spread widening and gaps behave differently in a live book, so treat the result as the optimistic case rather than a forecast.
  • Trading carries risk of loss. Positions opened here are real positions on a real account unless you have explicitly kept the campaign on demo.