tradeblocks-mcp 2.1.0-beta.2 → 2.2.0-beta.1

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 CHANGED
@@ -52,7 +52,7 @@ node packages/mcp-server/server/index.js ~/Trading/backtests
52
52
  2. **Connect your AI platform** - See [Configuration by Platform](#configuration-by-platform) below
53
53
  3. **Start analyzing** - Ask your AI to "list my backtests" or "run a health check on iron-condor"
54
54
 
55
- For detailed usage examples, see [docs/USAGE.md](docs/USAGE.md).
55
+ For detailed usage examples, see [../../docs/usage.md](../../docs/usage.md).
56
56
 
57
57
  ## Configuration by Platform
58
58
 
@@ -131,7 +131,7 @@ tradeblocks-mcp --http ~/Trading/backtests
131
131
 
132
132
  Then expose port 3100 however you prefer (ngrok, Cloudflare Tunnel, reverse proxy, Docker on a server, etc.) and add the URL (`https://your-host/mcp`) to your platform's MCP settings.
133
133
 
134
- See [Web Platforms Guide](docs/WEB-PLATFORMS.md) for platform-specific setup, or [Docker Deployment](#docker-deployment) for running on a remote server.
134
+ See [Web Platforms Guide](../../docs/web-platforms.md) for platform-specific setup, or [Docker Deployment](#docker-deployment) for running on a remote server.
135
135
 
136
136
  ## Transport Modes
137
137
 
@@ -361,12 +361,12 @@ Market data lives in a separate `market.duckdb` (configurable via `MARKET_DB_PAT
361
361
  - `market.context` — VIX / volatility context (keyed by `date`)
362
362
  - `market.intraday` — Intraday bars at any resolution (keyed by `ticker, date, time`)
363
363
 
364
- See [scripts/README.md](../../scripts/README.md) for import examples and column mapping reference.
364
+ See the [Market Data Guide](../../docs/market-data.md) for import examples, ticker formats, and column mapping reference.
365
365
 
366
366
  ## Related
367
367
 
368
- - [Usage Guide](docs/USAGE.md) - Detailed usage examples and workflows
369
- - [Web Platforms Guide](docs/WEB-PLATFORMS.md) - Connect to ChatGPT, Google AI Studio, Julius
368
+ - [Usage Guide](../../docs/usage.md) - Detailed usage examples and workflows
369
+ - [Web Platforms Guide](../../docs/web-platforms.md) - Connect to ChatGPT, Google AI Studio, Julius
370
370
  - [Agent Skills](../agent-skills/README.md) - Conversational workflows for guided analysis
371
- - [Market Data Import](../../scripts/README.md) - Import workflow and column mapping reference
371
+ - [Market Data Guide](../../docs/market-data.md) - Import workflow, Massive API, and column mapping reference
372
372
  - [Main Application](../../README.md) - Web-based UI for TradeBlocks
@@ -104,6 +104,59 @@ async function ensureReportingDataTable(conn) {
104
104
  }
105
105
 
106
106
  // src/db/market-schemas.ts
107
+ async function migrateContextToNormalized(conn) {
108
+ try {
109
+ const migrationCheck = await conn.runAndReadAll(
110
+ `SELECT 1 FROM market._sync_metadata WHERE source = 'migration:context_to_normalized'`
111
+ );
112
+ if (migrationCheck.getRows().length > 0) return { rowsMigrated: 0 };
113
+ } catch {
114
+ }
115
+ let contextCount = 0;
116
+ try {
117
+ const r = await conn.runAndReadAll(`SELECT COUNT(*) FROM market.context`);
118
+ contextCount = Number(r.getRows()[0]?.[0] ?? 0);
119
+ } catch {
120
+ return { rowsMigrated: 0 };
121
+ }
122
+ if (contextCount === 0) return { rowsMigrated: 0 };
123
+ let totalMigrated = 0;
124
+ const vixResult = await conn.run(`
125
+ INSERT OR IGNORE INTO market.daily (ticker, date, open, high, low, close, ivr, ivp)
126
+ SELECT 'VIX', date, VIX_Open, VIX_High, VIX_Low, VIX_Close, VIX_IVR, VIX_IVP
127
+ FROM market.context
128
+ WHERE VIX_Close IS NOT NULL
129
+ `);
130
+ totalMigrated += Number(vixResult.rowsChanged);
131
+ const vix9dResult = await conn.run(`
132
+ INSERT OR IGNORE INTO market.daily (ticker, date, open, close, ivr, ivp)
133
+ SELECT 'VIX9D', date, VIX9D_Open, VIX9D_Close, VIX9D_IVR, VIX9D_IVP
134
+ FROM market.context
135
+ WHERE VIX9D_Close IS NOT NULL
136
+ `);
137
+ totalMigrated += Number(vix9dResult.rowsChanged);
138
+ const vix3mResult = await conn.run(`
139
+ INSERT OR IGNORE INTO market.daily (ticker, date, open, close, ivr, ivp)
140
+ SELECT 'VIX3M', date, VIX3M_Open, VIX3M_Close, VIX3M_IVR, VIX3M_IVP
141
+ FROM market.context
142
+ WHERE VIX3M_Close IS NOT NULL
143
+ `);
144
+ totalMigrated += Number(vix3mResult.rowsChanged);
145
+ await conn.run(`
146
+ INSERT OR IGNORE INTO market._context_derived (date, Vol_Regime, Term_Structure_State, Trend_Direction, VIX_Spike_Pct, VIX_Gap_Pct)
147
+ SELECT date, Vol_Regime, Term_Structure_State, Trend_Direction, VIX_Spike_Pct, VIX_Gap_Pct
148
+ FROM market.context
149
+ WHERE Vol_Regime IS NOT NULL OR Term_Structure_State IS NOT NULL
150
+ `);
151
+ try {
152
+ await conn.run(`
153
+ INSERT OR REPLACE INTO market._sync_metadata (source, ticker, target_table, max_date, enriched_through, synced_at)
154
+ VALUES ('migration:context_to_normalized', '_system', '_system', NULL, NULL, CURRENT_TIMESTAMP)
155
+ `);
156
+ } catch {
157
+ }
158
+ return { rowsMigrated: totalMigrated };
159
+ }
107
160
  async function ensureMarketTables(conn) {
108
161
  await conn.run(`
109
162
  CREATE TABLE IF NOT EXISTS market.daily (
@@ -123,8 +176,6 @@ async function ensureMarketTables(conn) {
123
176
  RSI_14 DOUBLE,
124
177
  Price_vs_EMA21_Pct DOUBLE,
125
178
  Price_vs_SMA50_Pct DOUBLE,
126
- BB_Position DOUBLE,
127
- BB_Width DOUBLE,
128
179
  Realized_Vol_5D DOUBLE,
129
180
  Realized_Vol_20D DOUBLE,
130
181
  Return_5D DOUBLE,
@@ -157,6 +208,12 @@ async function ensureMarketTables(conn) {
157
208
  await conn.run(`ALTER TABLE market.daily DROP COLUMN Trend_Score`);
158
209
  } catch {
159
210
  }
211
+ for (const col of ["BB_Position", "BB_Width"]) {
212
+ try {
213
+ await conn.run(`ALTER TABLE market.daily DROP COLUMN ${col}`);
214
+ } catch {
215
+ }
216
+ }
160
217
  for (const col of [
161
218
  { name: "Opening_Drive_Strength", type: "DOUBLE" },
162
219
  { name: "Intraday_Realized_Vol", type: "DOUBLE" }
@@ -166,6 +223,15 @@ async function ensureMarketTables(conn) {
166
223
  } catch {
167
224
  }
168
225
  }
226
+ for (const col of [
227
+ { name: "ivr", type: "DOUBLE" },
228
+ { name: "ivp", type: "DOUBLE" }
229
+ ]) {
230
+ try {
231
+ await conn.run(`ALTER TABLE market.daily ADD COLUMN ${col.name} ${col.type}`);
232
+ } catch {
233
+ }
234
+ }
169
235
  await conn.run(`
170
236
  CREATE TABLE IF NOT EXISTS market.context (
171
237
  date VARCHAR NOT NULL,
@@ -187,13 +253,28 @@ async function ensureMarketTables(conn) {
187
253
  VIX_VIX3M_Ratio DOUBLE,
188
254
  Vol_Regime INTEGER,
189
255
  Term_Structure_State INTEGER,
190
- VIX_Percentile DOUBLE,
256
+ VIX_IVR DOUBLE,
257
+ VIX_IVP DOUBLE,
258
+ VIX9D_IVR DOUBLE,
259
+ VIX9D_IVP DOUBLE,
260
+ VIX3M_IVR DOUBLE,
261
+ VIX3M_IVP DOUBLE,
191
262
  VIX_Spike_Pct DOUBLE,
192
263
  Trend_Direction VARCHAR,
193
264
 
194
265
  PRIMARY KEY (date)
195
266
  )
196
267
  `);
268
+ await conn.run(`
269
+ CREATE TABLE IF NOT EXISTS market._context_derived (
270
+ date VARCHAR NOT NULL PRIMARY KEY,
271
+ Vol_Regime INTEGER,
272
+ Term_Structure_State INTEGER,
273
+ Trend_Direction VARCHAR,
274
+ VIX_Spike_Pct DOUBLE,
275
+ VIX_Gap_Pct DOUBLE
276
+ )
277
+ `);
197
278
  try {
198
279
  await conn.run(`ALTER TABLE market.context ADD COLUMN VIX_RTH_Open DOUBLE`);
199
280
  } catch {
@@ -202,6 +283,16 @@ async function ensureMarketTables(conn) {
202
283
  await conn.run(`ALTER TABLE market.context ADD COLUMN Trend_Direction VARCHAR`);
203
284
  } catch {
204
285
  }
286
+ try {
287
+ await conn.run(`ALTER TABLE market.context RENAME COLUMN VIX_Percentile TO VIX_IVP`);
288
+ } catch {
289
+ }
290
+ for (const col of ["VIX_IVR", "VIX9D_IVR", "VIX9D_IVP", "VIX3M_IVR", "VIX3M_IVP"]) {
291
+ try {
292
+ await conn.run(`ALTER TABLE market.context ADD COLUMN ${col} DOUBLE`);
293
+ } catch {
294
+ }
295
+ }
205
296
  await conn.run(`
206
297
  CREATE TABLE IF NOT EXISTS market.intraday (
207
298
  ticker VARCHAR NOT NULL,
@@ -231,6 +322,7 @@ async function ensureMarketTables(conn) {
231
322
  PRIMARY KEY (source, ticker, target_table)
232
323
  )
233
324
  `);
325
+ await migrateContextToNormalized(conn);
234
326
  }
235
327
 
236
328
  // src/db/profile-schemas.ts
@@ -22652,4 +22744,4 @@ decimal.js/decimal.mjs:
22652
22744
  * MIT Licence
22653
22745
  *)
22654
22746
  */
22655
- //# sourceMappingURL=chunk-BWUJ5CO2.js.map
22747
+ //# sourceMappingURL=chunk-YB2K6ONA.js.map