tradeblocks-mcp 3.0.2 → 3.3.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.
Files changed (218) hide show
  1. package/README.md +85 -80
  2. package/dist/{chunk-LDKTV7GW.js → chunk-27S67XW3.js} +24 -52
  3. package/dist/chunk-27S67XW3.js.map +1 -0
  4. package/dist/{chunk-FGZH632F.js → chunk-2E63THNI.js} +13 -11
  5. package/dist/chunk-2E63THNI.js.map +1 -0
  6. package/dist/{chunk-QTTR7AAW.js → chunk-2I3S2ZLT.js} +325 -84
  7. package/dist/chunk-2I3S2ZLT.js.map +1 -0
  8. package/dist/{chunk-4BLCXNQ6.js → chunk-4HZLVUOZ.js} +179 -183
  9. package/dist/chunk-4HZLVUOZ.js.map +1 -0
  10. package/dist/{chunk-XXYOUIZY.js → chunk-NWNSKALN.js} +63 -80
  11. package/dist/chunk-NWNSKALN.js.map +1 -0
  12. package/dist/{chunk-PRAYH3RT.js → chunk-WNTYA7ER.js} +29 -12
  13. package/dist/chunk-WNTYA7ER.js.map +1 -0
  14. package/dist/{chunk-BKQ4PM4Y.js → chunk-YZA4RS76.js} +24 -18
  15. package/dist/chunk-YZA4RS76.js.map +1 -0
  16. package/dist/{chunk-W2PP3LEH.js → chunk-ZTJXC3LS.js} +17 -8
  17. package/dist/chunk-ZTJXC3LS.js.map +1 -0
  18. package/dist/daily-log-processor-MZW2XBZY.js +9 -0
  19. package/dist/{daily-logs-store-D3QC2XPV.js → daily-logs-store-3C3OTGPK.js} +2 -2
  20. package/dist/iv-solver-worker.js +9 -1
  21. package/dist/market-provider-6U33TQUT.js +16 -0
  22. package/dist/{proto-3HZTCWK4.js → proto-V23GIZG2.js} +2 -2
  23. package/dist/{sync-PO4IPCYV.js → sync-3UBC37VW.js} +7 -7
  24. package/dist/test-exports.js +876 -483
  25. package/dist/test-exports.js.map +1 -1
  26. package/dist/trade-processor-DKDCWGKD.js +9 -0
  27. package/dist/{trades-store-LOL3FQSF.js → trades-store-R3NL25T2.js} +2 -2
  28. package/package.json +2 -6
  29. package/server/{chunk-CSDVJPBB.js → chunk-536NSFED.js} +29 -12
  30. package/server/chunk-536NSFED.js.map +1 -0
  31. package/server/{chunk-WA5AAPCH.js → chunk-A3UKD64A.js} +17 -8
  32. package/server/chunk-A3UKD64A.js.map +1 -0
  33. package/server/{chunk-PNKG7RY7.js → chunk-OMUDNJBJ.js} +63 -80
  34. package/server/chunk-OMUDNJBJ.js.map +1 -0
  35. package/server/{chunk-72GKJE2U.js → chunk-RJDJHZ5Y.js} +934 -335
  36. package/server/chunk-RJDJHZ5Y.js.map +1 -0
  37. package/server/{chunk-NZO6PT64.js → chunk-RM4B2VKS.js} +167 -177
  38. package/server/chunk-RM4B2VKS.js.map +1 -0
  39. package/server/{chunk-5EBXHT6C.js → chunk-SY6GDNVI.js} +24 -18
  40. package/server/chunk-SY6GDNVI.js.map +1 -0
  41. package/server/{chunk-FBNDMCT5.js → chunk-T66KH2XH.js} +13 -11
  42. package/server/chunk-T66KH2XH.js.map +1 -0
  43. package/server/{chunk-NRFXAJF7.js → chunk-W5E7FHC4.js} +24 -52
  44. package/server/chunk-W5E7FHC4.js.map +1 -0
  45. package/server/{config-6IZXEFEX.js → config-DK7KOMNL.js} +1 -1
  46. package/server/config-DK7KOMNL.js.map +1 -0
  47. package/server/daily-log-processor-B2VPU2FQ.js +10 -0
  48. package/server/{daily-logs-store-NU7M4L5C.js → daily-logs-store-YFNXTB7J.js} +2 -2
  49. package/server/http-server.js +2 -5
  50. package/server/index.js +2497 -2029
  51. package/server/index.js.map +1 -1
  52. package/server/iv-solver-worker.js +9 -1
  53. package/server/market-provider-L56RFHAC.js +17 -0
  54. package/server/{proto-DWRZJO4E.js → proto-YZ4TLX2N.js} +2 -2
  55. package/server/{sync-QFI5L7S7.js → sync-CENKDN53.js} +7 -7
  56. package/server/trade-processor-3PI4LHZI.js +10 -0
  57. package/server/{trades-store-VY26MWER.js → trades-store-RTTEYMXH.js} +2 -2
  58. package/src/auth/clients-store.ts +4 -4
  59. package/src/auth/code-store.ts +1 -1
  60. package/src/auth/config.ts +11 -12
  61. package/src/auth/login-page.ts +8 -10
  62. package/src/auth/provider.ts +35 -30
  63. package/src/auth/token.ts +17 -15
  64. package/src/db/backtest-schemas.ts +38 -8
  65. package/src/db/connection.ts +107 -40
  66. package/src/db/data-root.ts +22 -0
  67. package/src/db/index.ts +37 -5
  68. package/src/db/json-adapters.ts +22 -31
  69. package/src/db/json-migration.ts +11 -15
  70. package/src/db/json-store.ts +5 -3
  71. package/src/db/market-datasets.ts +48 -15
  72. package/src/db/market-schemas.ts +11 -5
  73. package/src/db/market-views.ts +119 -32
  74. package/src/db/parquet-writer.ts +7 -7
  75. package/src/db/profile-schemas.ts +39 -22
  76. package/src/db/schemas.ts +2 -2
  77. package/src/http-server.ts +7 -12
  78. package/src/index.ts +8 -9
  79. package/src/market/ingestor/index.ts +1 -4
  80. package/src/market/ingestor/market-ingestor.ts +140 -67
  81. package/src/market/ingestor/types.ts +1 -3
  82. package/src/market/stores/chain-sql.ts +2 -8
  83. package/src/market/stores/chain-store.ts +1 -4
  84. package/src/market/stores/duckdb-chain-store.ts +3 -14
  85. package/src/market/stores/duckdb-enriched-store.ts +3 -13
  86. package/src/market/stores/duckdb-quote-store.ts +10 -27
  87. package/src/market/stores/duckdb-spot-store.ts +4 -20
  88. package/src/market/stores/enriched-sql.ts +3 -9
  89. package/src/market/stores/enriched-store.ts +2 -2
  90. package/src/market/stores/parquet-chain-store.ts +5 -22
  91. package/src/market/stores/parquet-enriched-store.ts +4 -16
  92. package/src/market/stores/parquet-oi-daily-store.ts +3 -14
  93. package/src/market/stores/parquet-quote-store.ts +9 -29
  94. package/src/market/stores/parquet-spot-store.ts +14 -33
  95. package/src/market/stores/quote-store.ts +2 -10
  96. package/src/market/stores/spot-sql.ts +3 -15
  97. package/src/market/stores/spot-store.ts +1 -1
  98. package/src/market/tickers/defaults.json +6 -6
  99. package/src/market/tickers/loader.ts +2 -7
  100. package/src/market/tickers/registry.ts +5 -15
  101. package/src/market/tickers/schemas.ts +2 -6
  102. package/src/models/strategy-profile.ts +39 -39
  103. package/src/sync/block-sync.ts +44 -65
  104. package/src/sync/index.ts +1 -4
  105. package/src/sync/metadata.ts +14 -20
  106. package/src/test-exports.ts +139 -123
  107. package/src/tools/analysis.ts +180 -159
  108. package/src/tools/batch-exit-analysis.ts +100 -59
  109. package/src/tools/blocks/analysis.ts +116 -101
  110. package/src/tools/blocks/comparison.ts +281 -364
  111. package/src/tools/blocks/core.ts +208 -253
  112. package/src/tools/blocks/health.ts +571 -563
  113. package/src/tools/blocks/index.ts +2 -0
  114. package/src/tools/blocks/paired-comparison.ts +425 -0
  115. package/src/tools/blocks/similarity.ts +316 -283
  116. package/src/tools/edge-decay.ts +124 -197
  117. package/src/tools/exit-analysis.ts +130 -77
  118. package/src/tools/greeks-attribution.ts +84 -35
  119. package/src/tools/guides.ts +4 -6
  120. package/src/tools/imports.ts +11 -14
  121. package/src/tools/market-data.ts +1067 -757
  122. package/src/tools/market-enrichment.ts +3 -3
  123. package/src/tools/market-fetch.ts +148 -67
  124. package/src/tools/market-imports.ts +12 -12
  125. package/src/tools/middleware/sync-middleware.ts +5 -6
  126. package/src/tools/performance.ts +185 -302
  127. package/src/tools/profile-analysis.ts +52 -66
  128. package/src/tools/profiles.ts +106 -69
  129. package/src/tools/regime-advisor.ts +20 -45
  130. package/src/tools/replay.ts +81 -77
  131. package/src/tools/reports/discrepancies.ts +298 -328
  132. package/src/tools/reports/fields.ts +7 -25
  133. package/src/tools/reports/helpers.ts +18 -49
  134. package/src/tools/reports/predictive.ts +27 -70
  135. package/src/tools/reports/slippage-trends.ts +315 -345
  136. package/src/tools/reports/slippage.ts +1 -4
  137. package/src/tools/reports/strategy-matches.ts +399 -441
  138. package/src/tools/schema.ts +43 -40
  139. package/src/tools/shared/filters.ts +3 -9
  140. package/src/tools/snapshot.ts +9 -30
  141. package/src/tools/sql.ts +15 -14
  142. package/src/tools/tickers.ts +1 -4
  143. package/src/utils/batch-exit-analysis.ts +31 -42
  144. package/src/utils/black-scholes.ts +39 -29
  145. package/src/utils/block-loader.ts +69 -83
  146. package/src/utils/calibration-probe.ts +3 -4
  147. package/src/utils/chain-loader.ts +3 -3
  148. package/src/utils/csv-discovery.ts +16 -22
  149. package/src/utils/data-quality.ts +24 -36
  150. package/src/utils/exit-triggers.ts +91 -96
  151. package/src/utils/field-timing.ts +94 -79
  152. package/src/utils/filter-predicates.ts +13 -9
  153. package/src/utils/flatfile-importer.ts +94 -64
  154. package/src/utils/greeks-decomposition.ts +152 -100
  155. package/src/utils/iv-solver-pool.ts +55 -25
  156. package/src/utils/iv-solver-worker.ts +5 -5
  157. package/src/utils/market-enricher.ts +528 -497
  158. package/src/utils/market-importer.ts +31 -12
  159. package/src/utils/market-provider.ts +21 -23
  160. package/src/utils/massive-tier.ts +5 -7
  161. package/src/utils/migrate-option-data-helpers.ts +2 -8
  162. package/src/utils/option-quote-greeks.ts +25 -31
  163. package/src/utils/option-time.ts +4 -8
  164. package/src/utils/output-formatter.ts +1 -4
  165. package/src/utils/provider-capabilities.ts +1 -4
  166. package/src/utils/providers/massive.ts +59 -93
  167. package/src/utils/providers/thetadata/backfill.ts +14 -23
  168. package/src/utils/providers/thetadata/client.ts +12 -8
  169. package/src/utils/providers/thetadata/decode.ts +2 -20
  170. package/src/utils/providers/thetadata/endpoints.ts +32 -40
  171. package/src/utils/providers/thetadata/join.ts +11 -10
  172. package/src/utils/providers/thetadata/proto.ts +12 -10
  173. package/src/utils/providers/thetadata/quote-mid-greeks.ts +5 -5
  174. package/src/utils/providers/thetadata.ts +11 -10
  175. package/src/utils/quote-enricher.ts +4 -4
  176. package/src/utils/quote-parquet-projection.ts +3 -11
  177. package/src/utils/sample-date-selector.ts +3 -5
  178. package/src/utils/schema-metadata.ts +102 -70
  179. package/src/utils/ticker.ts +5 -9
  180. package/src/utils/trade-replay.ts +77 -68
  181. package/dist/chunk-4BLCXNQ6.js.map +0 -1
  182. package/dist/chunk-BKQ4PM4Y.js.map +0 -1
  183. package/dist/chunk-FGZH632F.js.map +0 -1
  184. package/dist/chunk-LDKTV7GW.js.map +0 -1
  185. package/dist/chunk-PRAYH3RT.js.map +0 -1
  186. package/dist/chunk-QTTR7AAW.js.map +0 -1
  187. package/dist/chunk-W2PP3LEH.js.map +0 -1
  188. package/dist/chunk-XXYOUIZY.js.map +0 -1
  189. package/dist/daily-log-processor-6MWJ23JK.js +0 -9
  190. package/dist/market-provider-VDRJUEF2.js +0 -16
  191. package/dist/trade-processor-NHU4VWRX.js +0 -9
  192. package/manifest.json +0 -141
  193. package/server/chunk-5EBXHT6C.js.map +0 -1
  194. package/server/chunk-72GKJE2U.js.map +0 -1
  195. package/server/chunk-CSDVJPBB.js.map +0 -1
  196. package/server/chunk-FBNDMCT5.js.map +0 -1
  197. package/server/chunk-NRFXAJF7.js.map +0 -1
  198. package/server/chunk-NZO6PT64.js.map +0 -1
  199. package/server/chunk-PNKG7RY7.js.map +0 -1
  200. package/server/chunk-WA5AAPCH.js.map +0 -1
  201. package/server/config-6IZXEFEX.js.map +0 -1
  202. package/server/daily-log-processor-Y3PVSVBM.js +0 -10
  203. package/server/market-provider-VOYYVYWT.js +0 -17
  204. package/server/trade-processor-JWVS37KM.js +0 -10
  205. /package/dist/{daily-log-processor-6MWJ23JK.js.map → daily-log-processor-MZW2XBZY.js.map} +0 -0
  206. /package/dist/{daily-logs-store-D3QC2XPV.js.map → daily-logs-store-3C3OTGPK.js.map} +0 -0
  207. /package/dist/{market-provider-VDRJUEF2.js.map → market-provider-6U33TQUT.js.map} +0 -0
  208. /package/dist/{proto-3HZTCWK4.js.map → proto-V23GIZG2.js.map} +0 -0
  209. /package/dist/{sync-PO4IPCYV.js.map → sync-3UBC37VW.js.map} +0 -0
  210. /package/dist/{trade-processor-NHU4VWRX.js.map → trade-processor-DKDCWGKD.js.map} +0 -0
  211. /package/dist/{trades-store-LOL3FQSF.js.map → trades-store-R3NL25T2.js.map} +0 -0
  212. /package/server/{daily-log-processor-Y3PVSVBM.js.map → daily-log-processor-B2VPU2FQ.js.map} +0 -0
  213. /package/server/{daily-logs-store-NU7M4L5C.js.map → daily-logs-store-YFNXTB7J.js.map} +0 -0
  214. /package/server/{market-provider-VOYYVYWT.js.map → market-provider-L56RFHAC.js.map} +0 -0
  215. /package/server/{proto-DWRZJO4E.js.map → proto-YZ4TLX2N.js.map} +0 -0
  216. /package/server/{sync-QFI5L7S7.js.map → sync-CENKDN53.js.map} +0 -0
  217. /package/server/{trade-processor-JWVS37KM.js.map → trade-processor-3PI4LHZI.js.map} +0 -0
  218. /package/server/{trades-store-VY26MWER.js.map → trades-store-RTTEYMXH.js.map} +0 -0
