🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@moneolabs/trading

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@moneolabs/trading

Execution for AI agents: quotes, slippage bounds, TWAP and bracket orders, positions.

latest
Source
npmnpm
Version
0.4.0
Version published
Maintainers
1
Created
Source

@moneolabs/trading

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.

Use

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

Routing

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 }]

Order types

TypeBehavior
marketFills at once inside the slippage bound. Rejected, not filled worse, if the bound is missed.
limitRests until the price arrives or expiresIn passes.
twapSlices the notional across window, so a large order stops being the reason the price moved.
bracketEnters 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"

Slippage

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.

Positions

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.

Venues

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.

Testing

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

License

MIT

Keywords

ai-agents

FAQs

Package last updated on 05 Aug 2026

Did you know?

Socket

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.

Install

Related posts