@timecell/engine 0.1.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/dist/crash-survival.d.ts +26 -0
- package/dist/crash-survival.d.ts.map +1 -0
- package/dist/crash-survival.js +98 -0
- package/dist/crash-survival.js.map +1 -0
- package/dist/fixtures/demo-portfolio.d.ts +10 -0
- package/dist/fixtures/demo-portfolio.d.ts.map +1 -0
- package/dist/fixtures/demo-portfolio.js +24 -0
- package/dist/fixtures/demo-portfolio.js.map +1 -0
- package/dist/geometric-mean.d.ts +21 -0
- package/dist/geometric-mean.d.ts.map +1 -0
- package/dist/geometric-mean.js +72 -0
- package/dist/geometric-mean.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/ruin-test.d.ts +17 -0
- package/dist/ruin-test.d.ts.map +1 -0
- package/dist/ruin-test.js +24 -0
- package/dist/ruin-test.js.map +1 -0
- package/dist/runway.d.ts +6 -0
- package/dist/runway.d.ts.map +1 -0
- package/dist/runway.js +15 -0
- package/dist/runway.js.map +1 -0
- package/dist/types.d.ts +55 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +26 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { PortfolioInput, HedgePosition, SurvivalResult, CrashSurvivalConfig } from "./types.js";
|
|
2
|
+
/** Default configuration — all values overridable */
|
|
3
|
+
export declare const DEFAULT_CONFIG: CrashSurvivalConfig;
|
|
4
|
+
/**
|
|
5
|
+
* Calculate crash survival across multiple drawdown scenarios.
|
|
6
|
+
*
|
|
7
|
+
* For each scenario:
|
|
8
|
+
* - BTC drops by drawdownPct%
|
|
9
|
+
* - Non-BTC assets drop by drawdownPct * config.nonBtcCorrelation
|
|
10
|
+
* - Hedge payoff = sum of max(0, strike - crashPrice) * quantity for each position
|
|
11
|
+
* - Runway = (portfolio after crash + hedge payoff + liquid reserve) / monthly burn
|
|
12
|
+
* - Survival status based on runway vs config thresholds
|
|
13
|
+
*/
|
|
14
|
+
export declare function calculateCrashSurvival(portfolio: PortfolioInput, hedgePositions?: HedgePosition[], config?: Partial<CrashSurvivalConfig>): SurvivalResult;
|
|
15
|
+
/**
|
|
16
|
+
* Calculate hedge payoff at various BTC price multipliers.
|
|
17
|
+
*/
|
|
18
|
+
export declare function calculatePriceScenarios(hedgePositions: HedgePosition[], totalBtcHoldings: number, currentBtcPrice: number, multipliers?: number[]): {
|
|
19
|
+
btcPrice: number;
|
|
20
|
+
portfolioValue: number;
|
|
21
|
+
hedgePayoff: number;
|
|
22
|
+
netValue: number;
|
|
23
|
+
protectionPct: number;
|
|
24
|
+
changePct: number;
|
|
25
|
+
}[];
|
|
26
|
+
//# sourceMappingURL=crash-survival.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crash-survival.d.ts","sourceRoot":"","sources":["../src/crash-survival.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,cAAc,EACd,aAAa,EAEb,cAAc,EACd,mBAAmB,EACnB,MAAM,YAAY,CAAC;AAOpB,qDAAqD;AACrD,eAAO,MAAM,cAAc,EAAE,mBAK5B,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACrC,SAAS,EAAE,cAAc,EACzB,cAAc,GAAE,aAAa,EAAO,EACpC,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACvC,cAAc,CAwBhB;AAqDD;;GAEG;AACH,wBAAgB,uBAAuB,CACtC,cAAc,EAAE,aAAa,EAAE,EAC/B,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,WAAW,GAAE,MAAM,EAA4D;;;;;;;IAoB/E"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { calculateRunwayMonths } from "./runway.js";
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// Crash Survival Calculator
|
|
4
|
+
// =============================================================================
|
|
5
|
+
/** Default configuration — all values overridable */
|
|
6
|
+
export const DEFAULT_CONFIG = {
|
|
7
|
+
drawdowns: [30, 50, 70, 80],
|
|
8
|
+
nonBtcCorrelation: 0.5,
|
|
9
|
+
runwayWarningMonths: 24,
|
|
10
|
+
runwayCriticalMonths: 18,
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Calculate crash survival across multiple drawdown scenarios.
|
|
14
|
+
*
|
|
15
|
+
* For each scenario:
|
|
16
|
+
* - BTC drops by drawdownPct%
|
|
17
|
+
* - Non-BTC assets drop by drawdownPct * config.nonBtcCorrelation
|
|
18
|
+
* - Hedge payoff = sum of max(0, strike - crashPrice) * quantity for each position
|
|
19
|
+
* - Runway = (portfolio after crash + hedge payoff + liquid reserve) / monthly burn
|
|
20
|
+
* - Survival status based on runway vs config thresholds
|
|
21
|
+
*/
|
|
22
|
+
export function calculateCrashSurvival(portfolio, hedgePositions = [], config = {}) {
|
|
23
|
+
const cfg = { ...DEFAULT_CONFIG, ...config };
|
|
24
|
+
const btcValue = portfolio.totalValueUsd * (portfolio.btcPercentage / 100);
|
|
25
|
+
const nonBtcValue = portfolio.totalValueUsd - btcValue;
|
|
26
|
+
const scenarios = cfg.drawdowns.map((drawdownPct) => calculateScenario(portfolio, btcValue, nonBtcValue, drawdownPct, hedgePositions, cfg));
|
|
27
|
+
// Find max survivable drawdown (highest where status is not critical)
|
|
28
|
+
const survivable = scenarios.filter((s) => s.survivalStatus !== "critical");
|
|
29
|
+
const maxSurvivableDrawdown = survivable.length > 0 ? Math.max(...survivable.map((s) => s.drawdownPct)) : 0;
|
|
30
|
+
// Ruin test: survive highest drawdown scenario
|
|
31
|
+
const worstScenario = scenarios[scenarios.length - 1];
|
|
32
|
+
const ruinTestPassed = worstScenario ? worstScenario.survivalStatus !== "critical" : false;
|
|
33
|
+
return {
|
|
34
|
+
portfolio,
|
|
35
|
+
scenarios,
|
|
36
|
+
maxSurvivableDrawdown,
|
|
37
|
+
ruinTestPassed,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function calculateScenario(portfolio, btcValue, nonBtcValue, drawdownPct, hedgePositions, config) {
|
|
41
|
+
const btcDrawdown = drawdownPct / 100;
|
|
42
|
+
const nonBtcDrawdown = btcDrawdown * config.nonBtcCorrelation;
|
|
43
|
+
const btcPriceAtCrash = portfolio.btcPriceUsd * (1 - btcDrawdown);
|
|
44
|
+
const btcValueAfterCrash = btcValue * (1 - btcDrawdown);
|
|
45
|
+
const nonBtcValueAfterCrash = nonBtcValue * (1 - nonBtcDrawdown);
|
|
46
|
+
const portfolioValueAfterCrash = btcValueAfterCrash + nonBtcValueAfterCrash;
|
|
47
|
+
// Hedge payoff: intrinsic value of puts
|
|
48
|
+
let hedgePayoff = 0;
|
|
49
|
+
for (const pos of hedgePositions) {
|
|
50
|
+
hedgePayoff += Math.max(0, pos.strikeUsd - btcPriceAtCrash) * pos.quantityBtc;
|
|
51
|
+
}
|
|
52
|
+
const netPosition = portfolioValueAfterCrash + hedgePayoff + portfolio.liquidReserveUsd;
|
|
53
|
+
// Runway: net position / monthly burn — how many months you can sustain
|
|
54
|
+
// by liquidating everything (portfolio after crash + hedge payoff + liquid reserve)
|
|
55
|
+
const runwayMonths = calculateRunwayMonths(netPosition, portfolio.monthlyBurnUsd);
|
|
56
|
+
// Survival status
|
|
57
|
+
let survivalStatus;
|
|
58
|
+
if (runwayMonths >= config.runwayWarningMonths) {
|
|
59
|
+
survivalStatus = "safe";
|
|
60
|
+
}
|
|
61
|
+
else if (runwayMonths >= config.runwayCriticalMonths) {
|
|
62
|
+
survivalStatus = "warning";
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
survivalStatus = "critical";
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
drawdownPct,
|
|
69
|
+
btcPriceAtCrash,
|
|
70
|
+
btcValueAfterCrash,
|
|
71
|
+
nonBtcValueAfterCrash,
|
|
72
|
+
portfolioValueAfterCrash,
|
|
73
|
+
hedgePayoff,
|
|
74
|
+
netPosition,
|
|
75
|
+
runwayMonths,
|
|
76
|
+
survivalStatus,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Calculate hedge payoff at various BTC price multipliers.
|
|
81
|
+
*/
|
|
82
|
+
export function calculatePriceScenarios(hedgePositions, totalBtcHoldings, currentBtcPrice, multipliers = [0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.4]) {
|
|
83
|
+
const currentPortfolioValue = totalBtcHoldings * currentBtcPrice;
|
|
84
|
+
return multipliers.map((m) => {
|
|
85
|
+
const btcPrice = m === 1.0 ? currentBtcPrice : Math.round((currentBtcPrice * m) / 5000) * 5000;
|
|
86
|
+
const portfolioValue = totalBtcHoldings * btcPrice;
|
|
87
|
+
let hedgePayoff = 0;
|
|
88
|
+
for (const p of hedgePositions) {
|
|
89
|
+
hedgePayoff += Math.max(0, p.strikeUsd - btcPrice) * p.quantityBtc;
|
|
90
|
+
}
|
|
91
|
+
const netValue = portfolioValue + hedgePayoff;
|
|
92
|
+
const portfolioLoss = currentPortfolioValue - portfolioValue;
|
|
93
|
+
const protectionPct = portfolioLoss > 0 ? hedgePayoff / portfolioLoss : 0;
|
|
94
|
+
const changePct = ((btcPrice - currentBtcPrice) / currentBtcPrice) * 100;
|
|
95
|
+
return { btcPrice, portfolioValue, hedgePayoff, netValue, protectionPct, changePct };
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=crash-survival.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crash-survival.js","sourceRoot":"","sources":["../src/crash-survival.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PortfolioInput, HedgePosition } from "../types.js";
|
|
2
|
+
/** Default BTC price for demo (approximate Feb 2026) */
|
|
3
|
+
export declare const DEMO_BTC_PRICE = 84000;
|
|
4
|
+
/** Demo portfolio: $5M, 35% BTC, $25K/mo burn, $600K liquid reserve */
|
|
5
|
+
export declare const DEMO_PORTFOLIO: PortfolioInput;
|
|
6
|
+
/** Demo hedge positions (optional — shows with vs without insurance) */
|
|
7
|
+
export declare const DEMO_HEDGE_POSITIONS: HedgePosition[];
|
|
8
|
+
/** Portfolio with no hedge — for comparison */
|
|
9
|
+
export declare const DEMO_PORTFOLIO_NO_HEDGE: HedgePosition[];
|
|
10
|
+
//# sourceMappingURL=demo-portfolio.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo-portfolio.d.ts","sourceRoot":"","sources":["../../src/fixtures/demo-portfolio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjE,wDAAwD;AACxD,eAAO,MAAM,cAAc,QAAQ,CAAC;AAEpC,uEAAuE;AACvE,eAAO,MAAM,cAAc,EAAE,cAM5B,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,oBAAoB,EAAE,aAAa,EAM/C,CAAC;AAEF,+CAA+C;AAC/C,eAAO,MAAM,uBAAuB,EAAE,aAAa,EAAO,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Demo Portfolio — Realistic YPO-relevant example
|
|
3
|
+
// =============================================================================
|
|
4
|
+
/** Default BTC price for demo (approximate Feb 2026) */
|
|
5
|
+
export const DEMO_BTC_PRICE = 84000;
|
|
6
|
+
/** Demo portfolio: $5M, 35% BTC, $25K/mo burn, $600K liquid reserve */
|
|
7
|
+
export const DEMO_PORTFOLIO = {
|
|
8
|
+
totalValueUsd: 5_000_000,
|
|
9
|
+
btcPercentage: 35,
|
|
10
|
+
monthlyBurnUsd: 25_000,
|
|
11
|
+
liquidReserveUsd: 600_000,
|
|
12
|
+
btcPriceUsd: DEMO_BTC_PRICE,
|
|
13
|
+
};
|
|
14
|
+
/** Demo hedge positions (optional — shows with vs without insurance) */
|
|
15
|
+
export const DEMO_HEDGE_POSITIONS = [
|
|
16
|
+
{
|
|
17
|
+
strikeUsd: 60_000,
|
|
18
|
+
quantityBtc: 10,
|
|
19
|
+
expiryDate: "2026-09-30",
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
/** Portfolio with no hedge — for comparison */
|
|
23
|
+
export const DEMO_PORTFOLIO_NO_HEDGE = [];
|
|
24
|
+
//# sourceMappingURL=demo-portfolio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo-portfolio.js","sourceRoot":"","sources":["../../src/fixtures/demo-portfolio.ts"],"names":[],"mappings":"AAEA,gFAAgF;AAChF,kDAAkD;AAClD,gFAAgF;AAEhF,wDAAwD;AACxD,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAC;AAEpC,uEAAuE;AACvE,MAAM,CAAC,MAAM,cAAc,GAAmB;IAC7C,aAAa,EAAE,SAAS;IACxB,aAAa,EAAE,EAAE;IACjB,cAAc,EAAE,MAAM;IACtB,gBAAgB,EAAE,OAAO;IACzB,WAAW,EAAE,cAAc;CAC3B,CAAC;AAEF,wEAAwE;AACxE,MAAM,CAAC,MAAM,oBAAoB,GAAoB;IACpD;QACC,SAAS,EAAE,MAAM;QACjB,WAAW,EAAE,EAAE;QACf,UAAU,EAAE,YAAY;KACxB;CACD,CAAC;AAEF,+CAA+C;AAC/C,MAAM,CAAC,MAAM,uBAAuB,GAAoB,EAAE,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { GeometricMeanResult } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Compare hedged vs unhedged CAGR over a crash cycle.
|
|
4
|
+
*
|
|
5
|
+
* Model: (n-1) good years at normalReturn, then 1 crash year.
|
|
6
|
+
* Hedge costs annualCost each year but recovers a fraction of crash loss.
|
|
7
|
+
*
|
|
8
|
+
* Ported from open-fo calculateGeometricMeanCAGR.
|
|
9
|
+
*/
|
|
10
|
+
export declare function calculateGeometricMeanCAGR(normalReturn: number, annualCost: number, crashMagnitude: number, recoveryOfLoss: number, cycleLength: number): GeometricMeanResult;
|
|
11
|
+
/**
|
|
12
|
+
* Find the max cycle length where hedge improves CAGR (break-even point).
|
|
13
|
+
* Lower = better (crash only needs to happen once every N years to justify hedge).
|
|
14
|
+
*
|
|
15
|
+
* Ported from open-fo calculateGeometricBreakeven.
|
|
16
|
+
*/
|
|
17
|
+
export declare function calculateGeometricBreakeven(annualCost: number, recoveryOfLoss: number, crashMagnitude?: number, normalReturn?: number): {
|
|
18
|
+
breakEvenYears: number | null;
|
|
19
|
+
annualProbability: number | null;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=geometric-mean.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geometric-mean.d.ts","sourceRoot":"","sources":["../src/geometric-mean.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAMtD;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACzC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM,GACjB,mBAAmB,CA6BrB;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAC1C,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,EACtB,cAAc,SAAM,EACpB,YAAY,SAAO,GACjB;IAAE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAiCrE"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Geometric Mean CAGR (Spitznagel Safe Haven Framework)
|
|
3
|
+
// =============================================================================
|
|
4
|
+
/**
|
|
5
|
+
* Compare hedged vs unhedged CAGR over a crash cycle.
|
|
6
|
+
*
|
|
7
|
+
* Model: (n-1) good years at normalReturn, then 1 crash year.
|
|
8
|
+
* Hedge costs annualCost each year but recovers a fraction of crash loss.
|
|
9
|
+
*
|
|
10
|
+
* Ported from open-fo calculateGeometricMeanCAGR.
|
|
11
|
+
*/
|
|
12
|
+
export function calculateGeometricMeanCAGR(normalReturn, annualCost, crashMagnitude, recoveryOfLoss, cycleLength) {
|
|
13
|
+
const recoveryValue = recoveryOfLoss * crashMagnitude;
|
|
14
|
+
// Unhedged: (n-1) normal years then one crash year
|
|
15
|
+
const unhedgedGrowth = Math.pow(1 + normalReturn, cycleLength - 1) * (1 - crashMagnitude);
|
|
16
|
+
const unhedgedCAGR = Math.pow(unhedgedGrowth, 1 / cycleLength) - 1;
|
|
17
|
+
// Hedged: (n-1) normal years minus cost, then crash year with recovery
|
|
18
|
+
const hedgedGrowth = Math.pow(1 + normalReturn - annualCost, cycleLength - 1) *
|
|
19
|
+
(1 - crashMagnitude + recoveryValue);
|
|
20
|
+
const hedgedCAGR = Math.pow(hedgedGrowth, 1 / cycleLength) - 1;
|
|
21
|
+
const improvement = hedgedCAGR - unhedgedCAGR;
|
|
22
|
+
return {
|
|
23
|
+
unhedgedCAGR,
|
|
24
|
+
hedgedCAGR,
|
|
25
|
+
improvement,
|
|
26
|
+
isPositiveEV: improvement > 0,
|
|
27
|
+
assumptions: {
|
|
28
|
+
normalReturn,
|
|
29
|
+
crashMagnitude,
|
|
30
|
+
cycleLength,
|
|
31
|
+
annualCost,
|
|
32
|
+
recoveryPercent: recoveryOfLoss,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Find the max cycle length where hedge improves CAGR (break-even point).
|
|
38
|
+
* Lower = better (crash only needs to happen once every N years to justify hedge).
|
|
39
|
+
*
|
|
40
|
+
* Ported from open-fo calculateGeometricBreakeven.
|
|
41
|
+
*/
|
|
42
|
+
export function calculateGeometricBreakeven(annualCost, recoveryOfLoss, crashMagnitude = 0.5, normalReturn = 0.15) {
|
|
43
|
+
if (annualCost <= 0) {
|
|
44
|
+
return { breakEvenYears: 1, annualProbability: 100 };
|
|
45
|
+
}
|
|
46
|
+
let lo = 2;
|
|
47
|
+
let hi = 200;
|
|
48
|
+
const atMin = calculateGeometricMeanCAGR(normalReturn, annualCost, crashMagnitude, recoveryOfLoss, lo);
|
|
49
|
+
if (atMin.improvement <= 0) {
|
|
50
|
+
return { breakEvenYears: null, annualProbability: null };
|
|
51
|
+
}
|
|
52
|
+
const atMax = calculateGeometricMeanCAGR(normalReturn, annualCost, crashMagnitude, recoveryOfLoss, hi);
|
|
53
|
+
if (atMax.improvement > 0) {
|
|
54
|
+
return { breakEvenYears: 200, annualProbability: 0.5 };
|
|
55
|
+
}
|
|
56
|
+
for (let i = 0; i < 50; i++) {
|
|
57
|
+
const mid = (lo + hi) / 2;
|
|
58
|
+
const result = calculateGeometricMeanCAGR(normalReturn, annualCost, crashMagnitude, recoveryOfLoss, mid);
|
|
59
|
+
if (result.improvement > 0) {
|
|
60
|
+
lo = mid;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
hi = mid;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const breakEvenYears = Math.round(lo);
|
|
67
|
+
return {
|
|
68
|
+
breakEvenYears,
|
|
69
|
+
annualProbability: breakEvenYears > 0 ? (1 / breakEvenYears) * 100 : null,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=geometric-mean.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geometric-mean.js","sourceRoot":"","sources":["../src/geometric-mean.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { PortfolioInput, HedgePosition, CrashScenario, SurvivalResult, CrashSurvivalConfig, GeometricMeanResult, } from "./types.js";
|
|
2
|
+
export { calculateCrashSurvival, calculatePriceScenarios, DEFAULT_CONFIG } from "./crash-survival.js";
|
|
3
|
+
export { calculateRunwayMonths } from "./runway.js";
|
|
4
|
+
export { ruinTest } from "./ruin-test.js";
|
|
5
|
+
export { calculateGeometricMeanCAGR, calculateGeometricBreakeven } from "./geometric-mean.js";
|
|
6
|
+
export { DEMO_PORTFOLIO, DEMO_HEDGE_POSITIONS, DEMO_BTC_PRICE } from "./fixtures/demo-portfolio.js";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,YAAY,EACX,cAAc,EACd,aAAa,EACb,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,mBAAmB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACtG,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// @timecell/engine — Public API
|
|
3
|
+
// =============================================================================
|
|
4
|
+
export { calculateCrashSurvival, calculatePriceScenarios, DEFAULT_CONFIG } from "./crash-survival.js";
|
|
5
|
+
export { calculateRunwayMonths } from "./runway.js";
|
|
6
|
+
export { ruinTest } from "./ruin-test.js";
|
|
7
|
+
export { calculateGeometricMeanCAGR, calculateGeometricBreakeven } from "./geometric-mean.js";
|
|
8
|
+
export { DEMO_PORTFOLIO, DEMO_HEDGE_POSITIONS, DEMO_BTC_PRICE } from "./fixtures/demo-portfolio.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,gCAAgC;AAChC,gFAAgF;AAWhF,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACtG,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { PortfolioInput, HedgePosition } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The Ruin Test from Bitcoin Investing Framework v2:
|
|
4
|
+
*
|
|
5
|
+
* "If Bitcoin drops 80% AND your other assets drop 40% simultaneously
|
|
6
|
+
* — as happened in 2022 — do you survive? Can you meet all obligations?"
|
|
7
|
+
*
|
|
8
|
+
* Returns true if you survive the worst-case correlated crash.
|
|
9
|
+
*/
|
|
10
|
+
export declare function ruinTest(portfolio: PortfolioInput, hedgePositions?: HedgePosition[]): {
|
|
11
|
+
passed: boolean;
|
|
12
|
+
runwayMonths: number;
|
|
13
|
+
portfolioValueAfterCrash: number;
|
|
14
|
+
netPosition: number;
|
|
15
|
+
hedgePayoff: number;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=ruin-test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruin-test.d.ts","sourceRoot":"","sources":["../src/ruin-test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAOhE;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACvB,SAAS,EAAE,cAAc,EACzB,cAAc,GAAE,aAAa,EAAO,GAClC;IACF,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,wBAAwB,EAAE,MAAM,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACpB,CAWA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { calculateCrashSurvival } from "./crash-survival.js";
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// Ruin Test (Framework Part 3, Step 3)
|
|
4
|
+
// =============================================================================
|
|
5
|
+
/**
|
|
6
|
+
* The Ruin Test from Bitcoin Investing Framework v2:
|
|
7
|
+
*
|
|
8
|
+
* "If Bitcoin drops 80% AND your other assets drop 40% simultaneously
|
|
9
|
+
* — as happened in 2022 — do you survive? Can you meet all obligations?"
|
|
10
|
+
*
|
|
11
|
+
* Returns true if you survive the worst-case correlated crash.
|
|
12
|
+
*/
|
|
13
|
+
export function ruinTest(portfolio, hedgePositions = []) {
|
|
14
|
+
const result = calculateCrashSurvival(portfolio, hedgePositions, { drawdowns: [80] });
|
|
15
|
+
const scenario = result.scenarios[0];
|
|
16
|
+
return {
|
|
17
|
+
passed: scenario.survivalStatus !== "critical",
|
|
18
|
+
runwayMonths: scenario.runwayMonths,
|
|
19
|
+
portfolioValueAfterCrash: scenario.portfolioValueAfterCrash,
|
|
20
|
+
netPosition: scenario.netPosition,
|
|
21
|
+
hedgePayoff: scenario.hedgePayoff,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=ruin-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruin-test.js","sourceRoot":"","sources":["../src/ruin-test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,gFAAgF;AAChF,uCAAuC;AACvC,gFAAgF;AAEhF;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CACvB,SAAyB,EACzB,iBAAkC,EAAE;IAQpC,MAAM,MAAM,GAAG,sBAAsB,CAAC,SAAS,EAAE,cAAc,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACtF,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAErC,OAAO;QACN,MAAM,EAAE,QAAQ,CAAC,cAAc,KAAK,UAAU;QAC9C,YAAY,EAAE,QAAQ,CAAC,YAAY;QACnC,wBAAwB,EAAE,QAAQ,CAAC,wBAAwB;QAC3D,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,WAAW,EAAE,QAAQ,CAAC,WAAW;KACjC,CAAC;AACH,CAAC"}
|
package/dist/runway.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calculate runway in months: how long can you sustain current burn
|
|
3
|
+
* from available liquidity without selling assets.
|
|
4
|
+
*/
|
|
5
|
+
export declare function calculateRunwayMonths(availableLiquidity: number, monthlyBurn: number): number;
|
|
6
|
+
//# sourceMappingURL=runway.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runway.d.ts","sourceRoot":"","sources":["../src/runway.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,qBAAqB,CACpC,kBAAkB,EAAE,MAAM,EAC1B,WAAW,EAAE,MAAM,GACjB,MAAM,CAIR"}
|
package/dist/runway.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Runway Calculator
|
|
3
|
+
// =============================================================================
|
|
4
|
+
/**
|
|
5
|
+
* Calculate runway in months: how long can you sustain current burn
|
|
6
|
+
* from available liquidity without selling assets.
|
|
7
|
+
*/
|
|
8
|
+
export function calculateRunwayMonths(availableLiquidity, monthlyBurn) {
|
|
9
|
+
if (monthlyBurn <= 0)
|
|
10
|
+
return Infinity;
|
|
11
|
+
if (availableLiquidity <= 0)
|
|
12
|
+
return 0;
|
|
13
|
+
return availableLiquidity / monthlyBurn;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=runway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runway.js","sourceRoot":"","sources":["../src/runway.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACpC,kBAA0B,EAC1B,WAAmB;IAEnB,IAAI,WAAW,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IACtC,IAAI,kBAAkB,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACtC,OAAO,kBAAkB,GAAG,WAAW,CAAC;AACzC,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** User's portfolio configuration */
|
|
2
|
+
export interface PortfolioInput {
|
|
3
|
+
totalValueUsd: number;
|
|
4
|
+
btcPercentage: number;
|
|
5
|
+
monthlyBurnUsd: number;
|
|
6
|
+
liquidReserveUsd: number;
|
|
7
|
+
btcPriceUsd: number;
|
|
8
|
+
}
|
|
9
|
+
/** Optional hedge position (put option) */
|
|
10
|
+
export interface HedgePosition {
|
|
11
|
+
strikeUsd: number;
|
|
12
|
+
quantityBtc: number;
|
|
13
|
+
expiryDate?: string;
|
|
14
|
+
}
|
|
15
|
+
/** Result for a single crash scenario */
|
|
16
|
+
export interface CrashScenario {
|
|
17
|
+
drawdownPct: number;
|
|
18
|
+
btcPriceAtCrash: number;
|
|
19
|
+
btcValueAfterCrash: number;
|
|
20
|
+
nonBtcValueAfterCrash: number;
|
|
21
|
+
portfolioValueAfterCrash: number;
|
|
22
|
+
hedgePayoff: number;
|
|
23
|
+
netPosition: number;
|
|
24
|
+
runwayMonths: number;
|
|
25
|
+
survivalStatus: "safe" | "warning" | "critical";
|
|
26
|
+
}
|
|
27
|
+
/** Full survival analysis result */
|
|
28
|
+
export interface SurvivalResult {
|
|
29
|
+
portfolio: PortfolioInput;
|
|
30
|
+
scenarios: CrashScenario[];
|
|
31
|
+
maxSurvivableDrawdown: number;
|
|
32
|
+
ruinTestPassed: boolean;
|
|
33
|
+
}
|
|
34
|
+
/** Configuration for crash survival calculations */
|
|
35
|
+
export interface CrashSurvivalConfig {
|
|
36
|
+
drawdowns: number[];
|
|
37
|
+
nonBtcCorrelation: number;
|
|
38
|
+
runwayWarningMonths: number;
|
|
39
|
+
runwayCriticalMonths: number;
|
|
40
|
+
}
|
|
41
|
+
/** Geometric mean CAGR comparison (hedged vs unhedged) */
|
|
42
|
+
export interface GeometricMeanResult {
|
|
43
|
+
unhedgedCAGR: number;
|
|
44
|
+
hedgedCAGR: number;
|
|
45
|
+
improvement: number;
|
|
46
|
+
isPositiveEV: boolean;
|
|
47
|
+
assumptions: {
|
|
48
|
+
normalReturn: number;
|
|
49
|
+
crashMagnitude: number;
|
|
50
|
+
cycleLength: number;
|
|
51
|
+
annualCost: number;
|
|
52
|
+
recoveryPercent: number;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAIA,qCAAqC;AACrC,MAAM,WAAW,cAAc;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,wBAAwB,EAAE,MAAM,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;CAChD;AAED,oCAAoC;AACpC,MAAM,WAAW,cAAc;IAC9B,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,cAAc,EAAE,OAAO,CAAC;CACxB;AAED,oDAAoD;AACpD,MAAM,WAAW,mBAAmB;IACnC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;CAC7B;AAED,0DAA0D;AAC1D,MAAM,WAAW,mBAAmB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE;QACZ,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,CAAC;KACxB,CAAC;CACF"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,iCAAiC;AACjC,gFAAgF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@timecell/engine",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "TimeCell core engine",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": ["dist"],
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"test": "vitest"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"vitest": "latest"
|
|
25
|
+
}
|
|
26
|
+
}
|