@livefolio/sdk 0.2.0
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 +191 -0
- package/dist/auth/client.d.ts +4 -0
- package/dist/auth/client.d.ts.map +1 -0
- package/dist/auth/client.js +37 -0
- package/dist/auth/client.js.map +1 -0
- package/dist/auth/index.d.ts +3 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +6 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/types.d.ts +9 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +3 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -0
- package/dist/market/client.d.ts +4 -0
- package/dist/market/client.d.ts.map +1 -0
- package/dist/market/client.js +65 -0
- package/dist/market/client.js.map +1 -0
- package/dist/market/index.d.ts +3 -0
- package/dist/market/index.d.ts.map +1 -0
- package/dist/market/index.js +6 -0
- package/dist/market/index.js.map +1 -0
- package/dist/market/types.d.ts +20 -0
- package/dist/market/types.d.ts.map +1 -0
- package/dist/market/types.js +3 -0
- package/dist/market/types.js.map +1 -0
- package/dist/portfolio/client.d.ts +4 -0
- package/dist/portfolio/client.d.ts.map +1 -0
- package/dist/portfolio/client.js +7 -0
- package/dist/portfolio/client.js.map +1 -0
- package/dist/portfolio/index.d.ts +3 -0
- package/dist/portfolio/index.d.ts.map +1 -0
- package/dist/portfolio/index.js +6 -0
- package/dist/portfolio/index.js.map +1 -0
- package/dist/portfolio/types.d.ts +3 -0
- package/dist/portfolio/types.d.ts.map +1 -0
- package/dist/portfolio/types.js +3 -0
- package/dist/portfolio/types.js.map +1 -0
- package/dist/strategy/client.d.ts +4 -0
- package/dist/strategy/client.d.ts.map +1 -0
- package/dist/strategy/client.js +350 -0
- package/dist/strategy/client.js.map +1 -0
- package/dist/strategy/evaluate.d.ts +10 -0
- package/dist/strategy/evaluate.d.ts.map +1 -0
- package/dist/strategy/evaluate.js +498 -0
- package/dist/strategy/evaluate.js.map +1 -0
- package/dist/strategy/index.d.ts +6 -0
- package/dist/strategy/index.d.ts.map +1 -0
- package/dist/strategy/index.js +20 -0
- package/dist/strategy/index.js.map +1 -0
- package/dist/strategy/symbols.d.ts +4 -0
- package/dist/strategy/symbols.d.ts.map +1 -0
- package/dist/strategy/symbols.js +41 -0
- package/dist/strategy/symbols.js.map +1 -0
- package/dist/strategy/time.d.ts +9 -0
- package/dist/strategy/time.d.ts.map +1 -0
- package/dist/strategy/time.js +28 -0
- package/dist/strategy/time.js.map +1 -0
- package/dist/strategy/types.d.ts +107 -0
- package/dist/strategy/types.d.ts.map +1 -0
- package/dist/strategy/types.js +3 -0
- package/dist/strategy/types.js.map +1 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# @livefolio/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for market data, strategy evaluation, and portfolio management.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @livefolio/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Getting Started
|
|
12
|
+
|
|
13
|
+
All modules are created from a single Supabase client:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { createLivefolioClient } from '@livefolio/sdk';
|
|
17
|
+
import { createClient } from '@supabase/supabase-js';
|
|
18
|
+
|
|
19
|
+
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
|
|
20
|
+
const livefolio = createLivefolioClient(supabase);
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Individual modules can also be imported directly:
|
|
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
|
|
72
|
+
|
|
73
|
+
Retrieve the latest real-time quote for one or more symbols.
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
const quote = await livefolio.market.getQuote('SPY');
|
|
77
|
+
// quote: Observation — { timestamp: '2025-03-02T21:00:00Z', value: 592.10 }
|
|
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
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
const strategy = await livefolio.strategy.get('abc-123');
|
|
128
|
+
if (strategy) {
|
|
129
|
+
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
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Utilities
|
|
139
|
+
|
|
140
|
+
| Method | Returns | Description |
|
|
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
|
|
146
|
+
|
|
147
|
+
For advanced use cases (testing, backtesting, custom pipelines), the pure evaluation functions operate synchronously without any DB interaction. They accept `EvaluationOptions` with `batchSeries` and optionally `previousSignalStates` and `previousIndicatorMetadata`.
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
import { evaluate, evaluateIndicator, evaluateSignal } from '@livefolio/sdk/strategy';
|
|
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);
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Portfolio
|
|
165
|
+
|
|
166
|
+
Brokerage account aggregation and trade order management. This module is planned but not yet implemented.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Development
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
npm install
|
|
174
|
+
npm run build # compile TypeScript → dist/
|
|
175
|
+
npm test # run tests
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## CI/CD
|
|
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
|
+
```
|
|
188
|
+
|
|
189
|
+
## License
|
|
190
|
+
|
|
191
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/auth/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,wBAAgB,UAAU,CAAC,MAAM,EAAE,mBAAmB,GAAG,UAAU,CA+BlE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAuth = createAuth;
|
|
4
|
+
function createAuth(client) {
|
|
5
|
+
return {
|
|
6
|
+
async getUser() {
|
|
7
|
+
const { data, error } = await client.auth.getUser();
|
|
8
|
+
if (error)
|
|
9
|
+
throw error;
|
|
10
|
+
return data.user;
|
|
11
|
+
},
|
|
12
|
+
async getSession() {
|
|
13
|
+
const { data, error } = await client.auth.getSession();
|
|
14
|
+
if (error)
|
|
15
|
+
throw error;
|
|
16
|
+
return data.session;
|
|
17
|
+
},
|
|
18
|
+
async requireUser() {
|
|
19
|
+
const { data, error } = await client.auth.getUser();
|
|
20
|
+
if (error)
|
|
21
|
+
throw error;
|
|
22
|
+
if (!data.user)
|
|
23
|
+
throw new Error('Not authenticated');
|
|
24
|
+
return data.user;
|
|
25
|
+
},
|
|
26
|
+
onAuthStateChange(callback) {
|
|
27
|
+
const { data } = client.auth.onAuthStateChange(callback);
|
|
28
|
+
return data.subscription;
|
|
29
|
+
},
|
|
30
|
+
async signOut() {
|
|
31
|
+
const { error } = await client.auth.signOut();
|
|
32
|
+
if (error)
|
|
33
|
+
throw error;
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/auth/client.ts"],"names":[],"mappings":";;AAGA,gCA+BC;AA/BD,SAAgB,UAAU,CAAC,MAA2B;IACpD,OAAO;QACL,KAAK,CAAC,OAAO;YACX,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACpD,IAAI,KAAK;gBAAE,MAAM,KAAK,CAAC;YACvB,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,CAAC;QAED,KAAK,CAAC,UAAU;YACd,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACvD,IAAI,KAAK;gBAAE,MAAM,KAAK,CAAC;YACvB,OAAO,IAAI,CAAC,OAAO,CAAC;QACtB,CAAC;QAED,KAAK,CAAC,WAAW;YACf,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACpD,IAAI,KAAK;gBAAE,MAAM,KAAK,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,CAAC;QAED,iBAAiB,CAAC,QAAQ;YACxB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YACzD,OAAO,IAAI,CAAC,YAAY,CAAC;QAC3B,CAAC;QAED,KAAK,CAAC,OAAO;YACX,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAC9C,IAAI,KAAK;gBAAE,MAAM,KAAK,CAAC;QACzB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAuth = void 0;
|
|
4
|
+
var client_1 = require("./client");
|
|
5
|
+
Object.defineProperty(exports, "createAuth", { enumerable: true, get: function () { return client_1.createAuth; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":";;;AACA,mCAAsC;AAA7B,oGAAA,UAAU,OAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { User, Session, AuthChangeEvent, Subscription } from '@supabase/supabase-js';
|
|
2
|
+
export interface AuthModule {
|
|
3
|
+
getUser(): Promise<User | null>;
|
|
4
|
+
getSession(): Promise<Session | null>;
|
|
5
|
+
requireUser(): Promise<User>;
|
|
6
|
+
onAuthStateChange(callback: (event: AuthChangeEvent, session: Session | null) => void): Subscription;
|
|
7
|
+
signOut(): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1F,MAAM,WAAW,UAAU;IACzB,OAAO,IAAI,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAChC,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACtC,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,iBAAiB,CACf,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,GAClE,YAAY,CAAC;IAChB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export * as auth from './auth';
|
|
2
|
+
export * as market from './market';
|
|
3
|
+
export * as strategy from './strategy';
|
|
4
|
+
export * as portfolio from './portfolio';
|
|
5
|
+
export type { TypedSupabaseClient } from './types';
|
|
6
|
+
export type { AuthModule } from './auth';
|
|
7
|
+
export type { MarketModule } from './market';
|
|
8
|
+
export type { StrategyModule } from './strategy';
|
|
9
|
+
export type { PortfolioModule } from './portfolio';
|
|
10
|
+
import type { TypedSupabaseClient } from './types';
|
|
11
|
+
import type { AuthModule } from './auth';
|
|
12
|
+
import type { MarketModule } from './market';
|
|
13
|
+
import type { StrategyModule } from './strategy';
|
|
14
|
+
import type { PortfolioModule } from './portfolio';
|
|
15
|
+
export interface LivefolioClient {
|
|
16
|
+
readonly supabase: TypedSupabaseClient;
|
|
17
|
+
readonly auth: AuthModule;
|
|
18
|
+
readonly market: MarketModule;
|
|
19
|
+
readonly strategy: StrategyModule;
|
|
20
|
+
readonly portfolio: PortfolioModule;
|
|
21
|
+
}
|
|
22
|
+
export declare function createLivefolioClient(supabase: TypedSupabaseClient): LivefolioClient;
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AAEzC,YAAY,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AACnD,YAAY,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAMnD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;CACrC;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,eAAe,CAQpF"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.portfolio = exports.strategy = exports.market = exports.auth = void 0;
|
|
37
|
+
exports.createLivefolioClient = createLivefolioClient;
|
|
38
|
+
exports.auth = __importStar(require("./auth"));
|
|
39
|
+
exports.market = __importStar(require("./market"));
|
|
40
|
+
exports.strategy = __importStar(require("./strategy"));
|
|
41
|
+
exports.portfolio = __importStar(require("./portfolio"));
|
|
42
|
+
const auth_1 = require("./auth");
|
|
43
|
+
const market_1 = require("./market");
|
|
44
|
+
const strategy_1 = require("./strategy");
|
|
45
|
+
const portfolio_1 = require("./portfolio");
|
|
46
|
+
function createLivefolioClient(supabase) {
|
|
47
|
+
return {
|
|
48
|
+
supabase,
|
|
49
|
+
auth: (0, auth_1.createAuth)(supabase),
|
|
50
|
+
market: (0, market_1.createMarket)(supabase),
|
|
51
|
+
strategy: (0, strategy_1.createStrategy)(supabase),
|
|
52
|
+
portfolio: (0, portfolio_1.createPortfolio)(supabase),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,sDAQC;AArCD,+CAA+B;AAC/B,mDAAmC;AACnC,uDAAuC;AACvC,yDAAyC;AAazC,iCAAoC;AACpC,qCAAwC;AACxC,yCAA4C;AAC5C,2CAA8C;AAU9C,SAAgB,qBAAqB,CAAC,QAA6B;IACjE,OAAO;QACL,QAAQ;QACR,IAAI,EAAE,IAAA,iBAAU,EAAC,QAAQ,CAAC;QAC1B,MAAM,EAAE,IAAA,qBAAY,EAAC,QAAQ,CAAC;QAC9B,QAAQ,EAAE,IAAA,yBAAc,EAAC,QAAQ,CAAC;QAClC,SAAS,EAAE,IAAA,2BAAe,EAAC,QAAQ,CAAC;KACrC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/market/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAA2B,YAAY,EAAE,MAAM,SAAS,CAAC;AAErE,wBAAgB,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,YAAY,CAgEtE"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMarket = createMarket;
|
|
4
|
+
function createMarket(client) {
|
|
5
|
+
return {
|
|
6
|
+
async getBatchSeries(symbols) {
|
|
7
|
+
const { data, error } = await client.functions.invoke('series', { body: { symbols } });
|
|
8
|
+
if (error)
|
|
9
|
+
throw error;
|
|
10
|
+
return data;
|
|
11
|
+
},
|
|
12
|
+
async getSeries(symbol) {
|
|
13
|
+
const result = await this.getBatchSeries([symbol]);
|
|
14
|
+
return result[symbol];
|
|
15
|
+
},
|
|
16
|
+
async getBatchQuotes(symbols) {
|
|
17
|
+
const { data, error } = await client.functions.invoke('quote', { body: { symbols } });
|
|
18
|
+
if (error)
|
|
19
|
+
throw error;
|
|
20
|
+
return data;
|
|
21
|
+
},
|
|
22
|
+
async getQuote(symbol) {
|
|
23
|
+
const result = await this.getBatchQuotes([symbol]);
|
|
24
|
+
const quote = result[symbol];
|
|
25
|
+
if (quote == null)
|
|
26
|
+
throw new Error(`No quote available for ${symbol}`);
|
|
27
|
+
return quote;
|
|
28
|
+
},
|
|
29
|
+
async getTradingDays(startDate, endDate) {
|
|
30
|
+
const { data, error } = await client
|
|
31
|
+
.from('trading_days')
|
|
32
|
+
.select('date, overnight, pre, regular, post, close')
|
|
33
|
+
.gte('date', startDate)
|
|
34
|
+
.lte('date', endDate)
|
|
35
|
+
.order('date', { ascending: true });
|
|
36
|
+
if (error)
|
|
37
|
+
throw new Error(`Failed to fetch trading days: ${error.message}`);
|
|
38
|
+
return (data ?? []).map((row) => ({
|
|
39
|
+
date: row.date,
|
|
40
|
+
open: row.regular,
|
|
41
|
+
close: row.post,
|
|
42
|
+
extended_open: row.overnight,
|
|
43
|
+
extended_close: row.close,
|
|
44
|
+
}));
|
|
45
|
+
},
|
|
46
|
+
async getTradingDay(date) {
|
|
47
|
+
const { data: row, error } = await client
|
|
48
|
+
.from('trading_days')
|
|
49
|
+
.select('date, overnight, pre, regular, post, close')
|
|
50
|
+
.eq('date', date)
|
|
51
|
+
.limit(1)
|
|
52
|
+
.maybeSingle();
|
|
53
|
+
if (error || !row)
|
|
54
|
+
return null;
|
|
55
|
+
return {
|
|
56
|
+
date: row.date,
|
|
57
|
+
open: row.regular,
|
|
58
|
+
close: row.post,
|
|
59
|
+
extended_open: row.overnight,
|
|
60
|
+
extended_close: row.close,
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/market/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/market/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMarket = void 0;
|
|
4
|
+
var client_1 = require("./client");
|
|
5
|
+
Object.defineProperty(exports, "createMarket", { enumerable: true, get: function () { return client_1.createMarket; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/market/index.ts"],"names":[],"mappings":";;;AACA,mCAAwC;AAA/B,sGAAA,YAAY,OAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface Observation {
|
|
2
|
+
timestamp: string;
|
|
3
|
+
value: number;
|
|
4
|
+
}
|
|
5
|
+
export interface TradingDay {
|
|
6
|
+
date: string;
|
|
7
|
+
open: string;
|
|
8
|
+
close: string;
|
|
9
|
+
extended_open: string;
|
|
10
|
+
extended_close: string;
|
|
11
|
+
}
|
|
12
|
+
export interface MarketModule {
|
|
13
|
+
getSeries(symbol: string): Promise<Observation[]>;
|
|
14
|
+
getBatchSeries(symbols: string[]): Promise<Record<string, Observation[]>>;
|
|
15
|
+
getQuote(symbol: string): Promise<Observation>;
|
|
16
|
+
getBatchQuotes(symbols: string[]): Promise<Record<string, Observation>>;
|
|
17
|
+
getTradingDays(startDate: string, endDate: string): Promise<TradingDay[]>;
|
|
18
|
+
getTradingDay(date: string): Promise<TradingDay | null>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/market/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAE3B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAClD,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;IAG1E,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/C,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAGxE,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1E,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;CACzD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/market/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/portfolio/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,wBAAgB,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,eAAe,CAE7E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/portfolio/client.ts"],"names":[],"mappings":";;AAGA,0CAEC;AAFD,SAAgB,eAAe,CAAC,OAA4B;IAC1D,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/portfolio/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createPortfolio = void 0;
|
|
4
|
+
var client_1 = require("./client");
|
|
5
|
+
Object.defineProperty(exports, "createPortfolio", { enumerable: true, get: function () { return client_1.createPortfolio; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/portfolio/index.ts"],"names":[],"mappings":";;;AACA,mCAA2C;AAAlC,yGAAA,eAAe,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/portfolio/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;CAE/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/portfolio/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +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,EAMV,cAAc,EAOf,MAAM,SAAS,CAAC;AAwEjB,wBAAgB,cAAc,CAAC,MAAM,EAAE,mBAAmB,GAAG,cAAc,CAwX1E"}
|