backtest-kit 8.1.1 → 8.1.2
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/build/index.cjs +9 -1
- package/build/index.mjs +9 -1
- package/package.json +1 -1
package/build/index.cjs
CHANGED
|
@@ -24657,10 +24657,18 @@ class HeatmapStorage {
|
|
|
24657
24657
|
}
|
|
24658
24658
|
// Max absolute drawdown across all signals — denominator for Calmar and Recovery
|
|
24659
24659
|
const maxAbsFall = fallReturns.reduce((max, r) => Math.max(max, Math.abs(r)), 0);
|
|
24660
|
+
// Expected yearly returns — needed for Calmar
|
|
24661
|
+
let expectedYearlyReturns = 0;
|
|
24662
|
+
if (signals.length > 0 && avgPnl !== null) {
|
|
24663
|
+
const avgDurationMs = signals.reduce((sum, s) => sum + (s.closeTimestamp - s.signal.pendingAt), 0) / signals.length;
|
|
24664
|
+
const avgDurationDays = avgDurationMs / (1000 * 60 * 60 * 24);
|
|
24665
|
+
const tradesPerYear = avgDurationDays > 0 ? 365 / avgDurationDays : 0;
|
|
24666
|
+
expectedYearlyReturns = avgPnl * tradesPerYear;
|
|
24667
|
+
}
|
|
24660
24668
|
let calmarRatio = null;
|
|
24661
24669
|
let recoveryFactor = null;
|
|
24662
24670
|
if (maxAbsFall > 0 && totalPnl !== null) {
|
|
24663
|
-
calmarRatio =
|
|
24671
|
+
calmarRatio = expectedYearlyReturns / maxAbsFall;
|
|
24664
24672
|
recoveryFactor = totalPnl / maxAbsFall;
|
|
24665
24673
|
}
|
|
24666
24674
|
// Apply safe math checks
|
package/build/index.mjs
CHANGED
|
@@ -24637,10 +24637,18 @@ class HeatmapStorage {
|
|
|
24637
24637
|
}
|
|
24638
24638
|
// Max absolute drawdown across all signals — denominator for Calmar and Recovery
|
|
24639
24639
|
const maxAbsFall = fallReturns.reduce((max, r) => Math.max(max, Math.abs(r)), 0);
|
|
24640
|
+
// Expected yearly returns — needed for Calmar
|
|
24641
|
+
let expectedYearlyReturns = 0;
|
|
24642
|
+
if (signals.length > 0 && avgPnl !== null) {
|
|
24643
|
+
const avgDurationMs = signals.reduce((sum, s) => sum + (s.closeTimestamp - s.signal.pendingAt), 0) / signals.length;
|
|
24644
|
+
const avgDurationDays = avgDurationMs / (1000 * 60 * 60 * 24);
|
|
24645
|
+
const tradesPerYear = avgDurationDays > 0 ? 365 / avgDurationDays : 0;
|
|
24646
|
+
expectedYearlyReturns = avgPnl * tradesPerYear;
|
|
24647
|
+
}
|
|
24640
24648
|
let calmarRatio = null;
|
|
24641
24649
|
let recoveryFactor = null;
|
|
24642
24650
|
if (maxAbsFall > 0 && totalPnl !== null) {
|
|
24643
|
-
calmarRatio =
|
|
24651
|
+
calmarRatio = expectedYearlyReturns / maxAbsFall;
|
|
24644
24652
|
recoveryFactor = totalPnl / maxAbsFall;
|
|
24645
24653
|
}
|
|
24646
24654
|
// Apply safe math checks
|