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.
- package/README.md +85 -80
- package/dist/{chunk-LDKTV7GW.js → chunk-27S67XW3.js} +24 -52
- package/dist/chunk-27S67XW3.js.map +1 -0
- package/dist/{chunk-FGZH632F.js → chunk-2E63THNI.js} +13 -11
- package/dist/chunk-2E63THNI.js.map +1 -0
- package/dist/{chunk-QTTR7AAW.js → chunk-2I3S2ZLT.js} +325 -84
- package/dist/chunk-2I3S2ZLT.js.map +1 -0
- package/dist/{chunk-4BLCXNQ6.js → chunk-4HZLVUOZ.js} +179 -183
- package/dist/chunk-4HZLVUOZ.js.map +1 -0
- package/dist/{chunk-XXYOUIZY.js → chunk-NWNSKALN.js} +63 -80
- package/dist/chunk-NWNSKALN.js.map +1 -0
- package/dist/{chunk-PRAYH3RT.js → chunk-WNTYA7ER.js} +29 -12
- package/dist/chunk-WNTYA7ER.js.map +1 -0
- package/dist/{chunk-BKQ4PM4Y.js → chunk-YZA4RS76.js} +24 -18
- package/dist/chunk-YZA4RS76.js.map +1 -0
- package/dist/{chunk-W2PP3LEH.js → chunk-ZTJXC3LS.js} +17 -8
- package/dist/chunk-ZTJXC3LS.js.map +1 -0
- package/dist/daily-log-processor-MZW2XBZY.js +9 -0
- package/dist/{daily-logs-store-D3QC2XPV.js → daily-logs-store-3C3OTGPK.js} +2 -2
- package/dist/iv-solver-worker.js +9 -1
- package/dist/market-provider-6U33TQUT.js +16 -0
- package/dist/{proto-3HZTCWK4.js → proto-V23GIZG2.js} +2 -2
- package/dist/{sync-PO4IPCYV.js → sync-3UBC37VW.js} +7 -7
- package/dist/test-exports.js +876 -483
- package/dist/test-exports.js.map +1 -1
- package/dist/trade-processor-DKDCWGKD.js +9 -0
- package/dist/{trades-store-LOL3FQSF.js → trades-store-R3NL25T2.js} +2 -2
- package/package.json +2 -6
- package/server/{chunk-CSDVJPBB.js → chunk-536NSFED.js} +29 -12
- package/server/chunk-536NSFED.js.map +1 -0
- package/server/{chunk-WA5AAPCH.js → chunk-A3UKD64A.js} +17 -8
- package/server/chunk-A3UKD64A.js.map +1 -0
- package/server/{chunk-PNKG7RY7.js → chunk-OMUDNJBJ.js} +63 -80
- package/server/chunk-OMUDNJBJ.js.map +1 -0
- package/server/{chunk-72GKJE2U.js → chunk-RJDJHZ5Y.js} +934 -335
- package/server/chunk-RJDJHZ5Y.js.map +1 -0
- package/server/{chunk-NZO6PT64.js → chunk-RM4B2VKS.js} +167 -177
- package/server/chunk-RM4B2VKS.js.map +1 -0
- package/server/{chunk-5EBXHT6C.js → chunk-SY6GDNVI.js} +24 -18
- package/server/chunk-SY6GDNVI.js.map +1 -0
- package/server/{chunk-FBNDMCT5.js → chunk-T66KH2XH.js} +13 -11
- package/server/chunk-T66KH2XH.js.map +1 -0
- package/server/{chunk-NRFXAJF7.js → chunk-W5E7FHC4.js} +24 -52
- package/server/chunk-W5E7FHC4.js.map +1 -0
- package/server/{config-6IZXEFEX.js → config-DK7KOMNL.js} +1 -1
- package/server/config-DK7KOMNL.js.map +1 -0
- package/server/daily-log-processor-B2VPU2FQ.js +10 -0
- package/server/{daily-logs-store-NU7M4L5C.js → daily-logs-store-YFNXTB7J.js} +2 -2
- package/server/http-server.js +2 -5
- package/server/index.js +2497 -2029
- package/server/index.js.map +1 -1
- package/server/iv-solver-worker.js +9 -1
- package/server/market-provider-L56RFHAC.js +17 -0
- package/server/{proto-DWRZJO4E.js → proto-YZ4TLX2N.js} +2 -2
- package/server/{sync-QFI5L7S7.js → sync-CENKDN53.js} +7 -7
- package/server/trade-processor-3PI4LHZI.js +10 -0
- package/server/{trades-store-VY26MWER.js → trades-store-RTTEYMXH.js} +2 -2
- package/src/auth/clients-store.ts +4 -4
- package/src/auth/code-store.ts +1 -1
- package/src/auth/config.ts +11 -12
- package/src/auth/login-page.ts +8 -10
- package/src/auth/provider.ts +35 -30
- package/src/auth/token.ts +17 -15
- package/src/db/backtest-schemas.ts +38 -8
- package/src/db/connection.ts +107 -40
- package/src/db/data-root.ts +22 -0
- package/src/db/index.ts +37 -5
- package/src/db/json-adapters.ts +22 -31
- package/src/db/json-migration.ts +11 -15
- package/src/db/json-store.ts +5 -3
- package/src/db/market-datasets.ts +48 -15
- package/src/db/market-schemas.ts +11 -5
- package/src/db/market-views.ts +119 -32
- package/src/db/parquet-writer.ts +7 -7
- package/src/db/profile-schemas.ts +39 -22
- package/src/db/schemas.ts +2 -2
- package/src/http-server.ts +7 -12
- package/src/index.ts +8 -9
- package/src/market/ingestor/index.ts +1 -4
- package/src/market/ingestor/market-ingestor.ts +140 -67
- package/src/market/ingestor/types.ts +1 -3
- package/src/market/stores/chain-sql.ts +2 -8
- package/src/market/stores/chain-store.ts +1 -4
- package/src/market/stores/duckdb-chain-store.ts +3 -14
- package/src/market/stores/duckdb-enriched-store.ts +3 -13
- package/src/market/stores/duckdb-quote-store.ts +10 -27
- package/src/market/stores/duckdb-spot-store.ts +4 -20
- package/src/market/stores/enriched-sql.ts +3 -9
- package/src/market/stores/enriched-store.ts +2 -2
- package/src/market/stores/parquet-chain-store.ts +5 -22
- package/src/market/stores/parquet-enriched-store.ts +4 -16
- package/src/market/stores/parquet-oi-daily-store.ts +3 -14
- package/src/market/stores/parquet-quote-store.ts +9 -29
- package/src/market/stores/parquet-spot-store.ts +14 -33
- package/src/market/stores/quote-store.ts +2 -10
- package/src/market/stores/spot-sql.ts +3 -15
- package/src/market/stores/spot-store.ts +1 -1
- package/src/market/tickers/defaults.json +6 -6
- package/src/market/tickers/loader.ts +2 -7
- package/src/market/tickers/registry.ts +5 -15
- package/src/market/tickers/schemas.ts +2 -6
- package/src/models/strategy-profile.ts +39 -39
- package/src/sync/block-sync.ts +44 -65
- package/src/sync/index.ts +1 -4
- package/src/sync/metadata.ts +14 -20
- package/src/test-exports.ts +139 -123
- package/src/tools/analysis.ts +180 -159
- package/src/tools/batch-exit-analysis.ts +100 -59
- package/src/tools/blocks/analysis.ts +116 -101
- package/src/tools/blocks/comparison.ts +281 -364
- package/src/tools/blocks/core.ts +208 -253
- package/src/tools/blocks/health.ts +571 -563
- package/src/tools/blocks/index.ts +2 -0
- package/src/tools/blocks/paired-comparison.ts +425 -0
- package/src/tools/blocks/similarity.ts +316 -283
- package/src/tools/edge-decay.ts +124 -197
- package/src/tools/exit-analysis.ts +130 -77
- package/src/tools/greeks-attribution.ts +84 -35
- package/src/tools/guides.ts +4 -6
- package/src/tools/imports.ts +11 -14
- package/src/tools/market-data.ts +1067 -757
- package/src/tools/market-enrichment.ts +3 -3
- package/src/tools/market-fetch.ts +148 -67
- package/src/tools/market-imports.ts +12 -12
- package/src/tools/middleware/sync-middleware.ts +5 -6
- package/src/tools/performance.ts +185 -302
- package/src/tools/profile-analysis.ts +52 -66
- package/src/tools/profiles.ts +106 -69
- package/src/tools/regime-advisor.ts +20 -45
- package/src/tools/replay.ts +81 -77
- package/src/tools/reports/discrepancies.ts +298 -328
- package/src/tools/reports/fields.ts +7 -25
- package/src/tools/reports/helpers.ts +18 -49
- package/src/tools/reports/predictive.ts +27 -70
- package/src/tools/reports/slippage-trends.ts +315 -345
- package/src/tools/reports/slippage.ts +1 -4
- package/src/tools/reports/strategy-matches.ts +399 -441
- package/src/tools/schema.ts +43 -40
- package/src/tools/shared/filters.ts +3 -9
- package/src/tools/snapshot.ts +9 -30
- package/src/tools/sql.ts +15 -14
- package/src/tools/tickers.ts +1 -4
- package/src/utils/batch-exit-analysis.ts +31 -42
- package/src/utils/black-scholes.ts +39 -29
- package/src/utils/block-loader.ts +69 -83
- package/src/utils/calibration-probe.ts +3 -4
- package/src/utils/chain-loader.ts +3 -3
- package/src/utils/csv-discovery.ts +16 -22
- package/src/utils/data-quality.ts +24 -36
- package/src/utils/exit-triggers.ts +91 -96
- package/src/utils/field-timing.ts +94 -79
- package/src/utils/filter-predicates.ts +13 -9
- package/src/utils/flatfile-importer.ts +94 -64
- package/src/utils/greeks-decomposition.ts +152 -100
- package/src/utils/iv-solver-pool.ts +55 -25
- package/src/utils/iv-solver-worker.ts +5 -5
- package/src/utils/market-enricher.ts +528 -497
- package/src/utils/market-importer.ts +31 -12
- package/src/utils/market-provider.ts +21 -23
- package/src/utils/massive-tier.ts +5 -7
- package/src/utils/migrate-option-data-helpers.ts +2 -8
- package/src/utils/option-quote-greeks.ts +25 -31
- package/src/utils/option-time.ts +4 -8
- package/src/utils/output-formatter.ts +1 -4
- package/src/utils/provider-capabilities.ts +1 -4
- package/src/utils/providers/massive.ts +59 -93
- package/src/utils/providers/thetadata/backfill.ts +14 -23
- package/src/utils/providers/thetadata/client.ts +12 -8
- package/src/utils/providers/thetadata/decode.ts +2 -20
- package/src/utils/providers/thetadata/endpoints.ts +32 -40
- package/src/utils/providers/thetadata/join.ts +11 -10
- package/src/utils/providers/thetadata/proto.ts +12 -10
- package/src/utils/providers/thetadata/quote-mid-greeks.ts +5 -5
- package/src/utils/providers/thetadata.ts +11 -10
- package/src/utils/quote-enricher.ts +4 -4
- package/src/utils/quote-parquet-projection.ts +3 -11
- package/src/utils/sample-date-selector.ts +3 -5
- package/src/utils/schema-metadata.ts +102 -70
- package/src/utils/ticker.ts +5 -9
- package/src/utils/trade-replay.ts +77 -68
- package/dist/chunk-4BLCXNQ6.js.map +0 -1
- package/dist/chunk-BKQ4PM4Y.js.map +0 -1
- package/dist/chunk-FGZH632F.js.map +0 -1
- package/dist/chunk-LDKTV7GW.js.map +0 -1
- package/dist/chunk-PRAYH3RT.js.map +0 -1
- package/dist/chunk-QTTR7AAW.js.map +0 -1
- package/dist/chunk-W2PP3LEH.js.map +0 -1
- package/dist/chunk-XXYOUIZY.js.map +0 -1
- package/dist/daily-log-processor-6MWJ23JK.js +0 -9
- package/dist/market-provider-VDRJUEF2.js +0 -16
- package/dist/trade-processor-NHU4VWRX.js +0 -9
- package/manifest.json +0 -141
- package/server/chunk-5EBXHT6C.js.map +0 -1
- package/server/chunk-72GKJE2U.js.map +0 -1
- package/server/chunk-CSDVJPBB.js.map +0 -1
- package/server/chunk-FBNDMCT5.js.map +0 -1
- package/server/chunk-NRFXAJF7.js.map +0 -1
- package/server/chunk-NZO6PT64.js.map +0 -1
- package/server/chunk-PNKG7RY7.js.map +0 -1
- package/server/chunk-WA5AAPCH.js.map +0 -1
- package/server/config-6IZXEFEX.js.map +0 -1
- package/server/daily-log-processor-Y3PVSVBM.js +0 -10
- package/server/market-provider-VOYYVYWT.js +0 -17
- package/server/trade-processor-JWVS37KM.js +0 -10
- /package/dist/{daily-log-processor-6MWJ23JK.js.map → daily-log-processor-MZW2XBZY.js.map} +0 -0
- /package/dist/{daily-logs-store-D3QC2XPV.js.map → daily-logs-store-3C3OTGPK.js.map} +0 -0
- /package/dist/{market-provider-VDRJUEF2.js.map → market-provider-6U33TQUT.js.map} +0 -0
- /package/dist/{proto-3HZTCWK4.js.map → proto-V23GIZG2.js.map} +0 -0
- /package/dist/{sync-PO4IPCYV.js.map → sync-3UBC37VW.js.map} +0 -0
- /package/dist/{trade-processor-NHU4VWRX.js.map → trade-processor-DKDCWGKD.js.map} +0 -0
- /package/dist/{trades-store-LOL3FQSF.js.map → trades-store-R3NL25T2.js.map} +0 -0
- /package/server/{daily-log-processor-Y3PVSVBM.js.map → daily-log-processor-B2VPU2FQ.js.map} +0 -0
- /package/server/{daily-logs-store-NU7M4L5C.js.map → daily-logs-store-YFNXTB7J.js.map} +0 -0
- /package/server/{market-provider-VOYYVYWT.js.map → market-provider-L56RFHAC.js.map} +0 -0
- /package/server/{proto-DWRZJO4E.js.map → proto-YZ4TLX2N.js.map} +0 -0
- /package/server/{sync-QFI5L7S7.js.map → sync-CENKDN53.js.map} +0 -0
- /package/server/{trade-processor-JWVS37KM.js.map → trade-processor-3PI4LHZI.js.map} +0 -0
- /package/server/{trades-store-VY26MWER.js.map → trades-store-RTTEYMXH.js.map} +0 -0
|
@@ -19791,8 +19791,10 @@ var PortfolioStatsCalculator = class _PortfolioStatsCalculator {
|
|
|
19791
19791
|
if (!trade.dateOpened) return false;
|
|
19792
19792
|
const date = new Date(trade.dateOpened);
|
|
19793
19793
|
if (isNaN(date.getTime())) return false;
|
|
19794
|
-
if (typeof trade.openingCommissionsFees !== "number" || isNaN(trade.openingCommissionsFees))
|
|
19795
|
-
|
|
19794
|
+
if (typeof trade.openingCommissionsFees !== "number" || isNaN(trade.openingCommissionsFees))
|
|
19795
|
+
return false;
|
|
19796
|
+
if (typeof trade.closingCommissionsFees !== "number" || isNaN(trade.closingCommissionsFees))
|
|
19797
|
+
return false;
|
|
19796
19798
|
return true;
|
|
19797
19799
|
} catch {
|
|
19798
19800
|
return false;
|
|
@@ -19831,7 +19833,10 @@ var PortfolioStatsCalculator = class _PortfolioStatsCalculator {
|
|
|
19831
19833
|
const streaks = this.calculateStreaks(validTrades);
|
|
19832
19834
|
const timeInDrawdown = this.calculateTimeInDrawdown(validTrades, adjustedDailyLogs);
|
|
19833
19835
|
const periodicWinRates = this.calculatePeriodicWinRates(validTrades);
|
|
19834
|
-
const initialCapital = _PortfolioStatsCalculator.calculateInitialCapital(
|
|
19836
|
+
const initialCapital = _PortfolioStatsCalculator.calculateInitialCapital(
|
|
19837
|
+
validTrades,
|
|
19838
|
+
adjustedDailyLogs
|
|
19839
|
+
);
|
|
19835
19840
|
return {
|
|
19836
19841
|
totalTrades,
|
|
19837
19842
|
totalPl,
|
|
@@ -19869,14 +19874,17 @@ var PortfolioStatsCalculator = class _PortfolioStatsCalculator {
|
|
|
19869
19874
|
if (trades.length === 0) {
|
|
19870
19875
|
return {};
|
|
19871
19876
|
}
|
|
19872
|
-
const tradesByStrategy = trades.reduce(
|
|
19873
|
-
|
|
19874
|
-
|
|
19875
|
-
acc[strategy]
|
|
19876
|
-
|
|
19877
|
-
|
|
19878
|
-
|
|
19879
|
-
|
|
19877
|
+
const tradesByStrategy = trades.reduce(
|
|
19878
|
+
(acc, trade) => {
|
|
19879
|
+
const strategy = trade.strategy || "Unknown";
|
|
19880
|
+
if (!acc[strategy]) {
|
|
19881
|
+
acc[strategy] = [];
|
|
19882
|
+
}
|
|
19883
|
+
acc[strategy].push(trade);
|
|
19884
|
+
return acc;
|
|
19885
|
+
},
|
|
19886
|
+
{}
|
|
19887
|
+
);
|
|
19880
19888
|
const strategyStats = {};
|
|
19881
19889
|
Object.entries(tradesByStrategy).forEach(([strategyName, strategyTrades]) => {
|
|
19882
19890
|
const portfolioStats = this.calculatePortfolioStats(strategyTrades);
|
|
@@ -19911,7 +19919,9 @@ var PortfolioStatsCalculator = class _PortfolioStatsCalculator {
|
|
|
19911
19919
|
return maxDrawdown2;
|
|
19912
19920
|
}
|
|
19913
19921
|
if (trades.length === 0) return 0;
|
|
19914
|
-
const closedTrades = trades.filter(
|
|
19922
|
+
const closedTrades = trades.filter(
|
|
19923
|
+
(trade) => trade.dateClosed && trade.fundsAtClose !== void 0
|
|
19924
|
+
);
|
|
19915
19925
|
if (closedTrades.length === 0) return 0;
|
|
19916
19926
|
const sortedTrades = [...closedTrades].sort((a, b) => {
|
|
19917
19927
|
try {
|
|
@@ -20012,9 +20022,7 @@ var PortfolioStatsCalculator = class _PortfolioStatsCalculator {
|
|
|
20012
20022
|
* Calculate average days to expiration (DTE)
|
|
20013
20023
|
*/
|
|
20014
20024
|
calculateAvgDTE(trades) {
|
|
20015
|
-
const tradesWithDTE = trades.filter(
|
|
20016
|
-
(trade) => trade.dateClosed && trade.dateOpened
|
|
20017
|
-
);
|
|
20025
|
+
const tradesWithDTE = trades.filter((trade) => trade.dateClosed && trade.dateOpened);
|
|
20018
20026
|
if (tradesWithDTE.length === 0) return void 0;
|
|
20019
20027
|
const totalDTE = tradesWithDTE.reduce((sum2, trade) => {
|
|
20020
20028
|
const openDate = new Date(trade.dateOpened);
|
|
@@ -20035,7 +20043,9 @@ var PortfolioStatsCalculator = class _PortfolioStatsCalculator {
|
|
|
20035
20043
|
return a.timeOpened.localeCompare(b.timeOpened);
|
|
20036
20044
|
});
|
|
20037
20045
|
const startDate = new Date(sortedTrades[0].dateOpened);
|
|
20038
|
-
const endDate = new Date(
|
|
20046
|
+
const endDate = new Date(
|
|
20047
|
+
sortedTrades[sortedTrades.length - 1].dateClosed || sortedTrades[sortedTrades.length - 1].dateOpened
|
|
20048
|
+
);
|
|
20039
20049
|
const totalYears = (endDate.getTime() - startDate.getTime()) / (1e3 * 60 * 60 * 24 * 365.25);
|
|
20040
20050
|
if (totalYears <= 0) return void 0;
|
|
20041
20051
|
const initialCapital = _PortfolioStatsCalculator.calculateInitialCapital(trades);
|
|
@@ -20102,7 +20112,9 @@ var PortfolioStatsCalculator = class _PortfolioStatsCalculator {
|
|
|
20102
20112
|
if (winningTrades.length === 0 || losingTrades.length === 0) return void 0;
|
|
20103
20113
|
const winRate = winningTrades.length / trades.length;
|
|
20104
20114
|
const avgWin = winningTrades.reduce((sum2, trade) => sum2 + trade.pl, 0) / winningTrades.length;
|
|
20105
|
-
const avgLoss = Math.abs(
|
|
20115
|
+
const avgLoss = Math.abs(
|
|
20116
|
+
losingTrades.reduce((sum2, trade) => sum2 + trade.pl, 0) / losingTrades.length
|
|
20117
|
+
);
|
|
20106
20118
|
if (avgLoss === 0) return void 0;
|
|
20107
20119
|
const winLossRatio = avgWin / avgLoss;
|
|
20108
20120
|
const kellyPercentage = (winRate * winLossRatio - (1 - winRate)) / winLossRatio;
|
|
@@ -20148,7 +20160,9 @@ var PortfolioStatsCalculator = class _PortfolioStatsCalculator {
|
|
|
20148
20160
|
return daysInDrawdown / dailyLogEntries.length * 100;
|
|
20149
20161
|
}
|
|
20150
20162
|
if (trades.length === 0) return void 0;
|
|
20151
|
-
const closedTrades = trades.filter(
|
|
20163
|
+
const closedTrades = trades.filter(
|
|
20164
|
+
(trade) => trade.dateClosed && trade.fundsAtClose !== void 0
|
|
20165
|
+
);
|
|
20152
20166
|
if (closedTrades.length === 0) return void 0;
|
|
20153
20167
|
const sortedTrades = [...closedTrades].sort((a, b) => {
|
|
20154
20168
|
try {
|
|
@@ -20197,7 +20211,9 @@ var PortfolioStatsCalculator = class _PortfolioStatsCalculator {
|
|
|
20197
20211
|
}
|
|
20198
20212
|
monthlyTrades.get(monthKey).push(trade);
|
|
20199
20213
|
const startOfYear = new Date(date.getFullYear(), 0, 1);
|
|
20200
|
-
const weekNumber = Math.ceil(
|
|
20214
|
+
const weekNumber = Math.ceil(
|
|
20215
|
+
((date.getTime() - startOfYear.getTime()) / 864e5 + startOfYear.getDay() + 1) / 7
|
|
20216
|
+
);
|
|
20201
20217
|
const weekKey = `${date.getFullYear()}-${String(weekNumber).padStart(2, "0")}`;
|
|
20202
20218
|
if (!weeklyTrades.has(weekKey)) {
|
|
20203
20219
|
weeklyTrades.set(weekKey, []);
|
|
@@ -20377,12 +20393,7 @@ function normalQuantile(p) {
|
|
|
20377
20393
|
4.374664141464968,
|
|
20378
20394
|
2.938163982698783
|
|
20379
20395
|
];
|
|
20380
|
-
const d = [
|
|
20381
|
-
0.007784695709041462,
|
|
20382
|
-
0.3224671290700398,
|
|
20383
|
-
2.445134137142996,
|
|
20384
|
-
3.754408661907416
|
|
20385
|
-
];
|
|
20396
|
+
const d = [0.007784695709041462, 0.3224671290700398, 2.445134137142996, 3.754408661907416];
|
|
20386
20397
|
const pLow = 0.02425;
|
|
20387
20398
|
const pHigh = 1 - pLow;
|
|
20388
20399
|
let q;
|
|
@@ -20510,10 +20521,7 @@ function calculateCorrelationMatrix(trades, options = {}) {
|
|
|
20510
20521
|
}
|
|
20511
20522
|
const strategyReturns = {};
|
|
20512
20523
|
for (const strategy of Object.keys(strategyDailyReturns)) {
|
|
20513
|
-
strategyReturns[strategy] = aggregateByPeriod(
|
|
20514
|
-
strategyDailyReturns[strategy],
|
|
20515
|
-
timePeriod
|
|
20516
|
-
);
|
|
20524
|
+
strategyReturns[strategy] = aggregateByPeriod(strategyDailyReturns[strategy], timePeriod);
|
|
20517
20525
|
}
|
|
20518
20526
|
const allDates = /* @__PURE__ */ new Set();
|
|
20519
20527
|
for (const returns of Object.values(strategyReturns)) {
|
|
@@ -20648,9 +20656,7 @@ function normalizeReturn(trade, mode) {
|
|
|
20648
20656
|
return trade.pl / trade.marginReq;
|
|
20649
20657
|
}
|
|
20650
20658
|
case "notional": {
|
|
20651
|
-
const notional = Math.abs(
|
|
20652
|
-
(trade.openingPrice || 0) * (trade.numContracts || 0)
|
|
20653
|
-
);
|
|
20659
|
+
const notional = Math.abs((trade.openingPrice || 0) * (trade.numContracts || 0));
|
|
20654
20660
|
if (!notional) {
|
|
20655
20661
|
return null;
|
|
20656
20662
|
}
|
|
@@ -20663,9 +20669,7 @@ function normalizeReturn(trade, mode) {
|
|
|
20663
20669
|
function getTradeDateKey(trade, basis) {
|
|
20664
20670
|
const date = basis === "closed" ? trade.dateClosed : trade.dateOpened;
|
|
20665
20671
|
if (!date) {
|
|
20666
|
-
throw new Error(
|
|
20667
|
-
"Trade is missing required date information for correlation calculation"
|
|
20668
|
-
);
|
|
20672
|
+
throw new Error("Trade is missing required date information for correlation calculation");
|
|
20669
20673
|
}
|
|
20670
20674
|
const year = date.getFullYear();
|
|
20671
20675
|
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
@@ -20682,9 +20686,7 @@ function getIsoWeekKey(dateStr) {
|
|
|
20682
20686
|
const dayOfWeek = thursday.getUTCDay() || 7;
|
|
20683
20687
|
thursday.setUTCDate(thursday.getUTCDate() + (4 - dayOfWeek));
|
|
20684
20688
|
const yearStart = new Date(Date.UTC(thursday.getUTCFullYear(), 0, 1));
|
|
20685
|
-
const weekNum = Math.ceil(
|
|
20686
|
-
((thursday.getTime() - yearStart.getTime()) / 864e5 + 1) / 7
|
|
20687
|
-
);
|
|
20689
|
+
const weekNum = Math.ceil(((thursday.getTime() - yearStart.getTime()) / 864e5 + 1) / 7);
|
|
20688
20690
|
return `${thursday.getUTCFullYear()}-W${String(weekNum).padStart(2, "0")}`;
|
|
20689
20691
|
}
|
|
20690
20692
|
function getMonthKey(dateStr) {
|
|
@@ -20734,9 +20736,7 @@ function performTailRiskAnalysis(trades, options = {}) {
|
|
|
20734
20736
|
}
|
|
20735
20737
|
if (strategyFilter && strategyFilter.length > 0) {
|
|
20736
20738
|
const filterSet = new Set(strategyFilter);
|
|
20737
|
-
filteredTrades = filteredTrades.filter(
|
|
20738
|
-
(t) => t.strategy && filterSet.has(t.strategy)
|
|
20739
|
-
);
|
|
20739
|
+
filteredTrades = filteredTrades.filter((t) => t.strategy && filterSet.has(t.strategy));
|
|
20740
20740
|
}
|
|
20741
20741
|
if (dateRange?.from || dateRange?.to) {
|
|
20742
20742
|
filteredTrades = filteredTrades.filter((t) => {
|
|
@@ -20751,41 +20751,27 @@ function performTailRiskAnalysis(trades, options = {}) {
|
|
|
20751
20751
|
return true;
|
|
20752
20752
|
});
|
|
20753
20753
|
}
|
|
20754
|
-
const aligned = aggregateAndAlignReturns(
|
|
20755
|
-
filteredTrades,
|
|
20756
|
-
normalization,
|
|
20757
|
-
dateBasis
|
|
20758
|
-
);
|
|
20754
|
+
const aligned = aggregateAndAlignReturns(filteredTrades, normalization, dateBasis);
|
|
20759
20755
|
if (aligned.strategies.length < 2) {
|
|
20760
|
-
return createEmptyResult(
|
|
20761
|
-
aligned,
|
|
20762
|
-
tailThreshold,
|
|
20763
|
-
varianceThreshold,
|
|
20764
|
-
startTime
|
|
20765
|
-
);
|
|
20756
|
+
return createEmptyResult(aligned, tailThreshold, varianceThreshold, startTime);
|
|
20766
20757
|
}
|
|
20767
20758
|
if (aligned.dates.length < minTradingDays) {
|
|
20768
|
-
return createEmptyResult(
|
|
20769
|
-
aligned,
|
|
20770
|
-
tailThreshold,
|
|
20771
|
-
varianceThreshold,
|
|
20772
|
-
startTime
|
|
20773
|
-
);
|
|
20759
|
+
return createEmptyResult(aligned, tailThreshold, varianceThreshold, startTime);
|
|
20774
20760
|
}
|
|
20775
20761
|
const transformedReturns = aligned.returns.map(
|
|
20776
20762
|
(strategyReturns) => probabilityIntegralTransform(strategyReturns)
|
|
20777
20763
|
);
|
|
20778
20764
|
const copulaCorrelationMatrix = computeCorrelationMatrix(transformedReturns);
|
|
20779
|
-
const { eigenvalues, eigenvectors, explainedVariance, effectiveFactors } = performEigenAnalysis(
|
|
20765
|
+
const { eigenvalues, eigenvectors, explainedVariance, effectiveFactors } = performEigenAnalysis(
|
|
20766
|
+
copulaCorrelationMatrix,
|
|
20767
|
+
varianceThreshold
|
|
20768
|
+
);
|
|
20780
20769
|
const jointTailRiskResult = estimateJointTailRisk(
|
|
20781
20770
|
transformedReturns,
|
|
20782
20771
|
aligned.tradedMask,
|
|
20783
20772
|
tailThreshold
|
|
20784
20773
|
);
|
|
20785
|
-
const analytics = calculateTailRiskAnalytics(
|
|
20786
|
-
jointTailRiskResult.matrix,
|
|
20787
|
-
aligned.strategies
|
|
20788
|
-
);
|
|
20774
|
+
const analytics = calculateTailRiskAnalytics(jointTailRiskResult.matrix, aligned.strategies);
|
|
20789
20775
|
const marginalContributions = calculateMarginalContributions(
|
|
20790
20776
|
copulaCorrelationMatrix,
|
|
20791
20777
|
jointTailRiskResult.matrix,
|
|
@@ -20882,9 +20868,7 @@ function normalizeReturn2(trade, mode) {
|
|
|
20882
20868
|
break;
|
|
20883
20869
|
}
|
|
20884
20870
|
case "notional": {
|
|
20885
|
-
const notional = Math.abs(
|
|
20886
|
-
(trade.openingPrice || 0) * (trade.numContracts || 0)
|
|
20887
|
-
);
|
|
20871
|
+
const notional = Math.abs((trade.openingPrice || 0) * (trade.numContracts || 0));
|
|
20888
20872
|
if (!notional || notional === 0) {
|
|
20889
20873
|
return null;
|
|
20890
20874
|
}
|
|
@@ -20968,10 +20952,7 @@ function performEigenAnalysis(correlationMatrix, varianceThreshold = 0.8) {
|
|
|
20968
20952
|
effectiveFactors
|
|
20969
20953
|
};
|
|
20970
20954
|
} catch (error) {
|
|
20971
|
-
console.warn(
|
|
20972
|
-
"Eigenvalue decomposition failed, using identity fallback:",
|
|
20973
|
-
error
|
|
20974
|
-
);
|
|
20955
|
+
console.warn("Eigenvalue decomposition failed, using identity fallback:", error);
|
|
20975
20956
|
return {
|
|
20976
20957
|
eigenvalues: new Array(n).fill(1),
|
|
20977
20958
|
eigenvectors: correlationMatrix.map(
|
|
@@ -21030,10 +21011,7 @@ function estimateJointTailRisk(transformedReturns, tradedMask, tailThreshold) {
|
|
|
21030
21011
|
}
|
|
21031
21012
|
}
|
|
21032
21013
|
}
|
|
21033
|
-
const minTailObs = getMinTailObservations(
|
|
21034
|
-
tailThreshold,
|
|
21035
|
-
sharedTradingDays
|
|
21036
|
-
);
|
|
21014
|
+
const minTailObs = getMinTailObservations(tailThreshold, sharedTradingDays);
|
|
21037
21015
|
if (iInTailAndBothTraded < minTailObs) {
|
|
21038
21016
|
row.push(NaN);
|
|
21039
21017
|
insufficientPairs++;
|
|
@@ -21104,10 +21082,7 @@ function calculateMarginalContributions(_copulaCorrelationMatrix, jointTailRiskM
|
|
|
21104
21082
|
}
|
|
21105
21083
|
const contributions = [];
|
|
21106
21084
|
const firstEigenvector = eigenvectors[0] || new Array(n).fill(0);
|
|
21107
|
-
const sumAbsLoadings = firstEigenvector.reduce(
|
|
21108
|
-
(sum2, val) => sum2 + Math.abs(val),
|
|
21109
|
-
0
|
|
21110
|
-
);
|
|
21085
|
+
const sumAbsLoadings = firstEigenvector.reduce((sum2, val) => sum2 + Math.abs(val), 0);
|
|
21111
21086
|
for (let i = 0; i < n; i++) {
|
|
21112
21087
|
const concentrationScore = sumAbsLoadings > 0 ? Math.abs(firstEigenvector[i]) / sumAbsLoadings : 1 / n;
|
|
21113
21088
|
let sumJointRisk = 0;
|
|
@@ -21303,7 +21278,9 @@ var PerformanceCalculator = class {
|
|
|
21303
21278
|
static calculateMonthlyReturns(trades, initialCapital) {
|
|
21304
21279
|
if (trades.length === 0) return {};
|
|
21305
21280
|
if (!initialCapital) {
|
|
21306
|
-
const firstTrade = trades.sort(
|
|
21281
|
+
const firstTrade = trades.sort(
|
|
21282
|
+
(a, b) => new Date(a.dateOpened).getTime() - new Date(b.dateOpened).getTime()
|
|
21283
|
+
)[0];
|
|
21307
21284
|
initialCapital = firstTrade.fundsAtClose - firstTrade.pl;
|
|
21308
21285
|
}
|
|
21309
21286
|
const monthlyPl = this.aggregatePLByPeriod(trades, "monthly");
|
|
@@ -21439,6 +21416,262 @@ var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
|
21439
21416
|
// ../lib/calculations/walk-forward-degradation.ts
|
|
21440
21417
|
var DAY_MS2 = 24 * 60 * 60 * 1e3;
|
|
21441
21418
|
|
|
21419
|
+
// ../lib/calculations/paired-block-bootstrap.ts
|
|
21420
|
+
function mulberry32(seed) {
|
|
21421
|
+
let state = seed >>> 0;
|
|
21422
|
+
return function() {
|
|
21423
|
+
state = state + 1831565813 >>> 0;
|
|
21424
|
+
let t = state;
|
|
21425
|
+
t = Math.imul(t ^ t >>> 15, t | 1);
|
|
21426
|
+
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
|
21427
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
21428
|
+
};
|
|
21429
|
+
}
|
|
21430
|
+
function deriveSeed(seed, blockDays) {
|
|
21431
|
+
return seed + Math.imul(blockDays, 2654435761) >>> 0;
|
|
21432
|
+
}
|
|
21433
|
+
function percentileOf(sorted, p) {
|
|
21434
|
+
const n = sorted.length;
|
|
21435
|
+
if (n === 1) return sorted[0];
|
|
21436
|
+
const rank = p * (n - 1);
|
|
21437
|
+
const lo = Math.floor(rank);
|
|
21438
|
+
const hi = Math.ceil(rank);
|
|
21439
|
+
if (lo === hi) return sorted[lo];
|
|
21440
|
+
const weight = rank - lo;
|
|
21441
|
+
return sorted[lo] * (1 - weight) + sorted[hi] * weight;
|
|
21442
|
+
}
|
|
21443
|
+
function observedValueMap(arm) {
|
|
21444
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
21445
|
+
for (let i = 0; i < arm.index.length; i++) {
|
|
21446
|
+
if (arm.observedMask[i]) {
|
|
21447
|
+
map2.set(arm.index[i], arm.values[i]);
|
|
21448
|
+
}
|
|
21449
|
+
}
|
|
21450
|
+
return map2;
|
|
21451
|
+
}
|
|
21452
|
+
function isConstantArm(arm) {
|
|
21453
|
+
return arm !== void 0 && "constant" in arm;
|
|
21454
|
+
}
|
|
21455
|
+
function unionDays(a, b) {
|
|
21456
|
+
const seen = /* @__PURE__ */ new Set();
|
|
21457
|
+
for (const d of a) seen.add(d);
|
|
21458
|
+
for (const d of b) seen.add(d);
|
|
21459
|
+
return Array.from(seen).sort();
|
|
21460
|
+
}
|
|
21461
|
+
function buildOverlap(ambient, isObserved, deltaOf) {
|
|
21462
|
+
const days = [];
|
|
21463
|
+
const delta = [];
|
|
21464
|
+
const runs = [];
|
|
21465
|
+
let runStart = -1;
|
|
21466
|
+
for (const day of ambient) {
|
|
21467
|
+
if (isObserved(day)) {
|
|
21468
|
+
if (runStart === -1) runStart = days.length;
|
|
21469
|
+
days.push(day);
|
|
21470
|
+
delta.push(deltaOf(day));
|
|
21471
|
+
} else if (runStart !== -1) {
|
|
21472
|
+
runs.push({ start: runStart, length: days.length - runStart });
|
|
21473
|
+
runStart = -1;
|
|
21474
|
+
}
|
|
21475
|
+
}
|
|
21476
|
+
if (runStart !== -1) {
|
|
21477
|
+
runs.push({ start: runStart, length: days.length - runStart });
|
|
21478
|
+
}
|
|
21479
|
+
return { days, delta, runs };
|
|
21480
|
+
}
|
|
21481
|
+
function buildComparisonOverlap(armA, armB) {
|
|
21482
|
+
const mapA = observedValueMap(armA);
|
|
21483
|
+
if (armB === void 0 || isConstantArm(armB)) {
|
|
21484
|
+
const c = armB === void 0 ? 0 : armB.constant;
|
|
21485
|
+
return buildOverlap(
|
|
21486
|
+
armA.index,
|
|
21487
|
+
(day) => mapA.has(day),
|
|
21488
|
+
(day) => mapA.get(day) - c
|
|
21489
|
+
);
|
|
21490
|
+
}
|
|
21491
|
+
const mapB = observedValueMap(armB);
|
|
21492
|
+
const ambient = unionDays(armA.index, armB.index);
|
|
21493
|
+
return buildOverlap(
|
|
21494
|
+
ambient,
|
|
21495
|
+
(day) => mapA.has(day) && mapB.has(day),
|
|
21496
|
+
(day) => mapA.get(day) - mapB.get(day)
|
|
21497
|
+
);
|
|
21498
|
+
}
|
|
21499
|
+
function enumerateBlockStarts(runs, blockDays) {
|
|
21500
|
+
const starts = [];
|
|
21501
|
+
for (const run of runs) {
|
|
21502
|
+
const lastStart = run.length - blockDays;
|
|
21503
|
+
for (let offset = 0; offset <= lastStart; offset++) {
|
|
21504
|
+
starts.push(run.start + offset);
|
|
21505
|
+
}
|
|
21506
|
+
}
|
|
21507
|
+
return starts;
|
|
21508
|
+
}
|
|
21509
|
+
function drawResampleIndices(rng, blockStarts, blockDays, n) {
|
|
21510
|
+
const indices = [];
|
|
21511
|
+
while (indices.length < n) {
|
|
21512
|
+
const start = blockStarts[Math.floor(rng() * blockStarts.length)];
|
|
21513
|
+
for (let k = 0; k < blockDays && indices.length < n; k++) {
|
|
21514
|
+
indices.push(start + k);
|
|
21515
|
+
}
|
|
21516
|
+
}
|
|
21517
|
+
return indices;
|
|
21518
|
+
}
|
|
21519
|
+
function computeCore(params) {
|
|
21520
|
+
const {
|
|
21521
|
+
overlapDays,
|
|
21522
|
+
runs,
|
|
21523
|
+
deltaSeries,
|
|
21524
|
+
memberDeltas,
|
|
21525
|
+
extremum,
|
|
21526
|
+
blockDays,
|
|
21527
|
+
resamples,
|
|
21528
|
+
seed,
|
|
21529
|
+
ciLevel,
|
|
21530
|
+
statistic,
|
|
21531
|
+
effectiveNFloorBlocks
|
|
21532
|
+
} = params;
|
|
21533
|
+
const n = overlapDays.length;
|
|
21534
|
+
const effectiveN = n / blockDays;
|
|
21535
|
+
const takeExtremum = (values) => extremum === "min" ? Math.min(...values) : Math.max(...values);
|
|
21536
|
+
let point;
|
|
21537
|
+
if (n === 0) {
|
|
21538
|
+
point = null;
|
|
21539
|
+
} else if (memberDeltas) {
|
|
21540
|
+
point = takeExtremum(memberDeltas.map((d) => statistic(d)));
|
|
21541
|
+
} else {
|
|
21542
|
+
point = statistic(deltaSeries);
|
|
21543
|
+
}
|
|
21544
|
+
const blockStarts = enumerateBlockStarts(runs, blockDays);
|
|
21545
|
+
if (effectiveNFloorBlocks !== void 0 && effectiveN < effectiveNFloorBlocks) {
|
|
21546
|
+
return { point, low: null, high: null, effectiveN, status: "notComparable" };
|
|
21547
|
+
}
|
|
21548
|
+
if (blockStarts.length < 2) {
|
|
21549
|
+
return { point, low: null, high: null, effectiveN, status: "underpowered" };
|
|
21550
|
+
}
|
|
21551
|
+
const rng = mulberry32(deriveSeed(seed, blockDays));
|
|
21552
|
+
const distribution = new Array(resamples);
|
|
21553
|
+
for (let r = 0; r < resamples; r++) {
|
|
21554
|
+
const idx = drawResampleIndices(rng, blockStarts, blockDays, n);
|
|
21555
|
+
if (memberDeltas) {
|
|
21556
|
+
const stats = memberDeltas.map((d) => statistic(idx.map((i) => d[i])));
|
|
21557
|
+
distribution[r] = takeExtremum(stats);
|
|
21558
|
+
} else {
|
|
21559
|
+
distribution[r] = statistic(idx.map((i) => deltaSeries[i]));
|
|
21560
|
+
}
|
|
21561
|
+
}
|
|
21562
|
+
distribution.sort((a, b) => a - b);
|
|
21563
|
+
const alpha = 1 - ciLevel;
|
|
21564
|
+
const low = percentileOf(distribution, alpha / 2);
|
|
21565
|
+
const high = percentileOf(distribution, 1 - alpha / 2);
|
|
21566
|
+
return { point, low, high, effectiveN, status: "resolved" };
|
|
21567
|
+
}
|
|
21568
|
+
function buildSelectionOverlap(members) {
|
|
21569
|
+
const memberMaps = members.map((m) => {
|
|
21570
|
+
const overlap2 = buildComparisonOverlap(m.armA, m.armB);
|
|
21571
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
21572
|
+
for (let i = 0; i < overlap2.days.length; i++) {
|
|
21573
|
+
map2.set(overlap2.days[i], overlap2.delta[i]);
|
|
21574
|
+
}
|
|
21575
|
+
return map2;
|
|
21576
|
+
});
|
|
21577
|
+
let ambient = [];
|
|
21578
|
+
for (const m of members) {
|
|
21579
|
+
const armBDays = isConstantArm(m.armB) || m.armB === void 0 ? [] : m.armB.index;
|
|
21580
|
+
ambient = unionDays(ambient, unionDays(m.armA.index, armBDays));
|
|
21581
|
+
}
|
|
21582
|
+
const overlap = buildOverlap(
|
|
21583
|
+
ambient,
|
|
21584
|
+
(day) => memberMaps.every((map2) => map2.has(day)),
|
|
21585
|
+
() => 0
|
|
21586
|
+
);
|
|
21587
|
+
const memberDeltas = memberMaps.map((map2) => overlap.days.map((day) => map2.get(day)));
|
|
21588
|
+
return { days: overlap.days, runs: overlap.runs, memberDeltas };
|
|
21589
|
+
}
|
|
21590
|
+
function holdingPeriodBlockDays(holdingPeriodsTradingDays, percentile = 0.95) {
|
|
21591
|
+
if (holdingPeriodsTradingDays.length === 0) return 1;
|
|
21592
|
+
const sorted = [...holdingPeriodsTradingDays].sort((a, b) => a - b);
|
|
21593
|
+
return Math.max(1, Math.round(percentileOf(sorted, percentile)));
|
|
21594
|
+
}
|
|
21595
|
+
function pairedBlockBootstrap(input) {
|
|
21596
|
+
const blockDays = Math.max(1, Math.round(input.holdingRule.blockDays));
|
|
21597
|
+
const { ciLevel, resamples, seed, statistic, effectiveNFloorBlocks } = input;
|
|
21598
|
+
let overlapDays;
|
|
21599
|
+
let runs;
|
|
21600
|
+
let deltaSeries;
|
|
21601
|
+
let memberDeltas;
|
|
21602
|
+
let extremum;
|
|
21603
|
+
let selection = null;
|
|
21604
|
+
if (input.selectionSet) {
|
|
21605
|
+
const sel = buildSelectionOverlap(input.selectionSet.members);
|
|
21606
|
+
overlapDays = sel.days;
|
|
21607
|
+
runs = sel.runs;
|
|
21608
|
+
memberDeltas = sel.memberDeltas;
|
|
21609
|
+
extremum = input.selectionSet.extremum;
|
|
21610
|
+
deltaSeries = [];
|
|
21611
|
+
const memberPoints = sel.memberDeltas.map((d) => statistic(d));
|
|
21612
|
+
const kConsidered = memberPoints.length;
|
|
21613
|
+
const centroid = kConsidered > 0 ? memberPoints.reduce((s, v) => s + v, 0) / kConsidered : 0;
|
|
21614
|
+
let maxGap = 0;
|
|
21615
|
+
if (kConsidered >= 2) {
|
|
21616
|
+
const ordered = [...memberPoints].sort((a, b) => a - b);
|
|
21617
|
+
maxGap = extremum === "min" ? ordered[1] - ordered[0] : ordered[kConsidered - 1] - ordered[kConsidered - 2];
|
|
21618
|
+
}
|
|
21619
|
+
selection = { centroid, maxGap, kConsidered };
|
|
21620
|
+
} else {
|
|
21621
|
+
const overlap = buildComparisonOverlap(input.armA, input.armB);
|
|
21622
|
+
overlapDays = overlap.days;
|
|
21623
|
+
runs = overlap.runs;
|
|
21624
|
+
deltaSeries = overlap.delta;
|
|
21625
|
+
}
|
|
21626
|
+
const overlapWindow = overlapDays.length > 0 ? { start: overlapDays[0], end: overlapDays[overlapDays.length - 1] } : null;
|
|
21627
|
+
const primary = computeCore({
|
|
21628
|
+
overlapDays,
|
|
21629
|
+
runs,
|
|
21630
|
+
deltaSeries,
|
|
21631
|
+
memberDeltas,
|
|
21632
|
+
extremum,
|
|
21633
|
+
blockDays,
|
|
21634
|
+
resamples,
|
|
21635
|
+
seed,
|
|
21636
|
+
ciLevel,
|
|
21637
|
+
statistic,
|
|
21638
|
+
effectiveNFloorBlocks
|
|
21639
|
+
});
|
|
21640
|
+
const sensitivity = [];
|
|
21641
|
+
for (const multiplier of input.holdingRule.sensitivity ?? []) {
|
|
21642
|
+
const sensBlockDays = Math.max(1, Math.round(multiplier * blockDays));
|
|
21643
|
+
const sens = computeCore({
|
|
21644
|
+
overlapDays,
|
|
21645
|
+
runs,
|
|
21646
|
+
deltaSeries,
|
|
21647
|
+
memberDeltas,
|
|
21648
|
+
extremum,
|
|
21649
|
+
blockDays: sensBlockDays,
|
|
21650
|
+
resamples,
|
|
21651
|
+
seed,
|
|
21652
|
+
ciLevel,
|
|
21653
|
+
statistic,
|
|
21654
|
+
effectiveNFloorBlocks
|
|
21655
|
+
});
|
|
21656
|
+
sensitivity.push({
|
|
21657
|
+
blockDays: sensBlockDays,
|
|
21658
|
+
ci: { low: sens.low, high: sens.high },
|
|
21659
|
+
status: sens.status
|
|
21660
|
+
});
|
|
21661
|
+
}
|
|
21662
|
+
return {
|
|
21663
|
+
point: primary.point,
|
|
21664
|
+
ci: { level: ciLevel, low: primary.low, high: primary.high, method: "paired-day-block" },
|
|
21665
|
+
effectiveN: primary.effectiveN,
|
|
21666
|
+
overlapWindow,
|
|
21667
|
+
blockDays,
|
|
21668
|
+
sensitivity,
|
|
21669
|
+
selection,
|
|
21670
|
+
status: primary.status,
|
|
21671
|
+
seed
|
|
21672
|
+
};
|
|
21673
|
+
}
|
|
21674
|
+
|
|
21442
21675
|
// ../lib/calculations/index.ts
|
|
21443
21676
|
function generateDataHash(trades, dailyLogs) {
|
|
21444
21677
|
const data = {
|
|
@@ -21467,9 +21700,15 @@ var CalculationOrchestrator = class {
|
|
|
21467
21700
|
};
|
|
21468
21701
|
}
|
|
21469
21702
|
const calculator = new PortfolioStatsCalculator(config4);
|
|
21470
|
-
const portfolioStats = calculator.calculatePortfolioStats(
|
|
21703
|
+
const portfolioStats = calculator.calculatePortfolioStats(
|
|
21704
|
+
trades,
|
|
21705
|
+
dailyLogs
|
|
21706
|
+
);
|
|
21471
21707
|
const strategyStats = calculator.calculateStrategyStats(trades);
|
|
21472
|
-
const performanceMetrics = PerformanceCalculator.calculatePerformanceMetrics(
|
|
21708
|
+
const performanceMetrics = PerformanceCalculator.calculatePerformanceMetrics(
|
|
21709
|
+
trades,
|
|
21710
|
+
dailyLogs
|
|
21711
|
+
);
|
|
21473
21712
|
this.cache.set(blockId, {
|
|
21474
21713
|
portfolioStats,
|
|
21475
21714
|
strategyStats,
|
|
@@ -21509,9 +21748,9 @@ var calculationOrchestrator = new CalculationOrchestrator();
|
|
|
21509
21748
|
var REPORTING_TRADE_COLUMN_ALIASES = {
|
|
21510
21749
|
"Initial Premium ($)": "Initial Premium",
|
|
21511
21750
|
"Initial Credit": "Initial Premium",
|
|
21512
|
-
|
|
21751
|
+
Contracts: "No. of Contracts",
|
|
21513
21752
|
"Contracts Traded": "No. of Contracts",
|
|
21514
|
-
|
|
21753
|
+
PL: "P/L"
|
|
21515
21754
|
};
|
|
21516
21755
|
|
|
21517
21756
|
// ../lib/processing/tat-adapter.ts
|
|
@@ -21654,6 +21893,8 @@ export {
|
|
|
21654
21893
|
PortfolioStatsCalculator,
|
|
21655
21894
|
calculateCorrelationMatrix,
|
|
21656
21895
|
performTailRiskAnalysis,
|
|
21896
|
+
holdingPeriodBlockDays,
|
|
21897
|
+
pairedBlockBootstrap,
|
|
21657
21898
|
REPORTING_TRADE_COLUMN_ALIASES,
|
|
21658
21899
|
isTatFormat,
|
|
21659
21900
|
convertTatRowToReportingTrade
|
|
@@ -21669,4 +21910,4 @@ decimal.js/decimal.mjs:
|
|
|
21669
21910
|
* MIT Licence
|
|
21670
21911
|
*)
|
|
21671
21912
|
*/
|
|
21672
|
-
//# sourceMappingURL=chunk-
|
|
21913
|
+
//# sourceMappingURL=chunk-2I3S2ZLT.js.map
|