OrderFill

TypeScript

@orderfill/sdk: Bun, Node 20+, browsers and Workers. No dependencies.

bun add @orderfill/sdk     # or: npm install @orderfill/sdk
import { OrderFill } from "@orderfill/sdk";

const client = new OrderFill({ token: process.env.ORDERFILL_API_KEY! });

const [account] = await client.accounts();
const gold = client.account(account.id);

console.log(await gold.info());
await gold.placeOrder({ symbol: "XAUUSD", side: "buy", volume: 0.1 });

Accounts

const { account, notice } = await client.connect({
  platform: "mt5", login: "477072059", password: "…", server: "Exness-MT5Trial9",
});
const all = await client.accounts();
const handle = client.account(account.id);

Trading

await handle.placeOrder({ symbol: "XAUUSD", side: "buy", volume: 0.1, stopLoss: 2395 });
await handle.placeOrder(order, "my-stable-key");   // your own idempotency key
await handle.modifyPosition(ticket, { takeProfit: 2440 });
await handle.modifyOrder(orderTicket, { price: 1.075 }); // a pending order; the rest is kept
await handle.closePosition(ticket);
await handle.closeLosing();                              // or closeAll(), closeProfitable()

const positions = await handle.positions();
const orders = await handle.orders();

Sizing and health

const { margin } = await handle.marginFor({ symbol: "XAUUSD", side: "buy", volume: 0.1 });
const { profit } = await handle.profitFor({ symbol: "XAUUSD", side: "buy", volume: 0.1, open: 2400, close: 2390 });
const last100 = await handle.candles("XAUUSD", { timeframe: "M1", count: 100 });
const { connected, tradeAllowed } = await handle.health();

instruments() carries contractSize, tickSize and tickValue for sizing from a risk amount; fills from executions() carry commission, swap and fee.

Pass your own idempotency key when you might retry after a restart; otherwise the SDK makes one per call.

Symbols

const { affix, symbols, unresolved } = await handle.symbols();
await handle.resolveSymbol("XAUUSD");                   // { brokerSymbol: "XAUUSDm", … }
await handle.setSymbolOverride("XAUUSD", "GOLD"); // pin
await handle.setSymbolOverride("XAUUSD", null);   // unpin

Streaming

import { OrderFillStream } from "@orderfill/sdk";

const stream = new OrderFillStream({ token: process.env.ORDERFILL_API_KEY! });
const stop = await stream.watch(account.id, "positions", (positions) => console.log(positions));

It reconnects with backoff and re-subscribes on its own. A rejected token is the one thing it does not retry.

Errors

import { OrderFillError } from "@orderfill/sdk";

try {
  await handle.placeOrder({ symbol: "NZDCAD", side: "buy", volume: 0.1 });
} catch (error) {
  if (error instanceof OrderFillError) {
    console.error(error.code, error.message, error.hint, error.requestId);
  }
}

On this page