@livefolio/sdk 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -146
- package/dist/strategy/backtest.d.ts +3 -0
- package/dist/strategy/backtest.d.ts.map +1 -0
- package/dist/strategy/backtest.js +7 -0
- package/dist/strategy/backtest.js.map +1 -0
- package/dist/strategy/cache.d.ts +7 -0
- package/dist/strategy/cache.d.ts.map +1 -0
- package/dist/strategy/cache.js +312 -0
- package/dist/strategy/cache.js.map +1 -0
- package/dist/strategy/client.d.ts.map +1 -1
- package/dist/strategy/client.js +9 -333
- package/dist/strategy/client.js.map +1 -1
- package/dist/strategy/get.d.ts +5 -0
- package/dist/strategy/get.d.ts.map +1 -0
- package/dist/strategy/get.js +25 -0
- package/dist/strategy/get.js.map +1 -0
- package/dist/strategy/index.d.ts +5 -1
- package/dist/strategy/index.d.ts.map +1 -1
- package/dist/strategy/index.js +10 -1
- package/dist/strategy/index.js.map +1 -1
- package/dist/strategy/stream.d.ts +5 -0
- package/dist/strategy/stream.d.ts.map +1 -0
- package/dist/strategy/stream.js +58 -0
- package/dist/strategy/stream.js.map +1 -0
- package/dist/strategy/types.d.ts +6 -0
- package/dist/strategy/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,9 +8,7 @@ TypeScript SDK for market data, strategy evaluation, and portfolio management.
|
|
|
8
8
|
npm install @livefolio/sdk
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
All modules are created from a single Supabase client:
|
|
11
|
+
## Quick Start
|
|
14
12
|
|
|
15
13
|
```ts
|
|
16
14
|
import { createLivefolioClient } from '@livefolio/sdk';
|
|
@@ -20,171 +18,47 @@ const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
|
|
|
20
18
|
const livefolio = createLivefolioClient(supabase);
|
|
21
19
|
```
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
```ts
|
|
26
|
-
import { createMarket } from '@livefolio/sdk/market';
|
|
27
|
-
import { createAuth } from '@livefolio/sdk/auth';
|
|
28
|
-
import { createStrategy } from '@livefolio/sdk/strategy';
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## Auth
|
|
34
|
-
|
|
35
|
-
Wraps Supabase Auth with a simplified interface.
|
|
36
|
-
|
|
37
|
-
| Method | Returns | Description |
|
|
38
|
-
|--------|---------|-------------|
|
|
39
|
-
| `getUser()` | `User \| null` | Get the current authenticated user, or `null` if not signed in |
|
|
40
|
-
| `getSession()` | `Session \| null` | Get the current session |
|
|
41
|
-
| `requireUser()` | `User` | Get the current user or throw if not authenticated |
|
|
42
|
-
| `onAuthStateChange(callback)` | `Subscription` | Subscribe to auth state changes (sign in, sign out, token refresh) |
|
|
43
|
-
| `signOut()` | `void` | Sign out the current user |
|
|
44
|
-
|
|
45
|
-
```ts
|
|
46
|
-
const user = await livefolio.auth.getUser();
|
|
47
|
-
|
|
48
|
-
const subscription = livefolio.auth.onAuthStateChange((event, session) => {
|
|
49
|
-
console.log(event, session);
|
|
50
|
-
});
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## Market
|
|
56
|
-
|
|
57
|
-
Provides historical price series, real-time quotes, and the trading calendar. Series and quotes are served through Supabase Edge Functions with transparent cache-through behavior — the SDK requests data and caching is handled server-side.
|
|
58
|
-
|
|
59
|
-
### Series
|
|
60
|
-
|
|
61
|
-
Retrieve historical daily observations for one or more symbols. Each observation has an ISO 8601 `timestamp` (market close) and a `value` (closing price).
|
|
62
|
-
|
|
63
|
-
```ts
|
|
64
|
-
const spy = await livefolio.market.getSeries('SPY');
|
|
65
|
-
// spy: Observation[] — [{ timestamp: '2025-01-10T21:00:00Z', value: 590.25 }, ...]
|
|
66
|
-
|
|
67
|
-
const batch = await livefolio.market.getBatchSeries(['SPY', 'QQQ', 'TLT']);
|
|
68
|
-
// batch: Record<string, Observation[]> — { SPY: [...], QQQ: [...], TLT: [...] }
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### Quotes
|
|
21
|
+
## Modules
|
|
72
22
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const quotes = await livefolio.market.getBatchQuotes(['SPY', 'QQQ']);
|
|
80
|
-
// quotes: Record<string, Observation>
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### Trading Calendar
|
|
84
|
-
|
|
85
|
-
Query the trading calendar for market open/close times. Dates are `YYYY-MM-DD` strings.
|
|
86
|
-
|
|
87
|
-
```ts
|
|
88
|
-
const days = await livefolio.market.getTradingDays('2025-01-01', '2025-12-31');
|
|
89
|
-
// days: TradingDay[] — [{ date, open, close, extended_open, extended_close }, ...]
|
|
90
|
-
|
|
91
|
-
const today = await livefolio.market.getTradingDay('2025-03-02');
|
|
92
|
-
// today: TradingDay | null
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
---
|
|
96
|
-
|
|
97
|
-
## Strategy
|
|
98
|
-
|
|
99
|
-
Handles strategy retrieval, evaluation, and result caching. The module exposes two evaluation paths:
|
|
100
|
-
|
|
101
|
-
- **`evaluate()`** (async) — the primary API. Checks the DB cache for a prior result, returns it on hit, or runs a fresh evaluation and stores the result on miss. Consumers never need to manage caching manually.
|
|
102
|
-
- **Pure functions** (sync) — `evaluateIndicator`, `evaluateSignal`, `evaluateAllocation` for direct computation without DB interaction. Useful for testing, debugging, or custom pipelines.
|
|
103
|
-
|
|
104
|
-
### Retrieving Strategies
|
|
105
|
-
|
|
106
|
-
Fetch a fully-resolved strategy by its link ID. The `get()` method calls the `strategy` edge function, which looks up the strategy in the database and auto-imports from testfol.io if not found. The returned `Strategy` object contains all named signals, indicators, condition trees, and allocations ready for evaluation.
|
|
107
|
-
|
|
108
|
-
```ts
|
|
109
|
-
const strategy = await livefolio.strategy.get('abc-123');
|
|
110
|
-
// strategy: Strategy | null
|
|
111
|
-
|
|
112
|
-
const strategies = await livefolio.strategy.getMany(['abc-123', 'def-456']);
|
|
113
|
-
// strategies: Record<string, Strategy>
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### Evaluating a Strategy
|
|
117
|
-
|
|
118
|
-
The `evaluate` method is the standard way to run a strategy. Pass a strategy and a date — everything else is handled internally:
|
|
119
|
-
|
|
120
|
-
1. Fetches historical series for all symbols used by the strategy
|
|
121
|
-
2. Computes the evaluation date
|
|
122
|
-
3. Checks the DB cache for a prior result on that trading day
|
|
123
|
-
4. On cache miss: fetches prior signal states (for hysteresis) and indicator metadata (for incremental EMA/RSI), runs the evaluation, and stores the result
|
|
124
|
-
5. On cache hit: returns the cached allocation and signal states
|
|
23
|
+
| Module | Description |
|
|
24
|
+
|--------|-------------|
|
|
25
|
+
| `livefolio.auth` | Authentication (user, session, sign-out) |
|
|
26
|
+
| `livefolio.market` | Historical series, real-time quotes, trading calendar |
|
|
27
|
+
| `livefolio.strategy` | Strategy retrieval, cached evaluation, live streaming |
|
|
28
|
+
| `livefolio.portfolio` | Brokerage account aggregation (stub) |
|
|
125
29
|
|
|
126
30
|
```ts
|
|
31
|
+
// Fetch and evaluate a strategy
|
|
127
32
|
const strategy = await livefolio.strategy.get('abc-123');
|
|
128
33
|
if (strategy) {
|
|
129
34
|
const result = await livefolio.strategy.evaluate(strategy, new Date());
|
|
130
|
-
|
|
131
|
-
result.allocation; // the winning allocation (name, holdings)
|
|
132
|
-
result.asOf; // Date the evaluation corresponds to (trading day market close)
|
|
133
|
-
result.signals; // Record<string, boolean> — all signal states
|
|
134
|
-
result.indicators; // Record<string, IndicatorEvaluation> — all indicator values
|
|
35
|
+
console.log(result.allocation.name, result.allocation.holdings);
|
|
135
36
|
}
|
|
136
|
-
```
|
|
137
37
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
| `extractSymbols(strategy)` | `string[]` | Collect all ticker symbols needed to evaluate a strategy (from signals + holdings) |
|
|
143
|
-
| `getEvaluationDate(trading, options)` | `Date` | Compute the evaluation date — requires `EvaluationOptions` with series data |
|
|
144
|
-
|
|
145
|
-
### Pure Evaluation Functions
|
|
38
|
+
// Market data
|
|
39
|
+
const series = await livefolio.market.getBatchSeries(['SPY', 'BND']);
|
|
40
|
+
const quote = await livefolio.market.getQuote('SPY');
|
|
41
|
+
```
|
|
146
42
|
|
|
147
|
-
|
|
43
|
+
Modules can also be imported individually:
|
|
148
44
|
|
|
149
45
|
```ts
|
|
150
|
-
import {
|
|
151
|
-
|
|
152
|
-
// Evaluate a single indicator
|
|
153
|
-
const smaResult = livefolio.strategy.evaluateIndicator(indicator, options);
|
|
154
|
-
|
|
155
|
-
// Evaluate a signal (comparison of two indicators)
|
|
156
|
-
const isAbove = livefolio.strategy.evaluateSignal(signal, options);
|
|
157
|
-
|
|
158
|
-
// Evaluate a full allocation condition tree
|
|
159
|
-
const matches = livefolio.strategy.evaluateAllocation(allocation, options);
|
|
46
|
+
import { createMarket } from '@livefolio/sdk/market';
|
|
47
|
+
import { createStrategy } from '@livefolio/sdk/strategy';
|
|
160
48
|
```
|
|
161
49
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
## Portfolio
|
|
50
|
+
## Documentation
|
|
165
51
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
---
|
|
52
|
+
Full method reference, arguments, return types, and usage examples: **[docs/](./docs/)**
|
|
169
53
|
|
|
170
54
|
## Development
|
|
171
55
|
|
|
172
56
|
```bash
|
|
173
|
-
npm install
|
|
174
57
|
npm run build # compile TypeScript → dist/
|
|
175
58
|
npm test # run tests
|
|
176
59
|
```
|
|
177
60
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
- PRs to `main` run build + tests and enforce a version bump
|
|
181
|
-
- Merges to `main` auto-publish to npm and create a GitHub release
|
|
182
|
-
|
|
183
|
-
Before merging, bump the version:
|
|
184
|
-
|
|
185
|
-
```bash
|
|
186
|
-
npm version patch
|
|
187
|
-
```
|
|
61
|
+
PRs to `main` run build + tests and enforce a version bump. Merges auto-publish to npm.
|
|
188
62
|
|
|
189
63
|
## License
|
|
190
64
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backtest.d.ts","sourceRoot":"","sources":["../../src/strategy/backtest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzE,wBAAsB,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAEtG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backtest.js","sourceRoot":"","sources":["../../src/strategy/backtest.ts"],"names":[],"mappings":";;AAEA,4BAEC;AAFM,KAAK,UAAU,QAAQ,CAAC,SAAmB,EAAE,QAAyB;IAC3E,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { TypedSupabaseClient } from '../types';
|
|
2
|
+
import type { MarketModule } from '../market/types';
|
|
3
|
+
import type { Strategy, StrategyEvaluation } from './types';
|
|
4
|
+
export declare function fetchSignalStates(client: TypedSupabaseClient, strategyId: number): Promise<Record<string, boolean>>;
|
|
5
|
+
export declare function fetchIndicatorMetadata(client: TypedSupabaseClient, strategyId: number): Promise<Record<string, unknown>>;
|
|
6
|
+
export declare function evaluateCached(client: TypedSupabaseClient, market: MarketModule, strategy: Strategy, at: Date): Promise<StrategyEvaluation>;
|
|
7
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/strategy/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAIV,QAAQ,EACR,kBAAkB,EAKnB,MAAM,SAAS,CAAC;AAoEjB,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,mBAAmB,EAC3B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA6ClC;AA4HD,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,mBAAmB,EAC3B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA+BlC;AAgDD,wBAAsB,cAAc,CAClC,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,QAAQ,EAClB,EAAE,EAAE,IAAI,GACP,OAAO,CAAC,kBAAkB,CAAC,CAwF7B"}
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchSignalStates = fetchSignalStates;
|
|
4
|
+
exports.fetchIndicatorMetadata = fetchIndicatorMetadata;
|
|
5
|
+
exports.evaluateCached = evaluateCached;
|
|
6
|
+
const evaluate_1 = require("./evaluate");
|
|
7
|
+
const symbols_1 = require("./symbols");
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Row → domain mapping helpers
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
function mapTicker(row) {
|
|
12
|
+
return { symbol: row.symbol, leverage: row.leverage };
|
|
13
|
+
}
|
|
14
|
+
function mapIndicator(row) {
|
|
15
|
+
return {
|
|
16
|
+
type: row.type,
|
|
17
|
+
ticker: row.tickers ? mapTicker(row.tickers) : { symbol: '', leverage: 1 },
|
|
18
|
+
lookback: row.lookback,
|
|
19
|
+
delay: row.delay,
|
|
20
|
+
unit: row.unit ?? null,
|
|
21
|
+
threshold: row.threshold,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function mapSignal(row) {
|
|
25
|
+
return {
|
|
26
|
+
left: mapIndicator(row.indicator_1),
|
|
27
|
+
comparison: row.comparison,
|
|
28
|
+
right: mapIndicator(row.indicator_2),
|
|
29
|
+
tolerance: row.tolerance,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// DB helpers
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
async function fetchSignalStates(client, strategyId) {
|
|
36
|
+
const db = client;
|
|
37
|
+
const { data: nsRows, error: nsErr } = await db
|
|
38
|
+
.from('named_signals')
|
|
39
|
+
.select(`
|
|
40
|
+
signal_id,
|
|
41
|
+
signals:signal_id (
|
|
42
|
+
id,
|
|
43
|
+
indicator_1:indicator_id_1 ( type, tickers:ticker_id ( symbol, leverage ), lookback, delay, unit, threshold ),
|
|
44
|
+
indicator_2:indicator_id_2 ( type, tickers:ticker_id ( symbol, leverage ), lookback, delay, unit, threshold ),
|
|
45
|
+
comparison,
|
|
46
|
+
tolerance
|
|
47
|
+
)
|
|
48
|
+
`)
|
|
49
|
+
.eq('strategy_id', strategyId);
|
|
50
|
+
if (nsErr || !nsRows || nsRows.length === 0)
|
|
51
|
+
return {};
|
|
52
|
+
const signalIds = nsRows.map((r) => r.signal_id);
|
|
53
|
+
const { data: evalRows, error: evalErr } = await client
|
|
54
|
+
.from('signal_evaluations')
|
|
55
|
+
.select('signal_id, result, trading_day_id')
|
|
56
|
+
.in('signal_id', signalIds)
|
|
57
|
+
.order('trading_day_id', { ascending: false });
|
|
58
|
+
if (evalErr || !evalRows)
|
|
59
|
+
return {};
|
|
60
|
+
const latestBySignalId = new Map();
|
|
61
|
+
for (const row of evalRows) {
|
|
62
|
+
if (!latestBySignalId.has(row.signal_id)) {
|
|
63
|
+
latestBySignalId.set(row.signal_id, row.result);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const result = {};
|
|
67
|
+
for (const nsRow of nsRows) {
|
|
68
|
+
const signal = mapSignal(nsRow.signals);
|
|
69
|
+
const key = (0, evaluate_1.signalKey)(signal);
|
|
70
|
+
const val = latestBySignalId.get(nsRow.signal_id);
|
|
71
|
+
if (val !== undefined) {
|
|
72
|
+
result[key] = val;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
async function fetchSignalStatesForDay(client, strategyId, tradingDayId) {
|
|
78
|
+
const db = client;
|
|
79
|
+
const { data: nsRows, error: nsErr } = await db
|
|
80
|
+
.from('named_signals')
|
|
81
|
+
.select(`
|
|
82
|
+
signal_id,
|
|
83
|
+
signals:signal_id (
|
|
84
|
+
id,
|
|
85
|
+
indicator_1:indicator_id_1 ( type, tickers:ticker_id ( symbol, leverage ), lookback, delay, unit, threshold ),
|
|
86
|
+
indicator_2:indicator_id_2 ( type, tickers:ticker_id ( symbol, leverage ), lookback, delay, unit, threshold ),
|
|
87
|
+
comparison,
|
|
88
|
+
tolerance
|
|
89
|
+
)
|
|
90
|
+
`)
|
|
91
|
+
.eq('strategy_id', strategyId);
|
|
92
|
+
if (nsErr || !nsRows || nsRows.length === 0)
|
|
93
|
+
return {};
|
|
94
|
+
const signalIds = nsRows.map((r) => r.signal_id);
|
|
95
|
+
const { data: evalRows, error: evalErr } = await client
|
|
96
|
+
.from('signal_evaluations')
|
|
97
|
+
.select('signal_id, result')
|
|
98
|
+
.in('signal_id', signalIds)
|
|
99
|
+
.eq('trading_day_id', tradingDayId);
|
|
100
|
+
if (evalErr || !evalRows)
|
|
101
|
+
return {};
|
|
102
|
+
const signalIdToResult = new Map();
|
|
103
|
+
for (const row of evalRows) {
|
|
104
|
+
signalIdToResult.set(row.signal_id, row.result);
|
|
105
|
+
}
|
|
106
|
+
const result = {};
|
|
107
|
+
for (const nsRow of nsRows) {
|
|
108
|
+
const signal = mapSignal(nsRow.signals);
|
|
109
|
+
const key = (0, evaluate_1.signalKey)(signal);
|
|
110
|
+
const val = signalIdToResult.get(nsRow.signal_id);
|
|
111
|
+
if (val !== undefined) {
|
|
112
|
+
result[key] = val;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
async function fetchIndicatorKeyMap(client, strategyId) {
|
|
118
|
+
const db = client;
|
|
119
|
+
const { data: nsRows, error: nsErr } = await db
|
|
120
|
+
.from('named_signals')
|
|
121
|
+
.select(`
|
|
122
|
+
signals:signal_id (
|
|
123
|
+
indicator_1:indicator_id_1 ( id, type, tickers:ticker_id ( symbol, leverage ), lookback, delay, unit, threshold ),
|
|
124
|
+
indicator_2:indicator_id_2 ( id, type, tickers:ticker_id ( symbol, leverage ), lookback, delay, unit, threshold )
|
|
125
|
+
)
|
|
126
|
+
`)
|
|
127
|
+
.eq('strategy_id', strategyId);
|
|
128
|
+
if (nsErr || !nsRows || nsRows.length === 0)
|
|
129
|
+
return new Map();
|
|
130
|
+
const keyToId = new Map();
|
|
131
|
+
for (const nsRow of nsRows) {
|
|
132
|
+
for (const ind of [nsRow.signals.indicator_1, nsRow.signals.indicator_2]) {
|
|
133
|
+
const key = (0, evaluate_1.indicatorKey)(mapIndicator(ind));
|
|
134
|
+
if (!keyToId.has(key)) {
|
|
135
|
+
keyToId.set(key, ind.id);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return keyToId;
|
|
140
|
+
}
|
|
141
|
+
async function fetchIndicatorEvaluationsForDay(client, strategyId, tradingDayId) {
|
|
142
|
+
const db = client;
|
|
143
|
+
const keyToId = await fetchIndicatorKeyMap(client, strategyId);
|
|
144
|
+
if (keyToId.size === 0)
|
|
145
|
+
return {};
|
|
146
|
+
const indicatorIds = [...keyToId.values()];
|
|
147
|
+
const { data: evalRows, error: evalErr } = await db
|
|
148
|
+
.from('indicator_evaluations')
|
|
149
|
+
.select('indicator_id, value, metadata, trading_days!inner(post)')
|
|
150
|
+
.in('indicator_id', indicatorIds)
|
|
151
|
+
.eq('trading_day_id', tradingDayId);
|
|
152
|
+
if (evalErr || !evalRows)
|
|
153
|
+
return {};
|
|
154
|
+
const byIndicatorId = new Map();
|
|
155
|
+
for (const row of evalRows) {
|
|
156
|
+
byIndicatorId.set(row.indicator_id, {
|
|
157
|
+
value: Number(row.value),
|
|
158
|
+
metadata: row.metadata,
|
|
159
|
+
post: row.trading_days.post,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
const result = {};
|
|
163
|
+
for (const [key, id] of keyToId) {
|
|
164
|
+
const entry = byIndicatorId.get(id);
|
|
165
|
+
if (entry) {
|
|
166
|
+
result[key] = {
|
|
167
|
+
timestamp: entry.post,
|
|
168
|
+
value: entry.value,
|
|
169
|
+
...(entry.metadata != null ? { metadata: entry.metadata } : {}),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
async function fetchIndicatorMetadata(client, strategyId) {
|
|
176
|
+
const db = client;
|
|
177
|
+
const keyToId = await fetchIndicatorKeyMap(client, strategyId);
|
|
178
|
+
if (keyToId.size === 0)
|
|
179
|
+
return {};
|
|
180
|
+
const indicatorIds = [...keyToId.values()];
|
|
181
|
+
const { data: evalRows, error: evalErr } = await db
|
|
182
|
+
.from('indicator_evaluations')
|
|
183
|
+
.select('indicator_id, metadata, trading_day_id')
|
|
184
|
+
.in('indicator_id', indicatorIds)
|
|
185
|
+
.order('trading_day_id', { ascending: false });
|
|
186
|
+
if (evalErr || !evalRows)
|
|
187
|
+
return {};
|
|
188
|
+
const latestByIndicatorId = new Map();
|
|
189
|
+
for (const row of evalRows) {
|
|
190
|
+
if (!latestByIndicatorId.has(row.indicator_id) && row.metadata != null) {
|
|
191
|
+
latestByIndicatorId.set(row.indicator_id, row.metadata);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const result = {};
|
|
195
|
+
for (const [key, id] of keyToId) {
|
|
196
|
+
const meta = latestByIndicatorId.get(id);
|
|
197
|
+
if (meta !== undefined) {
|
|
198
|
+
result[key] = meta;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return result;
|
|
202
|
+
}
|
|
203
|
+
async function storeResult(client, strategy, result, tradingDayId) {
|
|
204
|
+
const db = client;
|
|
205
|
+
const { data: stratRow } = await client
|
|
206
|
+
.from('strategies')
|
|
207
|
+
.select('id')
|
|
208
|
+
.eq('link_id', strategy.linkId)
|
|
209
|
+
.limit(1)
|
|
210
|
+
.maybeSingle();
|
|
211
|
+
const signalResults = Object.entries(result.signals).map(([_key, sigResult]) => {
|
|
212
|
+
const ns = strategy.signals.find((ns) => (0, evaluate_1.signalKey)(ns.signal) === _key);
|
|
213
|
+
return { name: ns?.name ?? _key, result: sigResult };
|
|
214
|
+
});
|
|
215
|
+
const keyToId = stratRow ? await fetchIndicatorKeyMap(client, stratRow.id) : new Map();
|
|
216
|
+
const indicatorResults = Object.entries(result.indicators)
|
|
217
|
+
.filter(([key]) => keyToId.has(key))
|
|
218
|
+
.map(([key, indResult]) => ({
|
|
219
|
+
indicatorId: keyToId.get(key),
|
|
220
|
+
value: indResult.value,
|
|
221
|
+
metadata: indResult.metadata ?? null,
|
|
222
|
+
}));
|
|
223
|
+
const { error } = await db.rpc('upsert_evaluation', {
|
|
224
|
+
p_link_id: strategy.linkId,
|
|
225
|
+
p_allocation_name: result.allocation.name,
|
|
226
|
+
p_signal_results: signalResults,
|
|
227
|
+
p_indicator_results: indicatorResults,
|
|
228
|
+
p_trading_day_id: tradingDayId,
|
|
229
|
+
});
|
|
230
|
+
if (error)
|
|
231
|
+
throw new Error(`Failed to store evaluation: ${error.message}`);
|
|
232
|
+
}
|
|
233
|
+
// ---------------------------------------------------------------------------
|
|
234
|
+
// Cache-through evaluation (exported)
|
|
235
|
+
// ---------------------------------------------------------------------------
|
|
236
|
+
async function evaluateCached(client, market, strategy, at) {
|
|
237
|
+
const db = client;
|
|
238
|
+
// 1. Fetch series + resolve strategy_id in parallel
|
|
239
|
+
const symbols = (0, symbols_1.extractSymbols)(strategy);
|
|
240
|
+
const [batchSeries, stratRow] = await Promise.all([
|
|
241
|
+
market.getBatchSeries(symbols),
|
|
242
|
+
client
|
|
243
|
+
.from('strategies')
|
|
244
|
+
.select('id')
|
|
245
|
+
.eq('link_id', strategy.linkId)
|
|
246
|
+
.limit(1)
|
|
247
|
+
.maybeSingle()
|
|
248
|
+
.then(({ data }) => data),
|
|
249
|
+
]);
|
|
250
|
+
// 2. Build options for pure evaluation
|
|
251
|
+
const options = { at, batchSeries };
|
|
252
|
+
const evaluationDate = (0, evaluate_1.getEvaluationDate)(strategy.trading, options);
|
|
253
|
+
// 3. No DB strategy → pure eval
|
|
254
|
+
if (!stratRow)
|
|
255
|
+
return (0, evaluate_1.evaluate)(strategy, options);
|
|
256
|
+
// 4. Resolve trading_day_id
|
|
257
|
+
const { data: tdRow } = await db
|
|
258
|
+
.from('trading_days')
|
|
259
|
+
.select('id')
|
|
260
|
+
.lte('post', evaluationDate.toISOString())
|
|
261
|
+
.order('post', { ascending: false })
|
|
262
|
+
.limit(1)
|
|
263
|
+
.maybeSingle();
|
|
264
|
+
if (!tdRow)
|
|
265
|
+
return (0, evaluate_1.evaluate)(strategy, options);
|
|
266
|
+
// 5. Check cache
|
|
267
|
+
const { data: cacheRow } = await db
|
|
268
|
+
.from('strategy_evaluations')
|
|
269
|
+
.select('allocation_id')
|
|
270
|
+
.eq('strategy_id', stratRow.id)
|
|
271
|
+
.eq('trading_day_id', tdRow.id)
|
|
272
|
+
.limit(1)
|
|
273
|
+
.maybeSingle();
|
|
274
|
+
if (cacheRow) {
|
|
275
|
+
// CACHE HIT — reconstruct result
|
|
276
|
+
const { data: allocRow } = await db
|
|
277
|
+
.from('allocations')
|
|
278
|
+
.select('name')
|
|
279
|
+
.eq('id', cacheRow.allocation_id)
|
|
280
|
+
.limit(1)
|
|
281
|
+
.maybeSingle();
|
|
282
|
+
const namedAlloc = strategy.allocations.find(na => na.name === allocRow?.name)
|
|
283
|
+
?? strategy.allocations[strategy.allocations.length - 1];
|
|
284
|
+
const [signals, indicators] = await Promise.all([
|
|
285
|
+
fetchSignalStatesForDay(client, stratRow.id, tdRow.id),
|
|
286
|
+
fetchIndicatorEvaluationsForDay(client, stratRow.id, tdRow.id),
|
|
287
|
+
]);
|
|
288
|
+
return {
|
|
289
|
+
allocation: {
|
|
290
|
+
name: namedAlloc.name,
|
|
291
|
+
holdings: namedAlloc.allocation.holdings,
|
|
292
|
+
},
|
|
293
|
+
asOf: evaluationDate,
|
|
294
|
+
signals,
|
|
295
|
+
indicators,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
// 6. CACHE MISS — fetch prior state, evaluate, store
|
|
299
|
+
const [prevSignals, prevMeta] = await Promise.all([
|
|
300
|
+
fetchSignalStates(client, stratRow.id),
|
|
301
|
+
fetchIndicatorMetadata(client, stratRow.id),
|
|
302
|
+
]);
|
|
303
|
+
const result = (0, evaluate_1.evaluate)(strategy, {
|
|
304
|
+
...options,
|
|
305
|
+
previousSignalStates: prevSignals,
|
|
306
|
+
previousIndicatorMetadata: prevMeta,
|
|
307
|
+
});
|
|
308
|
+
// Store (non-blocking)
|
|
309
|
+
storeResult(client, strategy, result, tdRow.id).catch(err => console.error('Failed to store evaluation:', err));
|
|
310
|
+
return result;
|
|
311
|
+
}
|
|
312
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/strategy/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/strategy/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/strategy/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAc9C,wBAAgB,cAAc,CAAC,MAAM,EAAE,mBAAmB,GAAG,cAAc,CAc1E"}
|
package/dist/strategy/client.js
CHANGED
|
@@ -4,347 +4,23 @@ exports.createStrategy = createStrategy;
|
|
|
4
4
|
const evaluate_1 = require("./evaluate");
|
|
5
5
|
const symbols_1 = require("./symbols");
|
|
6
6
|
const client_1 = require("../market/client");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return { symbol: row.symbol, leverage: row.leverage };
|
|
12
|
-
}
|
|
13
|
-
function mapIndicator(row) {
|
|
14
|
-
return {
|
|
15
|
-
type: row.type,
|
|
16
|
-
ticker: row.tickers ? mapTicker(row.tickers) : { symbol: '', leverage: 1 },
|
|
17
|
-
lookback: row.lookback,
|
|
18
|
-
delay: row.delay,
|
|
19
|
-
unit: row.unit ?? null,
|
|
20
|
-
threshold: row.threshold,
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
function mapSignal(row) {
|
|
24
|
-
return {
|
|
25
|
-
left: mapIndicator(row.indicator_1),
|
|
26
|
-
comparison: row.comparison,
|
|
27
|
-
right: mapIndicator(row.indicator_2),
|
|
28
|
-
tolerance: row.tolerance,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
// ---------------------------------------------------------------------------
|
|
32
|
-
// Factory
|
|
33
|
-
// ---------------------------------------------------------------------------
|
|
7
|
+
const get_1 = require("./get");
|
|
8
|
+
const cache_1 = require("./cache");
|
|
9
|
+
const stream_1 = require("./stream");
|
|
10
|
+
const backtest_1 = require("./backtest");
|
|
34
11
|
function createStrategy(client) {
|
|
35
|
-
// Cast to any for new tables not yet in generated types.
|
|
36
|
-
// Will be removed after regenerating database.types.ts.
|
|
37
|
-
const db = client;
|
|
38
12
|
const market = (0, client_1.createMarket)(client);
|
|
39
|
-
// -----------------------------------------------------------------------
|
|
40
|
-
// Private helpers (moved from public storage methods)
|
|
41
|
-
// -----------------------------------------------------------------------
|
|
42
|
-
async function fetchSignalStates(strategyId) {
|
|
43
|
-
const { data: nsRows, error: nsErr } = await db
|
|
44
|
-
.from('named_signals')
|
|
45
|
-
.select(`
|
|
46
|
-
signal_id,
|
|
47
|
-
signals:signal_id (
|
|
48
|
-
id,
|
|
49
|
-
indicator_1:indicator_id_1 ( type, tickers:ticker_id ( symbol, leverage ), lookback, delay, unit, threshold ),
|
|
50
|
-
indicator_2:indicator_id_2 ( type, tickers:ticker_id ( symbol, leverage ), lookback, delay, unit, threshold ),
|
|
51
|
-
comparison,
|
|
52
|
-
tolerance
|
|
53
|
-
)
|
|
54
|
-
`)
|
|
55
|
-
.eq('strategy_id', strategyId);
|
|
56
|
-
if (nsErr || !nsRows || nsRows.length === 0)
|
|
57
|
-
return {};
|
|
58
|
-
const signalIds = nsRows.map((r) => r.signal_id);
|
|
59
|
-
const { data: evalRows, error: evalErr } = await client
|
|
60
|
-
.from('signal_evaluations')
|
|
61
|
-
.select('signal_id, result, trading_day_id')
|
|
62
|
-
.in('signal_id', signalIds)
|
|
63
|
-
.order('trading_day_id', { ascending: false });
|
|
64
|
-
if (evalErr || !evalRows)
|
|
65
|
-
return {};
|
|
66
|
-
const latestBySignalId = new Map();
|
|
67
|
-
for (const row of evalRows) {
|
|
68
|
-
if (!latestBySignalId.has(row.signal_id)) {
|
|
69
|
-
latestBySignalId.set(row.signal_id, row.result);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
const result = {};
|
|
73
|
-
for (const nsRow of nsRows) {
|
|
74
|
-
const signal = mapSignal(nsRow.signals);
|
|
75
|
-
const key = (0, evaluate_1.signalKey)(signal);
|
|
76
|
-
const val = latestBySignalId.get(nsRow.signal_id);
|
|
77
|
-
if (val !== undefined) {
|
|
78
|
-
result[key] = val;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return result;
|
|
82
|
-
}
|
|
83
|
-
async function fetchSignalStatesForDay(strategyId, tradingDayId) {
|
|
84
|
-
const { data: nsRows, error: nsErr } = await db
|
|
85
|
-
.from('named_signals')
|
|
86
|
-
.select(`
|
|
87
|
-
signal_id,
|
|
88
|
-
signals:signal_id (
|
|
89
|
-
id,
|
|
90
|
-
indicator_1:indicator_id_1 ( type, tickers:ticker_id ( symbol, leverage ), lookback, delay, unit, threshold ),
|
|
91
|
-
indicator_2:indicator_id_2 ( type, tickers:ticker_id ( symbol, leverage ), lookback, delay, unit, threshold ),
|
|
92
|
-
comparison,
|
|
93
|
-
tolerance
|
|
94
|
-
)
|
|
95
|
-
`)
|
|
96
|
-
.eq('strategy_id', strategyId);
|
|
97
|
-
if (nsErr || !nsRows || nsRows.length === 0)
|
|
98
|
-
return {};
|
|
99
|
-
const signalIds = nsRows.map((r) => r.signal_id);
|
|
100
|
-
const { data: evalRows, error: evalErr } = await client
|
|
101
|
-
.from('signal_evaluations')
|
|
102
|
-
.select('signal_id, result')
|
|
103
|
-
.in('signal_id', signalIds)
|
|
104
|
-
.eq('trading_day_id', tradingDayId);
|
|
105
|
-
if (evalErr || !evalRows)
|
|
106
|
-
return {};
|
|
107
|
-
const signalIdToResult = new Map();
|
|
108
|
-
for (const row of evalRows) {
|
|
109
|
-
signalIdToResult.set(row.signal_id, row.result);
|
|
110
|
-
}
|
|
111
|
-
const result = {};
|
|
112
|
-
for (const nsRow of nsRows) {
|
|
113
|
-
const signal = mapSignal(nsRow.signals);
|
|
114
|
-
const key = (0, evaluate_1.signalKey)(signal);
|
|
115
|
-
const val = signalIdToResult.get(nsRow.signal_id);
|
|
116
|
-
if (val !== undefined) {
|
|
117
|
-
result[key] = val;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return result;
|
|
121
|
-
}
|
|
122
|
-
async function fetchIndicatorKeyMap(strategyId) {
|
|
123
|
-
const { data: nsRows, error: nsErr } = await db
|
|
124
|
-
.from('named_signals')
|
|
125
|
-
.select(`
|
|
126
|
-
signals:signal_id (
|
|
127
|
-
indicator_1:indicator_id_1 ( id, type, tickers:ticker_id ( symbol, leverage ), lookback, delay, unit, threshold ),
|
|
128
|
-
indicator_2:indicator_id_2 ( id, type, tickers:ticker_id ( symbol, leverage ), lookback, delay, unit, threshold )
|
|
129
|
-
)
|
|
130
|
-
`)
|
|
131
|
-
.eq('strategy_id', strategyId);
|
|
132
|
-
if (nsErr || !nsRows || nsRows.length === 0)
|
|
133
|
-
return new Map();
|
|
134
|
-
const keyToId = new Map();
|
|
135
|
-
for (const nsRow of nsRows) {
|
|
136
|
-
for (const ind of [nsRow.signals.indicator_1, nsRow.signals.indicator_2]) {
|
|
137
|
-
const key = (0, evaluate_1.indicatorKey)(mapIndicator(ind));
|
|
138
|
-
if (!keyToId.has(key)) {
|
|
139
|
-
keyToId.set(key, ind.id);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return keyToId;
|
|
144
|
-
}
|
|
145
|
-
async function fetchIndicatorEvaluationsForDay(strategyId, tradingDayId) {
|
|
146
|
-
const keyToId = await fetchIndicatorKeyMap(strategyId);
|
|
147
|
-
if (keyToId.size === 0)
|
|
148
|
-
return {};
|
|
149
|
-
const indicatorIds = [...keyToId.values()];
|
|
150
|
-
const { data: evalRows, error: evalErr } = await db
|
|
151
|
-
.from('indicator_evaluations')
|
|
152
|
-
.select('indicator_id, value, metadata, trading_days!inner(post)')
|
|
153
|
-
.in('indicator_id', indicatorIds)
|
|
154
|
-
.eq('trading_day_id', tradingDayId);
|
|
155
|
-
if (evalErr || !evalRows)
|
|
156
|
-
return {};
|
|
157
|
-
const byIndicatorId = new Map();
|
|
158
|
-
for (const row of evalRows) {
|
|
159
|
-
byIndicatorId.set(row.indicator_id, {
|
|
160
|
-
value: Number(row.value),
|
|
161
|
-
metadata: row.metadata,
|
|
162
|
-
post: row.trading_days.post,
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
const result = {};
|
|
166
|
-
for (const [key, id] of keyToId) {
|
|
167
|
-
const entry = byIndicatorId.get(id);
|
|
168
|
-
if (entry) {
|
|
169
|
-
result[key] = {
|
|
170
|
-
timestamp: entry.post,
|
|
171
|
-
value: entry.value,
|
|
172
|
-
...(entry.metadata != null ? { metadata: entry.metadata } : {}),
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
return result;
|
|
177
|
-
}
|
|
178
|
-
async function fetchIndicatorMetadata(strategyId) {
|
|
179
|
-
const keyToId = await fetchIndicatorKeyMap(strategyId);
|
|
180
|
-
if (keyToId.size === 0)
|
|
181
|
-
return {};
|
|
182
|
-
const indicatorIds = [...keyToId.values()];
|
|
183
|
-
const { data: evalRows, error: evalErr } = await db
|
|
184
|
-
.from('indicator_evaluations')
|
|
185
|
-
.select('indicator_id, metadata, trading_day_id')
|
|
186
|
-
.in('indicator_id', indicatorIds)
|
|
187
|
-
.order('trading_day_id', { ascending: false });
|
|
188
|
-
if (evalErr || !evalRows)
|
|
189
|
-
return {};
|
|
190
|
-
const latestByIndicatorId = new Map();
|
|
191
|
-
for (const row of evalRows) {
|
|
192
|
-
if (!latestByIndicatorId.has(row.indicator_id) && row.metadata != null) {
|
|
193
|
-
latestByIndicatorId.set(row.indicator_id, row.metadata);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
const result = {};
|
|
197
|
-
for (const [key, id] of keyToId) {
|
|
198
|
-
const meta = latestByIndicatorId.get(id);
|
|
199
|
-
if (meta !== undefined) {
|
|
200
|
-
result[key] = meta;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
return result;
|
|
204
|
-
}
|
|
205
|
-
async function storeResult(strategy, result, tradingDayId) {
|
|
206
|
-
// Resolve strategy_id for indicator key → DB ID mapping
|
|
207
|
-
const { data: stratRow } = await client
|
|
208
|
-
.from('strategies')
|
|
209
|
-
.select('id')
|
|
210
|
-
.eq('link_id', strategy.linkId)
|
|
211
|
-
.limit(1)
|
|
212
|
-
.maybeSingle();
|
|
213
|
-
const signalResults = Object.entries(result.signals).map(([_key, sigResult]) => {
|
|
214
|
-
const ns = strategy.signals.find((ns) => (0, evaluate_1.signalKey)(ns.signal) === _key);
|
|
215
|
-
return { name: ns?.name ?? _key, result: sigResult };
|
|
216
|
-
});
|
|
217
|
-
// Map indicator keys to database IDs
|
|
218
|
-
const keyToId = stratRow ? await fetchIndicatorKeyMap(stratRow.id) : new Map();
|
|
219
|
-
const indicatorResults = Object.entries(result.indicators)
|
|
220
|
-
.filter(([key]) => keyToId.has(key))
|
|
221
|
-
.map(([key, indResult]) => ({
|
|
222
|
-
indicatorId: keyToId.get(key),
|
|
223
|
-
value: indResult.value,
|
|
224
|
-
metadata: indResult.metadata ?? null,
|
|
225
|
-
}));
|
|
226
|
-
const { error } = await db.rpc('upsert_evaluation', {
|
|
227
|
-
p_link_id: strategy.linkId,
|
|
228
|
-
p_allocation_name: result.allocation.name,
|
|
229
|
-
p_signal_results: signalResults,
|
|
230
|
-
p_indicator_results: indicatorResults,
|
|
231
|
-
p_trading_day_id: tradingDayId,
|
|
232
|
-
});
|
|
233
|
-
if (error)
|
|
234
|
-
throw new Error(`Failed to store evaluation: ${error.message}`);
|
|
235
|
-
}
|
|
236
|
-
// -----------------------------------------------------------------------
|
|
237
|
-
// Module
|
|
238
|
-
// -----------------------------------------------------------------------
|
|
239
13
|
return {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
body: { linkId },
|
|
244
|
-
});
|
|
245
|
-
if (error || !data)
|
|
246
|
-
return null;
|
|
247
|
-
return data;
|
|
248
|
-
},
|
|
249
|
-
async getMany(linkIds) {
|
|
250
|
-
if (linkIds.length === 0)
|
|
251
|
-
return {};
|
|
252
|
-
const result = {};
|
|
253
|
-
// Use parallel fetches
|
|
254
|
-
const promises = linkIds.map(async (id) => {
|
|
255
|
-
const strategy = await this.get(id);
|
|
256
|
-
if (strategy)
|
|
257
|
-
result[id] = strategy;
|
|
258
|
-
});
|
|
259
|
-
await Promise.all(promises);
|
|
260
|
-
return result;
|
|
261
|
-
},
|
|
262
|
-
// ----- Cache-through evaluation -----
|
|
263
|
-
async evaluate(strategy, at) {
|
|
264
|
-
// 1. Fetch series + resolve strategy_id in parallel
|
|
265
|
-
const symbols = (0, symbols_1.extractSymbols)(strategy);
|
|
266
|
-
const [batchSeries, stratRow] = await Promise.all([
|
|
267
|
-
market.getBatchSeries(symbols),
|
|
268
|
-
client
|
|
269
|
-
.from('strategies')
|
|
270
|
-
.select('id')
|
|
271
|
-
.eq('link_id', strategy.linkId)
|
|
272
|
-
.limit(1)
|
|
273
|
-
.maybeSingle()
|
|
274
|
-
.then(({ data }) => data),
|
|
275
|
-
]);
|
|
276
|
-
// 2. Build options for pure evaluation
|
|
277
|
-
const options = { at, batchSeries };
|
|
278
|
-
const evaluationDate = (0, evaluate_1.getEvaluationDate)(strategy.trading, options);
|
|
279
|
-
// 4. No DB strategy → pure eval
|
|
280
|
-
if (!stratRow)
|
|
281
|
-
return (0, evaluate_1.evaluate)(strategy, options);
|
|
282
|
-
// 5. Resolve trading_day_id
|
|
283
|
-
const { data: tdRow } = await db
|
|
284
|
-
.from('trading_days')
|
|
285
|
-
.select('id')
|
|
286
|
-
.lte('post', evaluationDate.toISOString())
|
|
287
|
-
.order('post', { ascending: false })
|
|
288
|
-
.limit(1)
|
|
289
|
-
.maybeSingle();
|
|
290
|
-
if (!tdRow)
|
|
291
|
-
return (0, evaluate_1.evaluate)(strategy, options);
|
|
292
|
-
// 6. Check cache
|
|
293
|
-
const { data: cacheRow } = await db
|
|
294
|
-
.from('strategy_evaluations')
|
|
295
|
-
.select('allocation_id')
|
|
296
|
-
.eq('strategy_id', stratRow.id)
|
|
297
|
-
.eq('trading_day_id', tdRow.id)
|
|
298
|
-
.limit(1)
|
|
299
|
-
.maybeSingle();
|
|
300
|
-
if (cacheRow) {
|
|
301
|
-
// CACHE HIT — reconstruct result
|
|
302
|
-
const { data: allocRow } = await db
|
|
303
|
-
.from('allocations')
|
|
304
|
-
.select('name')
|
|
305
|
-
.eq('id', cacheRow.allocation_id)
|
|
306
|
-
.limit(1)
|
|
307
|
-
.maybeSingle();
|
|
308
|
-
const namedAlloc = strategy.allocations.find(na => na.name === allocRow?.name)
|
|
309
|
-
?? strategy.allocations[strategy.allocations.length - 1];
|
|
310
|
-
const [signals, indicators] = await Promise.all([
|
|
311
|
-
fetchSignalStatesForDay(stratRow.id, tdRow.id),
|
|
312
|
-
fetchIndicatorEvaluationsForDay(stratRow.id, tdRow.id),
|
|
313
|
-
]);
|
|
314
|
-
return {
|
|
315
|
-
allocation: {
|
|
316
|
-
name: namedAlloc.name,
|
|
317
|
-
holdings: namedAlloc.allocation.holdings,
|
|
318
|
-
},
|
|
319
|
-
asOf: evaluationDate,
|
|
320
|
-
signals,
|
|
321
|
-
indicators,
|
|
322
|
-
};
|
|
323
|
-
}
|
|
324
|
-
// 7. CACHE MISS — fetch prior state, evaluate, store
|
|
325
|
-
const [prevSignals, prevMeta] = await Promise.all([
|
|
326
|
-
fetchSignalStates(stratRow.id),
|
|
327
|
-
fetchIndicatorMetadata(stratRow.id),
|
|
328
|
-
]);
|
|
329
|
-
const result = (0, evaluate_1.evaluate)(strategy, {
|
|
330
|
-
...options,
|
|
331
|
-
previousSignalStates: prevSignals,
|
|
332
|
-
previousIndicatorMetadata: prevMeta,
|
|
333
|
-
});
|
|
334
|
-
// Store (non-blocking)
|
|
335
|
-
storeResult(strategy, result, tdRow.id).catch(err => console.error('Failed to store evaluation:', err));
|
|
336
|
-
return result;
|
|
337
|
-
},
|
|
338
|
-
// ----- Pure evaluation (delegate to evaluate.ts) -----
|
|
14
|
+
get: (linkId) => (0, get_1.get)(client, linkId),
|
|
15
|
+
getMany: (linkIds) => (0, get_1.getMany)(client, linkIds),
|
|
16
|
+
evaluate: (strategy, at) => (0, cache_1.evaluateCached)(client, market, strategy, at),
|
|
339
17
|
evaluateIndicator: evaluate_1.evaluateIndicator,
|
|
340
18
|
evaluateSignal: evaluate_1.evaluateSignal,
|
|
341
19
|
evaluateAllocation: evaluate_1.evaluateAllocation,
|
|
342
20
|
getEvaluationDate: evaluate_1.getEvaluationDate,
|
|
343
|
-
// ----- Utilities -----
|
|
344
21
|
extractSymbols: symbols_1.extractSymbols,
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
},
|
|
22
|
+
stream: (strategy, observation) => (0, stream_1.stream)(client, market, strategy, observation),
|
|
23
|
+
backtest: backtest_1.backtest,
|
|
348
24
|
};
|
|
349
25
|
}
|
|
350
26
|
//# sourceMappingURL=client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/strategy/client.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/strategy/client.ts"],"names":[],"mappings":";;AAeA,wCAcC;AA3BD,yCAKoB;AACpB,uCAAiE;AACjE,6CAAgD;AAChD,+BAAqC;AACrC,mCAAyC;AACzC,qCAAkC;AAClC,yCAAsC;AAEtC,SAAgB,cAAc,CAAC,MAA2B;IACxD,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,MAAM,CAAC,CAAC;IACpC,OAAO;QACL,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAA,SAAG,EAAC,MAAM,EAAE,MAAM,CAAC;QACpC,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAA,aAAO,EAAC,MAAM,EAAE,OAAO,CAAC;QAC9C,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,IAAA,sBAAc,EAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;QACxE,iBAAiB,EAAE,4BAAqB;QACxC,cAAc,EAAE,yBAAkB;QAClC,kBAAkB,EAAE,6BAAsB;QAC1C,iBAAiB,EAAE,4BAAqB;QACxC,cAAc,EAAE,wBAAkB;QAClC,MAAM,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,CAAC,IAAA,eAAM,EAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC;QAChF,QAAQ,EAAR,mBAAQ;KACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { TypedSupabaseClient } from '../types';
|
|
2
|
+
import type { Strategy } from './types';
|
|
3
|
+
export declare function get(client: TypedSupabaseClient, linkId: string): Promise<Strategy | null>;
|
|
4
|
+
export declare function getMany(client: TypedSupabaseClient, linkIds: string[]): Promise<Record<string, Strategy>>;
|
|
5
|
+
//# sourceMappingURL=get.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../src/strategy/get.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,wBAAsB,GAAG,CAAC,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAM/F;AAED,wBAAsB,OAAO,CAAC,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAU/G"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.get = get;
|
|
4
|
+
exports.getMany = getMany;
|
|
5
|
+
async function get(client, linkId) {
|
|
6
|
+
const { data, error } = await client.functions.invoke('strategy', {
|
|
7
|
+
body: { linkId },
|
|
8
|
+
});
|
|
9
|
+
if (error || !data)
|
|
10
|
+
return null;
|
|
11
|
+
return data;
|
|
12
|
+
}
|
|
13
|
+
async function getMany(client, linkIds) {
|
|
14
|
+
if (linkIds.length === 0)
|
|
15
|
+
return {};
|
|
16
|
+
const result = {};
|
|
17
|
+
const promises = linkIds.map(async (id) => {
|
|
18
|
+
const strategy = await get(client, id);
|
|
19
|
+
if (strategy)
|
|
20
|
+
result[id] = strategy;
|
|
21
|
+
});
|
|
22
|
+
await Promise.all(promises);
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../src/strategy/get.ts"],"names":[],"mappings":";;AAGA,kBAMC;AAED,0BAUC;AAlBM,KAAK,UAAU,GAAG,CAAC,MAA2B,EAAE,MAAc;IACnE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE;QAChE,IAAI,EAAE,EAAE,MAAM,EAAE;KACjB,CAAC,CAAC;IACH,IAAI,KAAK,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,IAAgB,CAAC;AAC1B,CAAC;AAEM,KAAK,UAAU,OAAO,CAAC,MAA2B,EAAE,OAAiB;IAC1E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEpC,MAAM,MAAM,GAA6B,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QACxC,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACvC,IAAI,QAAQ;YAAE,MAAM,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC5B,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/strategy/index.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
export type { StrategyModule, Strategy, NamedSignal, AllocationEvaluation, Signal, Allocation, Indicator, Ticker, Holding, Trading, Condition, SignalExpr, NotExpr, UnaryExpr, AndExpr, OrExpr, Comparison, IndicatorType, Frequency, Unit, EvaluationOptions, IndicatorEvaluation, StrategyEvaluation, BacktestOptions, BacktestResult, } from './types';
|
|
1
|
+
export type { StrategyModule, Strategy, NamedSignal, AllocationEvaluation, Signal, Allocation, Indicator, Ticker, Holding, Trading, Condition, SignalExpr, NotExpr, UnaryExpr, AndExpr, OrExpr, Comparison, IndicatorType, Frequency, Unit, EvaluationOptions, IndicatorEvaluation, StrategyEvaluation, StreamObservation, BacktestOptions, BacktestResult, } from './types';
|
|
2
2
|
export { createStrategy } from './client';
|
|
3
|
+
export { get, getMany } from './get';
|
|
4
|
+
export { evaluateCached } from './cache';
|
|
5
|
+
export { stream } from './stream';
|
|
6
|
+
export { backtest } from './backtest';
|
|
3
7
|
export { evaluateIndicator, evaluateSignal, evaluateAllocation, evaluate, getEvaluationDate, indicatorKey, signalKey } from './evaluate';
|
|
4
8
|
export { extractSymbols, INDICATOR_SYMBOL_MAP } from './symbols';
|
|
5
9
|
export { utcToET, isAtMarketClose } from './time';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/strategy/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,QAAQ,EACR,WAAW,EACX,oBAAoB,EACpB,MAAM,EACN,UAAU,EACV,SAAS,EACT,MAAM,EACN,OAAO,EACP,OAAO,EACP,SAAS,EACT,UAAU,EACV,OAAO,EACP,SAAS,EACT,OAAO,EACP,MAAM,EACN,UAAU,EACV,aAAa,EACb,SAAS,EACT,IAAI,EACJ,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,cAAc,GACf,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,kBAAkB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACzI,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/strategy/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,QAAQ,EACR,WAAW,EACX,oBAAoB,EACpB,MAAM,EACN,UAAU,EACV,SAAS,EACT,MAAM,EACN,OAAO,EACP,OAAO,EACP,SAAS,EACT,UAAU,EACV,OAAO,EACP,SAAS,EACT,OAAO,EACP,MAAM,EACN,UAAU,EACV,aAAa,EACb,SAAS,EACT,IAAI,EACJ,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,cAAc,GACf,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,kBAAkB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACzI,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC"}
|
package/dist/strategy/index.js
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isAtMarketClose = exports.utcToET = exports.INDICATOR_SYMBOL_MAP = exports.extractSymbols = exports.signalKey = exports.indicatorKey = exports.getEvaluationDate = exports.evaluate = exports.evaluateAllocation = exports.evaluateSignal = exports.evaluateIndicator = exports.createStrategy = void 0;
|
|
3
|
+
exports.isAtMarketClose = exports.utcToET = exports.INDICATOR_SYMBOL_MAP = exports.extractSymbols = exports.signalKey = exports.indicatorKey = exports.getEvaluationDate = exports.evaluate = exports.evaluateAllocation = exports.evaluateSignal = exports.evaluateIndicator = exports.backtest = exports.stream = exports.evaluateCached = exports.getMany = exports.get = exports.createStrategy = void 0;
|
|
4
4
|
var client_1 = require("./client");
|
|
5
5
|
Object.defineProperty(exports, "createStrategy", { enumerable: true, get: function () { return client_1.createStrategy; } });
|
|
6
|
+
var get_1 = require("./get");
|
|
7
|
+
Object.defineProperty(exports, "get", { enumerable: true, get: function () { return get_1.get; } });
|
|
8
|
+
Object.defineProperty(exports, "getMany", { enumerable: true, get: function () { return get_1.getMany; } });
|
|
9
|
+
var cache_1 = require("./cache");
|
|
10
|
+
Object.defineProperty(exports, "evaluateCached", { enumerable: true, get: function () { return cache_1.evaluateCached; } });
|
|
11
|
+
var stream_1 = require("./stream");
|
|
12
|
+
Object.defineProperty(exports, "stream", { enumerable: true, get: function () { return stream_1.stream; } });
|
|
13
|
+
var backtest_1 = require("./backtest");
|
|
14
|
+
Object.defineProperty(exports, "backtest", { enumerable: true, get: function () { return backtest_1.backtest; } });
|
|
6
15
|
var evaluate_1 = require("./evaluate");
|
|
7
16
|
Object.defineProperty(exports, "evaluateIndicator", { enumerable: true, get: function () { return evaluate_1.evaluateIndicator; } });
|
|
8
17
|
Object.defineProperty(exports, "evaluateSignal", { enumerable: true, get: function () { return evaluate_1.evaluateSignal; } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/strategy/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/strategy/index.ts"],"names":[],"mappings":";;;AA6BA,mCAA0C;AAAjC,wGAAA,cAAc,OAAA;AACvB,6BAAqC;AAA5B,0FAAA,GAAG,OAAA;AAAE,8FAAA,OAAO,OAAA;AACrB,iCAAyC;AAAhC,uGAAA,cAAc,OAAA;AACvB,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AACjB,uCAAyI;AAAhI,6GAAA,iBAAiB,OAAA;AAAE,0GAAA,cAAc,OAAA;AAAE,8GAAA,kBAAkB,OAAA;AAAE,oGAAA,QAAQ,OAAA;AAAE,6GAAA,iBAAiB,OAAA;AAAE,wGAAA,YAAY,OAAA;AAAE,qGAAA,SAAS,OAAA;AACpH,qCAAiE;AAAxD,yGAAA,cAAc,OAAA;AAAE,+GAAA,oBAAoB,OAAA;AAC7C,+BAAkD;AAAzC,+FAAA,OAAO,OAAA;AAAE,uGAAA,eAAe,OAAA"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { TypedSupabaseClient } from '../types';
|
|
2
|
+
import type { MarketModule } from '../market/types';
|
|
3
|
+
import type { Strategy, StrategyEvaluation, StreamObservation } from './types';
|
|
4
|
+
export declare function stream(client: TypedSupabaseClient, market: MarketModule, strategy: Strategy, observation: StreamObservation | StreamObservation[]): Promise<StrategyEvaluation>;
|
|
5
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/strategy/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,iBAAiB,CAAC;AACjE,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAsB/E,wBAAsB,MAAM,CAC1B,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,iBAAiB,GAAG,iBAAiB,EAAE,GACnD,OAAO,CAAC,kBAAkB,CAAC,CAyC7B"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.stream = stream;
|
|
4
|
+
const evaluate_1 = require("./evaluate");
|
|
5
|
+
const symbols_1 = require("./symbols");
|
|
6
|
+
const cache_1 = require("./cache");
|
|
7
|
+
function mergeObservations(batchSeries, observations) {
|
|
8
|
+
let merged = { ...batchSeries };
|
|
9
|
+
for (const obs of observations) {
|
|
10
|
+
const series = [...(merged[obs.symbol] ?? [])];
|
|
11
|
+
const obsDate = obs.timestamp.slice(0, 10); // YYYY-MM-DD
|
|
12
|
+
const idx = series.findIndex(o => o.timestamp.slice(0, 10) === obsDate);
|
|
13
|
+
const entry = { timestamp: obs.timestamp, value: obs.value };
|
|
14
|
+
if (idx >= 0)
|
|
15
|
+
series[idx] = entry; // replace incomplete bar
|
|
16
|
+
else
|
|
17
|
+
series.push(entry); // append new day
|
|
18
|
+
merged = { ...merged, [obs.symbol]: series };
|
|
19
|
+
}
|
|
20
|
+
return merged;
|
|
21
|
+
}
|
|
22
|
+
async function stream(client, market, strategy, observation) {
|
|
23
|
+
const observations = Array.isArray(observation) ? observation : [observation];
|
|
24
|
+
if (observations.length === 0) {
|
|
25
|
+
throw new Error('stream() requires at least one observation');
|
|
26
|
+
}
|
|
27
|
+
// 1. Fetch historical series for all symbols
|
|
28
|
+
const symbols = (0, symbols_1.extractSymbols)(strategy);
|
|
29
|
+
const batchSeries = await market.getBatchSeries(symbols);
|
|
30
|
+
// 2. Merge the incoming observations into the series (replace same-date or append)
|
|
31
|
+
const mergedSeries = mergeObservations(batchSeries, observations);
|
|
32
|
+
// 3. Build evaluation options with latest observation timestamp
|
|
33
|
+
const at = new Date(observations[observations.length - 1].timestamp);
|
|
34
|
+
const options = { at, batchSeries: mergedSeries };
|
|
35
|
+
// 4. Fetch prior signal states for hysteresis (read-only, no cache write)
|
|
36
|
+
const stratRow = await client
|
|
37
|
+
.from('strategies')
|
|
38
|
+
.select('id')
|
|
39
|
+
.eq('link_id', strategy.linkId)
|
|
40
|
+
.limit(1)
|
|
41
|
+
.maybeSingle()
|
|
42
|
+
.then(({ data }) => data);
|
|
43
|
+
let prevSignals = {};
|
|
44
|
+
let prevMeta = {};
|
|
45
|
+
if (stratRow) {
|
|
46
|
+
[prevSignals, prevMeta] = await Promise.all([
|
|
47
|
+
(0, cache_1.fetchSignalStates)(client, stratRow.id),
|
|
48
|
+
(0, cache_1.fetchIndicatorMetadata)(client, stratRow.id),
|
|
49
|
+
]);
|
|
50
|
+
}
|
|
51
|
+
// 5. Evaluate (skip cache check and result storage — interim data)
|
|
52
|
+
return (0, evaluate_1.evaluate)(strategy, {
|
|
53
|
+
...options,
|
|
54
|
+
previousSignalStates: prevSignals,
|
|
55
|
+
previousIndicatorMetadata: prevMeta,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/strategy/stream.ts"],"names":[],"mappings":"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"}
|
package/dist/strategy/types.d.ts
CHANGED
|
@@ -87,6 +87,11 @@ export interface StrategyEvaluation {
|
|
|
87
87
|
signals: Record<string, boolean>;
|
|
88
88
|
indicators: Record<string, IndicatorEvaluation>;
|
|
89
89
|
}
|
|
90
|
+
export interface StreamObservation {
|
|
91
|
+
symbol: string;
|
|
92
|
+
timestamp: string;
|
|
93
|
+
value: number;
|
|
94
|
+
}
|
|
90
95
|
export interface BacktestOptions {
|
|
91
96
|
startDate: string;
|
|
92
97
|
endDate: string;
|
|
@@ -102,6 +107,7 @@ export interface StrategyModule {
|
|
|
102
107
|
evaluateAllocation(allocation: Allocation, options: EvaluationOptions): boolean;
|
|
103
108
|
getEvaluationDate(trading: Trading, options: EvaluationOptions): Date;
|
|
104
109
|
extractSymbols(strategy: Strategy): string[];
|
|
110
|
+
stream(strategy: Strategy, observation: StreamObservation | StreamObservation[]): Promise<StrategyEvaluation>;
|
|
105
111
|
backtest(strategy: Strategy, options: BacktestOptions): Promise<BacktestResult>;
|
|
106
112
|
}
|
|
107
113
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/strategy/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAMnD,MAAM,MAAM,UAAU,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEzC,MAAM,MAAM,aAAa,GACrB,KAAK,GACL,KAAK,GACL,OAAO,GACP,QAAQ,GACR,YAAY,GACZ,UAAU,GACV,KAAK,GACL,KAAK,GACL,OAAO,GACP,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,MAAM,GACN,MAAM,GACN,MAAM,GACN,OAAO,GACP,aAAa,GACb,cAAc,GACd,aAAa,GACb,WAAW,CAAC;AAEhB,MAAM,MAAM,SAAS,GACjB,OAAO,GACP,QAAQ,GACR,SAAS,GACT,YAAY,GACZ,WAAW,GACX,gBAAgB,GAChB,cAAc,GACd,QAAQ,CAAC;AAEb,MAAM,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC;AAMpC,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,SAAS,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAMD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,KAAK,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAE7C,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,SAAS,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,OAAO,EAAE,CAAC;CACjB;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAMrD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,UAAU,CAAC;CACxB;AAMD,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAMD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,IAAI,CAAC;IACT,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IAC3C,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/C,yBAAyB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,IAAI,CAAC;IACX,UAAU,EAAE,oBAAoB,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CACjD;AAMD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;CAAG;AAMlC,MAAM,WAAW,cAAc;IAE7B,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC9C,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAG9D,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAGpE,iBAAiB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,iBAAiB,GAAG,mBAAmB,CAAC;IACzF,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC;IACpE,kBAAkB,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC;IAGhF,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAGtE,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,EAAE,CAAC;IAG7C,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACjF"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/strategy/types.ts"],"names":[],"mappings":"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"}
|