
Company News
Free Business Plan Upgrades for Open Source Maintainers
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.
@moneolabs/trading
Advanced tools
Execution for AI agents: quotes, slippage bounds, TWAP and bracket orders, positions.
Execution for AI agents: quotes, slippage bounds, TWAP and bracket orders, positions.
npm install @moneolabs/trading
An agent that can only pay is half a participant. This package gives it quotes, routing, and order types that survive being left alone overnight, with the spend guard sitting between every intent and every signature.
import { createTrading, simulatedVenue } from "@moneolabs/trading";
const trading = createTrading({
venues: [simulatedVenue({ prices: { "USDG/AAPL": 1 / 309.92 } })],
quoteAsset: "USDG",
guard,
});
const quote = await trading.quote({ sell: "USDG", buy: "AAPL", notional: "1500 USDG" });
const order = await trading.execute(quote, { type: "twap", window: "30m", maxSlippage: 0.003 });
const result = await order.settled();
result.status; // "filled"
result.averagePrice; // what you actually got
result.slippage; // how far that was from the quote
quote() asks every venue that can trade the pair and returns whichever gives back the most of the
buy asset. Not the lowest fee, not the best headline price: the most units, after fees and impact.
await trading.quoteAll({ sell: "USDG", buy: "AAPL", notional: "1500 USDG" });
// [{ venue: "deep-pool", buyAmount: 4.8375 AAPL }, { venue: "thin-pool", buyAmount: 4.7930 AAPL }]
| Type | Behavior |
|---|---|
market | Fills at once inside the slippage bound. Rejected, not filled worse, if the bound is missed. |
limit | Rests until the price arrives or expiresIn passes. |
twap | Slices the notional across window, so a large order stops being the reason the price moved. |
bracket | Enters at once with takeProfit and stopLoss recorded at submission. |
TWAP slices run on absolute deadlines, not "wait gap after the last fill". Filling takes time,
and with relative sleeps that time is added to every remaining slice until the order runs past the
window it was given.
const order = await trading.execute(quote, { type: "twap", window: "30m", slices: 6 });
order.status(); // read state without waiting
await order.cancel(); // stops early, keeps what already filled, returns "partial"
Every order carries a bound. It is checked twice: against a fresh quote before the venue is touched, and against the achieved fill price after. Exceeding it rejects rather than filling worse.
const result = await (await trading.execute(quote, { maxSlippage: 0.003 })).settled();
result.status; // "rejected"
result.reason; // "price moved 2.00% against the quote, over the 0.30% bound. Nothing was filled."
result.fills; // []
A rejected order never reaches a venue, so it costs nothing. Under a guard, the reserved budget is released; a partially filled order settles for exactly what filled.
Cost basis moves with average cost, so selling half a position realizes half the gain.
await (await trading.execute(entry)).settled();
trading.position("AAPL");
// { quantity, averageCost, costBasis, marketValue, unrealized, realized }
trading.mark("AAPL", 317.40); // price for unrealized figures
await trading.close("AAPL"); // sell the whole position back to the quote asset
trading.realized(); // realized P&L across everything
Cost and proceeds have to land in the quote asset. Dollar-pegged assets convert by precision alone. Anything else needs a price, and silently guessing one is how a P&L number becomes fiction, so it is refused instead.
Venue is an interface with two methods, quote and fill. simulatedVenue is the reference
implementation: a fixed price table, configurable fees, price impact, and drift.
simulatedVenue({
prices: { "USDG/AAPL": 1 / 309.92 },
feeRate: 0.0005,
impactPerUnit: 0.00001, // price moves against larger orders
drift: 0.02, // adverse move between quote and fill
quoteTtlMs: 12_000,
});
Nothing in it is random. Given the same inputs it produces the same fills, which is the only way an
execution test is worth running. Turn drift up to watch the slippage bound do its job.
Pass a manualClock and a thirty minute TWAP takes a millisecond.
import { manualClock } from "@moneolabs/core";
const clock = manualClock(0);
const trading = createTrading({ venues, clock });
const order = await trading.execute(quote, { type: "twap", window: "30m", slices: 6 });
await clock.advance("31m");
(await order.settled()).fills; // 6
MIT
FAQs
Execution for AI agents: quotes, slippage bounds, TWAP and bracket orders, positions.
We found that @moneolabs/trading demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.