kestrel.markets
Version:
A typed, token-efficient language + runtime for agentic trading: agents author bounded plans, the runtime fires them at the tick. CLI + typed library + MCP server.
147 lines (145 loc) • 3.97 kB
JavaScript
import"./bin-q0g6xvsw.js";
import"./bin-pcxsrxfy.js";
import"./bin-8gxcgtzn.js";
import"./bin-5t125gvh.js";
import"./bin-xx1qrxe3.js";
import"./bin-t58k60v9.js";
import"./bin-p5jfg5b0.js";
import"./bin-29be75ss.js";
import"./bin-n77kea5n.js";
import"./bin-mn7wcxhv.js";
import"./bin-8pchjxn2.js";
import"./bin-am3351y2.js";
import"./bin-73jr945c.js";
import"./bin-df1tn094.js";
import"./bin-3ft0k1jq.js";
import"./bin-2ywrx58g.js";
import {
require_dist
} from "./bin-ah4h5nq5.js";
import"./bin-ff04wpv3.js";
import {
__toESM
} from "./bin-wckvcay0.js";
// src/adapters/broker/ibkr/order-dryrun.ts
var import_ib = __toESM(require_dist(), 1);
var IB_TICK_BID = 1;
var IB_TICK_ASK = 2;
var IB_TICK_LAST = 4;
var IB_TICK_DELAYED_BID = 66;
var IB_TICK_DELAYED_ASK = 67;
var IB_TICK_DELAYED_LAST = 68;
var IB_MARKET_DATA_LIVE = 1;
function freshnessOf(marketDataType) {
switch (marketDataType) {
case 1:
return "live";
case 2:
return "frozen";
case 3:
return "delayed";
case 4:
return "delayed-frozen";
default:
return "unknown";
}
}
function reqMktDataQuotes(transport, timeoutMs = 6000) {
const client = transport.client();
let reqId = 9000;
client.reqMarketDataType(IB_MARKET_DATA_LIVE);
return {
quote(contract) {
const id = ++reqId;
return new Promise((resolve) => {
let bid = null;
let ask = null;
let last = null;
let freshness = "unknown";
let done = false;
const finish = () => {
if (done)
return;
done = true;
clearTimeout(deadline);
client.removeListener(import_ib.EventName.tickPrice, onTick);
client.removeListener(import_ib.EventName.marketDataType, onType);
try {
client.cancelMktData(id);
} catch {}
resolve({ bid, ask, last, freshness });
};
const onType = (rid, marketDataType) => {
if (rid !== id)
return;
freshness = freshnessOf(marketDataType);
};
const onTick = (rid, field, value) => {
if (rid !== id)
return;
const v = value > 0 ? value : null;
switch (field) {
case IB_TICK_BID:
bid = v;
break;
case IB_TICK_ASK:
ask = v;
break;
case IB_TICK_LAST:
last = v;
break;
case IB_TICK_DELAYED_BID:
bid = v;
freshness = "delayed";
break;
case IB_TICK_DELAYED_ASK:
ask = v;
freshness = "delayed";
break;
case IB_TICK_DELAYED_LAST:
last = v;
freshness = "delayed";
break;
default:
return;
}
if (bid !== null && ask !== null)
finish();
};
const deadline = setTimeout(finish, timeoutMs);
client.on(import_ib.EventName.tickPrice, onTick);
client.on(import_ib.EventName.marketDataType, onType);
client.reqMktData(id, contract, null, false, false);
});
}
};
}
function priceAnchorFrom(quote, fair) {
if (quote.bid === null || quote.ask === null)
return;
if (quote.freshness !== "live")
return;
return { bid: quote.bid, ask: quote.ask, fair, fairTrusted: true, freshness: quote.freshness };
}
function mintOrderId(client) {
let next;
client.on(import_ib.EventName.nextValidId, (id) => {
if (next === undefined || id > next)
next = id;
});
client.reqIds(1);
return () => {
if (next === undefined) {
throw new Error("the IB Gateway has issued no nextValidId — refusing to invent an order id (it could collide with a live order). Fail-closed.");
}
const id = next;
next += 1;
return id;
};
}
if (false) {}
export {
reqMktDataQuotes,
priceAnchorFrom,
mintOrderId
};