MCPcopy Create free account
hub / github.com/TraderAlice/OpenAlice / createQuantTools

Function createQuantTools

src/tool/quant.ts:15–105  ·  view source on GitHub ↗
(deps: CalcDeps)

Source from the content-addressed store, hash-verified

13import { runScript, type CalcDeps } from '@/domain/analysis/calc-v2/index'
14
15export function createQuantTools(deps: CalcDeps) {
16 return {
17 searchBars: tool({
18 description: `Find K-line sources for a symbol — returns barIds to paste into calculateQuant's bars(...).
19
20Federates connected brokers (alpaca-paper, binance-readonly, …) AND vendors (fmp, yfinance).
21Candidates come back freshest-first. Each carries:
22 - barId: use directly, e.g. bars("<barId>", "1d", count=250).
23 · broker barIds ("accountId|symbol") need NO asset= in bars().
24 · vendor barIds ("provider|symbol") need asset="equity|crypto|currency|commodity".
25 - source: "uta" (broker) | "vendor"
26 - barCapability: "realtime" | "delayed" | "iex" | "subscription".
27Source preference: a broker you actually trade (realtime, and the chart matches your fills) >
28a paid vendor (fmp, …) > yfinance. yfinance is a FREE FALLBACK only — its end-of-day bars can
29lag a day or two, so don't use it for anything time-sensitive or to chart a live position when
30a broker source exists. The same asset appears from multiple sources (redundancy is expected);
31default to the freshest broker candidate.`,
32 inputSchema: z.object({
33 query: z.string().describe('Symbol or keyword, e.g. "AAPL", "BTC", "bitcoin"'),
34 limit: z.number().int().positive().optional().describe('Max candidates (default 20)'),
35 }).meta({ examples: [{ query: 'AAPL' }] }),
36 execute: async ({ query, limit }) => {
37 const candidates = await deps.barService.searchBarSources(query, limit != null ? { limit } : undefined)
38 return { candidates, count: candidates.length }
39 },
40 }),
41
42 calculateQuant: tool({
43 description: `Run a technical-analysis script over K-lines from explicit sources (barId-keyed).
44Get barIds from \`searchBars\` first (or \`searchContracts\` for broker-only).
45
46A script is one or more \`name = bars(...)\` bindings followed by a final result expression:
47
48 s = bars("alpaca-paper|AAPL", "1d", count=250)
49 sma(s.close, 50) - sma(s.close, 200)
50
51bars(barId, interval, count=, asOf=, start=, end=, asset=):
52 - barId: "{source}|{symbol}" from searchBars (broker, e.g. "alpaca-paper|AAPL",
53 "binance-readonly|BTC/USDT") or a vendor ("yfinance|AAPL", "fmp|AAPL"). Prefer a broker
54 barId for anything you trade or anything time-sensitive — yfinance is a delayed free
55 fallback (EOD bars can lag a day or two).
56 - interval: "1m" "5m" "15m" "30m" "1h" "4h" "1d" "1w".
57 - count=N: number of most-recent bars (the natural window for indicators).
58 - asset=: REQUIRED for vendor barIds — "equity" | "crypto" | "currency" | "commodity".
59 (Broker barIds infer it.)
60Series columns: s.open / s.high / s.low / s.close / s.volume
61Functions: sma(series, n), ema(series, n), stdev(series), max/min/sum/average/median(series),
62 rsi(series, n=14), bbands(series, n, std), macd(series, fast, slow, signal),
63 atr(high, low, close, n), rvol(volume, n=20), obv(close, volume),
64 mfi(high, low, close, volume, n=14), vwap(high, low, close, volume),
65 roc(series, n) [% change over n], zscore(series, n?) [how extended vs trailing window],
66 slope(series, n) [linreg trend, signed/rankable], correlation(seriesA, seriesB) [−1..1],
67 highest(series, n), lowest(series, n).
68Indicators return the LATEST value directly (a scalar) — do NOT index them.
69Only raw columns are series: index them with s.close[-1] (latest), s.close[-n] (n-back).
70Arithmetic: + - * /.
71
72Panels — batch many computations in ONE call (avoids calling this tool N times).

Callers 3

mainFunction · 0.85
quant.spec.tsFile · 0.85

Calls 2

runScriptFunction · 0.90
searchBarSourcesMethod · 0.80

Tested by

no test coverage detected