@@ -1,9 +0,0 @@
1
- import {
2
- DailyLogProcessor
3
- } from "./chunk-W2PP3LEH.js";
4
- import "./chunk-BKQ4PM4Y.js";
5
- import "./chunk-5WRI5ZAA.js";
6
- export {
7
- DailyLogProcessor
8
- };
9
- //# sourceMappingURL=daily-log-processor-6MWJ23JK.js.map
@@ -1,16 +0,0 @@
1
- import {
2
- _resetProvider,
3
- getProvider
4
- } from "./chunk-XXYOUIZY.js";
5
- import "./chunk-QTTR7AAW.js";
6
- import "./chunk-PRAYH3RT.js";
7
- import "./chunk-W2PP3LEH.js";
8
- import "./chunk-BKQ4PM4Y.js";
9
- import "./chunk-LDKTV7GW.js";
10
- import "./chunk-FGZH632F.js";
11
- import "./chunk-5WRI5ZAA.js";
12
- export {
13
- _resetProvider,
14
- getProvider
15
- };
16
- //# sourceMappingURL=market-provider-VDRJUEF2.js.map
@@ -1,9 +0,0 @@
1
- import {
2
- TradeProcessor
3
- } from "./chunk-PRAYH3RT.js";
4
- import "./chunk-BKQ4PM4Y.js";
5
- import "./chunk-5WRI5ZAA.js";
6
- export {
7
- TradeProcessor
8
- };
9
- //# sourceMappingURL=trade-processor-NHU4VWRX.js.map
package/manifest.json DELETED
@@ -1,141 +0,0 @@
1
- {
2
- "manifest_version": "0.3",
3
- "name": "tradeblocks",
4
- "display_name": "TradeBlocks",
5
- "version": "3.0.2",
6
- "description": "Options trading analysis - backtest stats, walk-forward analysis, Monte Carlo simulations, and risk metrics",
7
- "long_description": "TradeBlocks MCP server provides comprehensive options trading analysis capabilities. Import your trade logs and get detailed performance statistics, run walk-forward analysis to detect overfitting, perform Monte Carlo simulations for risk assessment, calculate optimal position sizing with Kelly criterion, and compare backtest results against actual trading performance. All analysis runs locally on your machine.",
8
- "author": {
9
- "name": "David Romeo",
10
- "url": "https://github.com/davidromeo"
11
- },
12
- "repository": {
13
- "type": "git",
14
- "url": "https://github.com/tradeblocks-org/tradeblocks"
15
- },
16
- "homepage": "https://github.com/tradeblocks-org/tradeblocks",
17
- "documentation": "https://github.com/tradeblocks-org/tradeblocks/tree/master/packages/mcp-server",
18
- "support": "https://github.com/tradeblocks-org/tradeblocks/issues",
19
- "server": {
20
- "type": "node",
21
- "entry_point": "server/index.js",
22
- "mcp_config": {
23
- "command": "node",
24
- "args": [
25
- "${__dirname}/server/index.js"
26
- ],
27
- "env": {
28
- "BLOCKS_DIRECTORY": "${user_config.blocks_directory}"
29
- }
30
- }
31
- },
32
- "tools": [
33
- {
34
- "name": "list_blocks",
35
- "description": "List all available trading backtests/blocks in the configured directory"
36
- },
37
- {
38
- "name": "get_statistics",
39
- "description": "Get comprehensive performance statistics for a backtest including P&L, win rate, drawdowns, Sharpe ratio"
40
- },
41
- {
42
- "name": "run_walk_forward",
43
- "description": "Run walk-forward analysis to test strategy robustness and detect overfitting"
44
- },
45
- {
46
- "name": "run_monte_carlo",
47
- "description": "Monte Carlo simulation for risk assessment and confidence intervals"
48
- },
49
- {
50
- "name": "calculate_correlation",
51
- "description": "Calculate correlation between multiple strategies using Kendall's tau"
52
- },
53
- {
54
- "name": "get_tail_risk",
55
- "description": "Analyze tail risk metrics including VaR, CVaR, and maximum drawdown"
56
- },
57
- {
58
- "name": "calculate_position_sizing",
59
- "description": "Calculate optimal position size using Kelly criterion with safety adjustments"
60
- },
61
- {
62
- "name": "get_performance_charts",
63
- "description": "Get chart data for equity curves, drawdowns, returns distribution, and more"
64
- },
65
- {
66
- "name": "get_period_returns",
67
- "description": "Get returns aggregated by time period (daily, weekly, monthly, yearly)"
68
- },
69
- {
70
- "name": "compare_backtest_vs_actual",
71
- "description": "Compare backtest results against actual live trading performance"
72
- },
73
- {
74
- "name": "list_available_fields",
75
- "description": "List all filterable fields available for trade queries"
76
- },
77
- {
78
- "name": "run_filtered_query",
79
- "description": "Query trades with filters and return matching results"
80
- },
81
- {
82
- "name": "get_field_statistics",
83
- "description": "Get statistics for a specific trade field"
84
- },
85
- {
86
- "name": "aggregate_by_field",
87
- "description": "Aggregate trade data by field values"
88
- }
89
- ],
90
- "prompts": [
91
- {
92
- "name": "getting_started",
93
- "description": "How to set up and use TradeBlocks for trading analysis",
94
- "text": "# Getting Started with TradeBlocks\n\n## Setup\nYour trading data should be in your configured Trading Data Directory. Each strategy/backtest is a **block** - a folder containing:\n- `tradelog.csv` (required): Your trade records with columns like Date Opened, Date Closed, P/L, etc.\n- `dailylog.csv` (optional): Daily portfolio values for more accurate drawdown calculations\n\n## Adding New Backtests\nTo add a new backtest for analysis:\n1. Create a new folder in your Trading Data Directory (e.g., `my-strategy-2024`)\n2. Export your trade log CSV from Option Omega (or other backtesting platform)\n3. Save it as `tradelog.csv` in the new folder\n4. The block will appear when you run `list_blocks`\n\n**Folder structure example:**\n```\nTrading Data Directory/\n my-strategy-2024/\n tradelog.csv\n dailylog.csv (optional)\n another-strategy/\n tradelog.csv\n```\n\n## Quick Start\n1. **List your blocks**: Use `list_blocks` to see available strategies\n2. **Get statistics**: Use `get_statistics` with a block ID to see performance metrics\n3. **Run analysis**: Use `run_walk_forward` or `run_monte_carlo` for deeper analysis"
95
- },
96
- {
97
- "name": "analyze_strategy",
98
- "description": "Comprehensive strategy analysis workflow",
99
- "arguments": [
100
- "block_id"
101
- ],
102
- "text": "Analyze the strategy '${arguments.block_id}' comprehensively:\n\n1. First get basic statistics with `get_statistics`\n2. Run walk-forward analysis with `run_walk_forward` to check for overfitting\n3. Run Monte Carlo simulation with `run_monte_carlo` for risk assessment\n4. Calculate position sizing with `calculate_position_sizing`\n5. Check tail risk with `get_tail_risk`\n\nProvide insights on:\n- Is this strategy robust or potentially overfit?\n- What position size is appropriate given the risk?\n- What are the worst-case scenarios?\n- Any red flags or concerns?"
103
- },
104
- {
105
- "name": "optionomega_guide",
106
- "description": "Guide for setting up Option Omega backtests that export clean data for TradeBlocks",
107
- "text": "# Option Omega Backtest Setup for TradeBlocks\n\n## Supported Assets\nSPY, SPX (afternoon expirations only), QQQ, IWM, AAPL, TSLA\n- Historical data from January 1, 2013 through previous trading day\n- Data updates overnight (3-5am ET), available before market open\n\n## Strategy Configuration\n\n### Strike Selection Methods\n- **Delta**: Select strikes by delta value (default)\n- **Percentage OTM**: Target specific out-of-the-money distances\n- **Fixed Premium**: Choose strikes nearest a specified price\n- **Strike Offset**: Position relative to parent legs (for linked legs)\n\n### Option Legs\n- Up to 8 legs per backtest\n- Linked legs for dependent strike selections\n- Round strikes to nearest multiples for liquidity\n\n## Entry Configuration\n\n### Timing\n- Entry window: 9:32am - 3:59pm ET (1-minute intervals)\n- Frequency: Daily, Weekly (specific days), Monthly (specific dates), or Specific Dates\n\n### Entry Filters (Optional)\n- VIX levels (min/max), VIX movement\n- Technical indicators: RSI (14-day), SMA, EMA\n- Opening Range Breakout (ORB)\n- Gap conditions, intraday movement\n- SqueezeMetrics: DIX, GEX, GXV\n\n## Exit Conditions\n\n### Profit/Loss Targets\n- Percentage-based\n- Fixed dollar amount\n- Closing order price\n\n### Stop Loss Options\n- Fixed stop loss\n- Trailing stop (recalculated or fixed)\n- 0-DTE intra-minute stops (SPX/SPY only)\n- Per-leg stop loss\n\n### Time-Based Exits\n- By DTE remaining\n- Days in trade\n- Minutes in trade\n\n### Other Exits\n- Technical indicator triggers\n- Delta-based (position or leg level)\n- Short tested / underlying movement\n\n## Risk Controls (The Punisher)\n- Commission/fee modeling (per contract)\n- Slippage adjustments (entry, exit, stop loss)\n- Bid-ask spread filter (default: 10,000 bps max)\n- Consecutive hits requirement (2 intervals at target/stop)\n- Min/max entry premium filters\n- Blackout days\n- Re-entry delays after exits\n\n## Data Quality Notes\n- Uses mid-price from OPRA bid/ask data\n- 1-minute resolution (open price for signals)\n- RTH only (9:30-4:00 market time)\n- SPX uses standard EOD contracts only (no AM expirations)\n- Calendar days for DTE calculations\n- March 2020 / Spring 2025 show unusual volatility\n\n## Exporting for TradeBlocks\n\n1. Run your backtest in Option Omega\n2. Go to Results -> Trade Log\n3. Click Export/Download CSV\n4. Create a new folder in your Trading Data Directory (e.g., `my-strategy-2024`)\n5. Save the CSV as `tradelog.csv` in that folder\n6. Run `list_blocks` to see your new block\n\nTradeBlocks expects these columns (Option Omega exports them automatically):\n- Date Opened, Time Opened\n- Date Closed, Time Closed\n- P/L, Strategy, Legs\n- No. of Contracts, Premium\n- Opening/Closing Prices\n- Reason For Close\n\n**Note**: The visual context from Option Omega's trade log (replay, charts) is lost in CSV export. TradeBlocks provides its own analysis tools to compensate."
108
- }
109
- ],
110
- "keywords": [
111
- "trading",
112
- "options",
113
- "backtest",
114
- "analysis",
115
- "walk-forward",
116
- "monte-carlo",
117
- "risk",
118
- "portfolio"
119
- ],
120
- "license": "MIT",
121
- "user_config": {
122
- "blocks_directory": {
123
- "type": "directory",
124
- "title": "Trading Data Directory",
125
- "description": "Directory containing your trading data blocks. Each block is a folder with tradelog.csv and optional dailylog.csv",
126
- "required": true
127
- }
128
- },
129
- "compatibility": {
130
- "claude_desktop": ">=0.10.0",
131
- "platforms": [
132
- "darwin",
133
- "win32",
134
- "linux"
135
- ],
136
- "runtimes": {
137
- "node": ">=18.0.0"
138
- }
139
- },
140
- "privacy_policies": []
141
- }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../lib/processing/csv-parser.ts","../../lib/models/validators.ts","../../lib/utils/csv-headers.ts"],"sourcesContent":["/**\n * CSV Parser Service\n *\n * Handles CSV file parsing with progress tracking, error handling,\n * and validation for TradeBlocks data.\n */\n\nimport type { ParsingError } from '../models/index.ts'\n// import { ProcessingError } from '../models/index.ts'\n\n/**\n * CSV parsing configuration\n */\nexport interface CSVParseConfig {\n delimiter?: string\n quote?: string\n escape?: string\n skipEmptyLines?: boolean\n trimValues?: boolean\n maxRows?: number\n progressCallback?: (progress: number, rowsProcessed: number) => void\n}\n\n/**\n * CSV parsing result\n */\nexport interface CSVParseResult<T = Record<string, string>> {\n data: T[]\n headers: string[]\n totalRows: number\n validRows: number\n errors: ParsingError[]\n warnings: string[]\n}\n\n/**\n * CSV parsing progress info\n */\nexport interface ParseProgress {\n stage: 'reading' | 'parsing' | 'validating' | 'converting' | 'completed'\n progress: number // 0-100\n rowsProcessed: number\n totalRows: number\n errors: number\n}\n\n/**\n * Base CSV parser class with streaming support for large files\n */\nexport class CSVParser {\n private config: Required<CSVParseConfig>\n\n constructor(config: CSVParseConfig = {}) {\n this.config = {\n delimiter: ',',\n quote: '\"',\n escape: '\"',\n skipEmptyLines: true,\n trimValues: true,\n maxRows: 100000, // Safety limit\n progressCallback: () => {},\n ...config,\n }\n }\n\n /**\n * Parse CSV file content\n */\n async parseFile<T = Record<string, string>>(\n fileContent: string,\n validator?: (row: Record<string, string>, rowIndex: number) => T | null\n ): Promise<CSVParseResult<T>> {\n const errors: ParsingError[] = []\n const warnings: string[] = []\n const data: T[] = []\n\n try {\n // Split into lines and handle different line endings\n const lines = fileContent.split(/\\r?\\n/)\n const totalRows = lines.length\n\n if (totalRows === 0) {\n throw new Error('Empty CSV file')\n }\n\n // Parse headers\n const headerLine = lines[0]\n if (!headerLine || headerLine.trim() === '') {\n throw new Error('Missing CSV headers')\n }\n\n const headers = this.parseLine(headerLine)\n if (headers.length === 0) {\n throw new Error('No valid headers found')\n }\n\n // Clean headers (remove BOM, trim whitespace)\n const cleanHeaders = headers.map(header =>\n header.replace(/^\\ufeff/, '').trim()\n )\n\n let validRows = 0\n let processedRows = 0\n\n // Process data rows\n for (let i = 1; i < lines.length && processedRows < this.config.maxRows; i++) {\n const line = lines[i]\n\n // Skip empty lines if configured\n if (this.config.skipEmptyLines && (!line || line.trim() === '')) {\n continue\n }\n\n processedRows++\n\n try {\n const values = this.parseLine(line)\n\n // Create row object\n const row: Record<string, string> = {}\n cleanHeaders.forEach((header, index) => {\n const value = values[index] || ''\n row[header] = this.config.trimValues ? value.trim() : value\n })\n\n // Validate row if validator provided\n if (validator) {\n const validatedRow = validator(row, i)\n if (validatedRow) {\n data.push(validatedRow)\n validRows++\n }\n } else {\n data.push(row as T)\n validRows++\n }\n\n } catch (error) {\n const parsingError: ParsingError = {\n type: 'parsing',\n message: `Error parsing line ${i + 1}: ${error instanceof Error ? error.message : String(error)}`,\n details: { lineNumber: i + 1, line },\n line: i + 1,\n raw: line,\n }\n errors.push(parsingError)\n }\n\n // Report progress\n if (processedRows % 100 === 0 || processedRows === totalRows - 1) {\n const progress = Math.round((processedRows / (totalRows - 1)) * 100)\n this.config.progressCallback(progress, processedRows)\n }\n }\n\n // Check for truncation\n if (processedRows >= this.config.maxRows && lines.length > this.config.maxRows + 1) {\n warnings.push(`File truncated at ${this.config.maxRows} rows for performance`)\n }\n\n return {\n data,\n headers: cleanHeaders,\n totalRows: totalRows - 1, // Excluding header\n validRows,\n errors,\n warnings,\n }\n\n } catch (error) {\n const parsingError: ParsingError = {\n type: 'parsing',\n message: `CSV parsing failed: ${error instanceof Error ? error.message : String(error)}`,\n details: { fileContent: fileContent.substring(0, 500) + '...' },\n line: 0,\n raw: '',\n }\n\n return {\n data: [],\n headers: [],\n totalRows: 0,\n validRows: 0,\n errors: [parsingError],\n warnings,\n }\n }\n }\n\n /**\n * Parse CSV from File object with progress tracking\n */\n async parseFileObject<T = Record<string, string>>(\n file: File,\n validator?: (row: Record<string, string>, rowIndex: number) => T | null,\n progressCallback?: (progress: ParseProgress) => void\n ): Promise<CSVParseResult<T>> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n\n reader.onprogress = (event) => {\n if (event.lengthComputable && progressCallback) {\n const progress = Math.round((event.loaded / event.total) * 100)\n progressCallback({\n stage: 'reading',\n progress,\n rowsProcessed: 0,\n totalRows: 0,\n errors: 0,\n })\n }\n }\n\n reader.onload = async (event) => {\n try {\n const content = event.target?.result as string\n if (!content) {\n throw new Error('Failed to read file content')\n }\n\n // Update progress callback for parsing stage\n const parseConfig = {\n ...this.config,\n progressCallback: (progress: number, rowsProcessed: number) => {\n if (progressCallback) {\n progressCallback({\n stage: 'parsing',\n progress,\n rowsProcessed,\n totalRows: content.split(/\\r?\\n/).length - 1,\n errors: 0,\n })\n }\n },\n }\n\n const parser = new CSVParser(parseConfig)\n const result = await parser.parseFile(content, validator)\n\n if (progressCallback) {\n progressCallback({\n stage: 'completed',\n progress: 100,\n rowsProcessed: result.validRows,\n totalRows: result.totalRows,\n errors: result.errors.length,\n })\n }\n\n resolve(result)\n } catch (error) {\n reject(error)\n }\n }\n\n reader.onerror = () => {\n reject(new Error('Failed to read file'))\n }\n\n reader.readAsText(file)\n })\n }\n\n /**\n * Parse a single CSV line, handling quoted values and escapes\n */\n private parseLine(line: string): string[] {\n const result: string[] = []\n const { delimiter, quote, escape } = this.config\n\n let current = ''\n let inQuotes = false\n let i = 0\n\n while (i < line.length) {\n const char = line[i]\n const nextChar = line[i + 1]\n\n if (!inQuotes) {\n if (char === delimiter) {\n result.push(current)\n current = ''\n } else if (char === quote) {\n inQuotes = true\n } else {\n current += char\n }\n } else {\n if (char === escape && nextChar === quote) {\n // Escaped quote\n current += quote\n i++ // Skip next character\n } else if (char === quote) {\n inQuotes = false\n } else {\n current += char\n }\n }\n\n i++\n }\n\n // Add the last field\n result.push(current)\n\n return result\n }\n\n /**\n * Validate CSV file format before parsing\n */\n static validateCSVFile(file: File): { valid: boolean; error?: string } {\n // Check file type\n const validTypes = ['text/csv', 'application/vnd.ms-excel', 'text/plain']\n if (!validTypes.includes(file.type) && !file.name.toLowerCase().endsWith('.csv')) {\n return { valid: false, error: 'File must be a CSV file (.csv extension)' }\n }\n\n // Check file size (50MB limit)\n const maxSize = 50 * 1024 * 1024\n if (file.size > maxSize) {\n return { valid: false, error: 'File size must be less than 50MB' }\n }\n\n // Check for empty file\n if (file.size === 0) {\n return { valid: false, error: 'File is empty' }\n }\n\n return { valid: true }\n }\n\n /**\n * Detect CSV delimiter from sample content\n */\n static detectDelimiter(sampleContent: string): string {\n const delimiters = [',', ';', '\\t', '|']\n const lines = sampleContent.split(/\\r?\\n/).slice(0, 5) // Check first 5 lines\n\n let bestDelimiter = ','\n let maxScore = 0\n\n for (const delimiter of delimiters) {\n let score = 0\n let consistentCounts = true\n let expectedCount = -1\n\n for (const line of lines) {\n if (!line.trim()) continue\n\n const count = line.split(delimiter).length - 1\n if (expectedCount === -1) {\n expectedCount = count\n } else if (count !== expectedCount) {\n consistentCounts = false\n break\n }\n score += count\n }\n\n if (consistentCounts && score > maxScore) {\n maxScore = score\n bestDelimiter = delimiter\n }\n }\n\n return bestDelimiter\n }\n}","import { z } from 'zod'\n\n/**\n * Zod schema for validating raw trade data from CSV\n */\nexport const rawTradeDataSchema = z.object({\n \"Date Opened\": z.string().min(1, \"Date Opened is required\"),\n \"Time Opened\": z.string().min(1, \"Time Opened is required\"),\n \"Opening Price\": z.string().min(1, \"Opening Price is required\"),\n \"Legs\": z.string().min(1, \"Legs description is required\"),\n \"Premium\": z.string().min(1, \"Premium is required\"),\n \"Closing Price\": z.string().optional(),\n \"Date Closed\": z.string().optional(),\n \"Time Closed\": z.string().optional(),\n \"Avg. Closing Cost\": z.string().optional(),\n \"Reason For Close\": z.string().optional(),\n \"P/L\": z.string().min(1, \"P/L is required\"),\n \"No. of Contracts\": z.string().min(1, \"Number of Contracts is required\"),\n \"Funds at Close\": z.string().min(1, \"Funds at Close is required\"),\n \"Margin Req.\": z.string().min(1, \"Margin Requirement is required\"),\n \"Strategy\": z.string().min(1, \"Strategy is required\"),\n \"Opening Commissions + Fees\": z.string().default(\"0\"),\n \"Closing Commissions + Fees\": z.string().optional(),\n \"Opening Short/Long Ratio\": z.string().default(\"0\"),\n \"Closing Short/Long Ratio\": z.string().optional(),\n \"Opening VIX\": z.string().optional(),\n \"Closing VIX\": z.string().optional(),\n \"Gap\": z.string().optional(),\n \"Movement\": z.string().optional(),\n \"Max Profit\": z.string().optional(),\n \"Max Loss\": z.string().optional(),\n}).passthrough() // Allow custom columns to pass through validation\n\n/**\n * Zod schema for validating processed trade data\n */\nexport const tradeSchema = z.object({\n dateOpened: z.date(),\n timeOpened: z.string().regex(/^\\d{1,2}:\\d{2}:\\d{2}$/, \"Time must be in H:mm:ss or HH:mm:ss format\"),\n openingPrice: z.number().finite(),\n legs: z.string().min(1),\n premium: z.number().finite(),\n premiumPrecision: z.enum(['dollars', 'cents']).optional(),\n closingPrice: z.number().finite().optional(),\n dateClosed: z.date().optional(),\n timeClosed: z.string().regex(/^\\d{1,2}:\\d{2}:\\d{2}$/).optional(),\n avgClosingCost: z.number().finite().optional(),\n reasonForClose: z.string().optional(),\n pl: z.number().finite(),\n numContracts: z.number().int().positive(),\n fundsAtClose: z.number().finite(),\n marginReq: z.number().finite().min(0),\n strategy: z.string().min(1),\n openingCommissionsFees: z.number().finite().min(0),\n closingCommissionsFees: z.number().finite().min(0),\n openingShortLongRatio: z.number().finite().min(0),\n closingShortLongRatio: z.number().finite().min(0).optional(),\n openingVix: z.number().finite().min(0).optional(),\n closingVix: z.number().finite().min(0).optional(),\n gap: z.number().finite().optional(),\n movement: z.number().finite().optional(),\n maxProfit: z.number().finite().optional(),\n maxLoss: z.number().finite().optional(),\n syntheticCapitalRatio: z.number().finite().optional(),\n customFields: z.record(z.string(), z.union([z.number(), z.string()])).optional(),\n})\n\n/**\n * Zod schema for validating raw reporting trade data from strategy logs\n */\nexport const rawReportingTradeDataSchema = z.object({\n \"Strategy\": z.string().min(1, \"Strategy is required\"),\n \"Date Opened\": z.string().min(1, \"Date Opened is required\"),\n \"Time Opened\": z.string().optional(),\n \"Opening Price\": z.string().min(1, \"Opening Price is required\"),\n \"Legs\": z.string().min(1, \"Legs description is required\"),\n \"Initial Premium\": z.string().min(1, \"Initial Premium is required\"),\n \"No. of Contracts\": z.string().min(1, \"Number of Contracts is required\"),\n \"P/L\": z.string().min(1, \"P/L is required\"),\n \"Closing Price\": z.string().optional(),\n \"Date Closed\": z.string().optional(),\n \"Time Closed\": z.string().optional(),\n \"Avg. Closing Cost\": z.string().optional(),\n \"Reason For Close\": z.string().optional(),\n})\n\n/**\n * Zod schema for validating processed reporting trade data\n */\nexport const reportingTradeSchema = z.object({\n strategy: z.string().min(1),\n dateOpened: z.date(),\n timeOpened: z.string().optional(),\n openingPrice: z.number().finite(),\n legs: z.string().min(1),\n initialPremium: z.number().finite(),\n numContracts: z.number().finite(),\n pl: z.number().finite(),\n closingPrice: z.number().finite().optional(),\n dateClosed: z.date().optional(),\n timeClosed: z.string().optional(),\n avgClosingCost: z.number().finite().optional(),\n reasonForClose: z.string().optional(),\n})\n\n/**\n * Zod schema for validating raw daily log data from CSV\n */\nexport const rawDailyLogDataSchema = z.object({\n \"Date\": z.string().min(1, \"Date is required\"),\n \"Net Liquidity\": z.string().min(1, \"Net Liquidity is required\"),\n \"Current Funds\": z.string().min(1, \"Current Funds is required\"),\n \"Withdrawn\": z.string().default(\"0\"),\n \"Trading Funds\": z.string().min(1, \"Trading Funds is required\"),\n \"P/L\": z.string().min(1, \"P/L is required\"),\n \"P/L %\": z.string().min(1, \"P/L % is required\"),\n \"Drawdown %\": z.string().min(1, \"Drawdown % is required\"),\n}).passthrough() // Allow custom columns to pass through validation\n\n/**\n * Zod schema for validating processed daily log entry\n */\nexport const dailyLogEntrySchema = z.object({\n date: z.date(),\n netLiquidity: z.number().finite(),\n currentFunds: z.number().finite(),\n withdrawn: z.number().finite().min(0),\n tradingFunds: z.number().finite().min(0),\n dailyPl: z.number().finite(),\n dailyPlPct: z.number().finite(),\n drawdownPct: z.number().finite().max(0), // Drawdown should be negative or zero\n blockId: z.string().optional(),\n customFields: z.record(z.string(), z.union([z.number(), z.string()])).optional(),\n})\n\n/**\n * Zod schema for portfolio statistics\n */\nexport const portfolioStatsSchema = z.object({\n totalTrades: z.number().int().min(0),\n totalPl: z.number().finite(),\n winRate: z.number().min(0).max(1),\n avgWin: z.number().finite().min(0),\n avgLoss: z.number().finite().max(0),\n maxWin: z.number().finite().min(0),\n maxLoss: z.number().finite().max(0),\n sharpeRatio: z.number().finite().optional(),\n maxDrawdown: z.number().finite().max(0),\n avgDailyPl: z.number().finite(),\n totalCommissions: z.number().finite().min(0),\n netPl: z.number().finite(),\n profitFactor: z.number().finite().min(0),\n})\n\n/**\n * Zod schema for strategy statistics\n */\nexport const strategyStatsSchema = z.object({\n strategyName: z.string().min(1),\n tradeCount: z.number().int().min(0),\n totalPl: z.number().finite(),\n winRate: z.number().min(0).max(1),\n avgWin: z.number().finite().min(0),\n avgLoss: z.number().finite().max(0),\n maxWin: z.number().finite().min(0),\n maxLoss: z.number().finite().max(0),\n avgDte: z.number().finite().min(0).optional(),\n successRate: z.number().min(0).max(1),\n profitFactor: z.number().finite().min(0),\n})\n\n/**\n * Zod schema for analysis configuration\n */\nexport const analysisConfigSchema = z.object({\n useBusinessDaysOnly: z.boolean(),\n annualizationFactor: z.number().int().min(200).max(365),\n confidenceLevel: z.number().min(0.8).max(0.99),\n})\n\n/**\n * Zod schema for file validation\n */\nexport const fileSchema = z.object({\n name: z.string().min(1),\n size: z.number().int().positive(),\n type: z.string().refine(\n (type) => type === 'text/csv' || type === 'application/vnd.ms-excel',\n \"File must be a CSV file\"\n ),\n})\n\n/**\n * Zod schema for block creation request\n */\nexport const createBlockRequestSchema = z.object({\n name: z.string().min(1).max(100),\n description: z.string().max(500).optional(),\n analysisConfig: analysisConfigSchema.partial().optional(),\n})\n\n/**\n * Type exports for use with TypeScript\n */\nexport type RawTradeData = z.infer<typeof rawTradeDataSchema>\nexport type ValidatedTrade = z.infer<typeof tradeSchema>\nexport type RawReportingTradeData = z.infer<typeof rawReportingTradeDataSchema>\nexport type ValidatedReportingTrade = z.infer<typeof reportingTradeSchema>\nexport type RawDailyLogData = z.infer<typeof rawDailyLogDataSchema>\nexport type ValidatedDailyLogEntry = z.infer<typeof dailyLogEntrySchema>\nexport type ValidatedPortfolioStats = z.infer<typeof portfolioStatsSchema>\nexport type ValidatedStrategyStats = z.infer<typeof strategyStatsSchema>\nexport type ValidatedAnalysisConfig = z.infer<typeof analysisConfigSchema>\nexport type ValidatedFile = z.infer<typeof fileSchema>\nexport type ValidatedCreateBlockRequest = z.infer<typeof createBlockRequestSchema>\n","/**\n * CSV header utilities\n */\n\nexport interface HeaderValidationOptions {\n /** Optional map of alternate header names to canonical names */\n aliases?: Record<string, string> | Readonly<Record<string, string>>\n /** Human-readable label used in error messages */\n contextLabel?: string\n}\n\nconst BOM = '\\uFEFF'\n\n/**\n * Remove UTF-8 byte order mark from a string if present\n */\nexport function stripBom(value: string): string {\n return value.startsWith(BOM) ? value.slice(1) : value\n}\n\n/**\n * Parse a single CSV line into values, handling quoted fields and commas\n */\nexport function parseCsvLine(line: string): string[] {\n const result: string[] = []\n let current = ''\n let inQuotes = false\n\n for (let i = 0; i < line.length; i++) {\n const char = line[i]\n\n if (char === '\"') {\n const nextChar = line[i + 1]\n if (inQuotes && nextChar === '\"') {\n // Escaped quote inside quoted value\n current += '\"'\n i++\n } else {\n inQuotes = !inQuotes\n }\n continue\n }\n\n if (char === ',' && !inQuotes) {\n result.push(current.trim())\n current = ''\n } else {\n current += char\n }\n }\n\n result.push(current.trim())\n\n if (result.length > 0) {\n result[0] = stripBom(result[0])\n }\n\n return result\n}\n\n/**\n * Normalize a CSV header by trimming whitespace, stripping BOM, and applying aliases\n */\nexport function normalizeHeader(\n header: string,\n aliases?: Record<string, string> | Readonly<Record<string, string>>\n): string {\n const trimmed = stripBom(header).trim()\n return aliases?.[trimmed] ?? trimmed\n}\n\n/**\n * Normalize an array of headers\n */\nexport function normalizeHeaders(\n headers: string[],\n aliases?: Record<string, string> | Readonly<Record<string, string>>\n): string[] {\n return headers.map(header => normalizeHeader(header, aliases))\n}\n\n/**\n * Validate that required headers are present. Returns the missing headers without throwing.\n */\nexport function findMissingHeaders(\n headers: string[],\n required: readonly string[]\n): string[] {\n const headerSet = new Set(headers)\n return required.filter(requiredHeader => !headerSet.has(requiredHeader))\n}\n\n/**\n * Ensure required headers are present, throwing an Error with a helpful message when missing.\n */\nexport function assertRequiredHeaders(\n headers: string[],\n required: readonly string[],\n options: HeaderValidationOptions = {}\n): void {\n const missing = findMissingHeaders(headers, required)\n if (missing.length === 0) {\n return\n }\n\n const label = options.contextLabel ? `${options.contextLabel} ` : ''\n throw new Error(`Missing required ${label}columns: ${missing.join(', ')}`)\n}\n"],"mappings":"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","names":[]}