openalgo-script 0.2.0 → 0.5.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/CHANGELOG.md +1198 -0
- package/README.md +127 -40
- package/dist/adapters/charts/driving.d.ts +50 -0
- package/dist/adapters/charts/driving.d.ts.map +1 -0
- package/dist/adapters/charts/driving.js +57 -0
- package/dist/adapters/charts/driving.js.map +1 -0
- package/dist/adapters/charts/run.d.ts +20 -0
- package/dist/adapters/charts/run.d.ts.map +1 -1
- package/dist/adapters/charts/run.js +83 -16
- package/dist/adapters/charts/run.js.map +1 -1
- package/dist/adapters/charts/surfaces.d.ts +17 -0
- package/dist/adapters/charts/surfaces.d.ts.map +1 -1
- package/dist/adapters/charts/tables.js +82 -0
- package/dist/adapters/charts/tables.js.map +1 -1
- package/dist/adapters/charts/venue.d.ts +73 -0
- package/dist/adapters/charts/venue.d.ts.map +1 -0
- package/dist/adapters/charts/venue.js +104 -0
- package/dist/adapters/charts/venue.js.map +1 -0
- package/dist/adapters/codemirror/commands.d.ts +14 -0
- package/dist/adapters/codemirror/commands.d.ts.map +1 -0
- package/dist/adapters/codemirror/commands.js +52 -0
- package/dist/adapters/codemirror/commands.js.map +1 -0
- package/dist/adapters/codemirror/completion.d.ts +15 -0
- package/dist/adapters/codemirror/completion.d.ts.map +1 -0
- package/dist/adapters/codemirror/completion.js +64 -0
- package/dist/adapters/codemirror/completion.js.map +1 -0
- package/dist/adapters/codemirror/contract.d.ts +156 -0
- package/dist/adapters/codemirror/contract.d.ts.map +1 -0
- package/dist/adapters/codemirror/contract.js +42 -0
- package/dist/adapters/codemirror/contract.js.map +1 -0
- package/dist/adapters/codemirror/index.d.ts +43 -0
- package/dist/adapters/codemirror/index.d.ts.map +1 -0
- package/dist/adapters/codemirror/index.js +8 -0
- package/dist/adapters/codemirror/index.js.map +1 -0
- package/dist/adapters/codemirror/lint.d.ts +17 -0
- package/dist/adapters/codemirror/lint.d.ts.map +1 -0
- package/dist/adapters/codemirror/lint.js +62 -0
- package/dist/adapters/codemirror/lint.js.map +1 -0
- package/dist/adapters/codemirror/positions.d.ts +16 -0
- package/dist/adapters/codemirror/positions.d.ts.map +1 -0
- package/dist/adapters/codemirror/positions.js +65 -0
- package/dist/adapters/codemirror/positions.js.map +1 -0
- package/dist/adapters/codemirror/stream.d.ts +23 -0
- package/dist/adapters/codemirror/stream.d.ts.map +1 -0
- package/dist/adapters/codemirror/stream.js +70 -0
- package/dist/adapters/codemirror/stream.js.map +1 -0
- package/dist/adapters/codemirror/tokens.d.ts +44 -0
- package/dist/adapters/codemirror/tokens.d.ts.map +1 -0
- package/dist/adapters/codemirror/tokens.js +34 -0
- package/dist/adapters/codemirror/tokens.js.map +1 -0
- package/dist/adapters/codemirror/tooltips.d.ts +35 -0
- package/dist/adapters/codemirror/tooltips.d.ts.map +1 -0
- package/dist/adapters/codemirror/tooltips.js +108 -0
- package/dist/adapters/codemirror/tooltips.js.map +1 -0
- package/dist/core/accounting/analysis.d.ts +111 -0
- package/dist/core/accounting/analysis.d.ts.map +1 -0
- package/dist/core/accounting/analysis.js +123 -0
- package/dist/core/accounting/analysis.js.map +1 -0
- package/dist/core/accounting/charges.d.ts +136 -0
- package/dist/core/accounting/charges.d.ts.map +1 -0
- package/dist/core/accounting/charges.js +362 -0
- package/dist/core/accounting/charges.js.map +1 -0
- package/dist/core/accounting/equity.d.ts +191 -0
- package/dist/core/accounting/equity.d.ts.map +1 -0
- package/dist/core/accounting/equity.js +167 -0
- package/dist/core/accounting/equity.js.map +1 -0
- package/dist/core/accounting/index.d.ts +46 -0
- package/dist/core/accounting/index.d.ts.map +1 -0
- package/dist/core/accounting/index.js +37 -0
- package/dist/core/accounting/index.js.map +1 -0
- package/dist/core/accounting/markers.d.ts +43 -0
- package/dist/core/accounting/markers.d.ts.map +1 -0
- package/dist/core/accounting/markers.js +64 -0
- package/dist/core/accounting/markers.js.map +1 -0
- package/dist/core/accounting/monthly.d.ts +52 -0
- package/dist/core/accounting/monthly.d.ts.map +1 -0
- package/dist/core/accounting/monthly.js +99 -0
- package/dist/core/accounting/monthly.js.map +1 -0
- package/dist/core/accounting/report.d.ts +41 -0
- package/dist/core/accounting/report.d.ts.map +1 -0
- package/dist/core/accounting/report.js +65 -0
- package/dist/core/accounting/report.js.map +1 -0
- package/dist/core/accounting/shapes.d.ts +70 -0
- package/dist/core/accounting/shapes.d.ts.map +1 -0
- package/dist/core/accounting/shapes.js +21 -0
- package/dist/core/accounting/shapes.js.map +1 -0
- package/dist/core/accounting/statistics.d.ts +87 -0
- package/dist/core/accounting/statistics.d.ts.map +1 -0
- package/dist/core/accounting/statistics.js +268 -0
- package/dist/core/accounting/statistics.js.map +1 -0
- package/dist/core/accounting/trades.d.ts +118 -0
- package/dist/core/accounting/trades.d.ts.map +1 -0
- package/dist/core/accounting/trades.js +186 -0
- package/dist/core/accounting/trades.js.map +1 -0
- package/dist/core/backtest/case.d.ts +60 -0
- package/dist/core/backtest/case.d.ts.map +1 -0
- package/dist/core/backtest/case.js +319 -0
- package/dist/core/backtest/case.js.map +1 -0
- package/dist/core/backtest/compare.d.ts +38 -0
- package/dist/core/backtest/compare.d.ts.map +1 -0
- package/dist/core/backtest/compare.js +191 -0
- package/dist/core/backtest/compare.js.map +1 -0
- package/dist/core/backtest/declaration.d.ts +52 -0
- package/dist/core/backtest/declaration.d.ts.map +1 -0
- package/dist/core/backtest/declaration.js +48 -0
- package/dist/core/backtest/declaration.js.map +1 -0
- package/dist/core/backtest/deliver.d.ts +93 -0
- package/dist/core/backtest/deliver.d.ts.map +1 -0
- package/dist/core/backtest/deliver.js +94 -0
- package/dist/core/backtest/deliver.js.map +1 -0
- package/dist/core/backtest/drive.d.ts +87 -0
- package/dist/core/backtest/drive.d.ts.map +1 -0
- package/dist/core/backtest/drive.js +312 -0
- package/dist/core/backtest/drive.js.map +1 -0
- package/dist/core/backtest/index.d.ts +58 -0
- package/dist/core/backtest/index.d.ts.map +1 -0
- package/dist/core/backtest/index.js +47 -0
- package/dist/core/backtest/index.js.map +1 -0
- package/dist/core/backtest/range.d.ts +84 -0
- package/dist/core/backtest/range.d.ts.map +1 -0
- package/dist/core/backtest/range.js +90 -0
- package/dist/core/backtest/range.js.map +1 -0
- package/dist/core/backtest/record.d.ts +299 -0
- package/dist/core/backtest/record.d.ts.map +1 -0
- package/dist/core/backtest/record.js +243 -0
- package/dist/core/backtest/record.js.map +1 -0
- package/dist/core/backtest/replay.d.ts +48 -0
- package/dist/core/backtest/replay.d.ts.map +1 -0
- package/dist/core/backtest/replay.js +137 -0
- package/dist/core/backtest/replay.js.map +1 -0
- package/dist/core/backtest/resting.d.ts +62 -0
- package/dist/core/backtest/resting.d.ts.map +1 -0
- package/dist/core/backtest/resting.js +59 -0
- package/dist/core/backtest/resting.js.map +1 -0
- package/dist/core/backtest/settings.d.ts +117 -0
- package/dist/core/backtest/settings.d.ts.map +1 -0
- package/dist/core/backtest/settings.js +207 -0
- package/dist/core/backtest/settings.js.map +1 -0
- package/dist/core/backtest/simulate.d.ts +258 -0
- package/dist/core/backtest/simulate.d.ts.map +1 -0
- package/dist/core/backtest/simulate.js +335 -0
- package/dist/core/backtest/simulate.js.map +1 -0
- package/dist/core/catalogue/catalogue.generated.d.ts +66 -0
- package/dist/core/catalogue/catalogue.generated.d.ts.map +1 -1
- package/dist/core/catalogue/catalogue.generated.js +6 -0
- package/dist/core/catalogue/catalogue.generated.js.map +1 -1
- package/dist/core/catalogue/values.generated.d.ts +24 -0
- package/dist/core/catalogue/values.generated.d.ts.map +1 -1
- package/dist/core/check/index.d.ts +2 -1
- package/dist/core/check/index.d.ts.map +1 -1
- package/dist/core/check/index.js +1 -1
- package/dist/core/check/index.js.map +1 -1
- package/dist/core/check/library-orders.js +2 -2
- package/dist/core/check/library-orders.js.map +1 -1
- package/dist/core/check/library-prose.generated.d.ts +16 -0
- package/dist/core/check/library-prose.generated.d.ts.map +1 -0
- package/dist/core/check/library-prose.generated.js +353 -0
- package/dist/core/check/library-prose.generated.js.map +1 -0
- package/dist/core/check/surface.d.ts +24 -0
- package/dist/core/check/surface.d.ts.map +1 -1
- package/dist/core/check/surface.js +29 -0
- package/dist/core/check/surface.js.map +1 -1
- package/dist/core/emit/canonical.d.ts +22 -8
- package/dist/core/emit/canonical.d.ts.map +1 -1
- package/dist/core/emit/canonical.js +67 -6
- package/dist/core/emit/canonical.js.map +1 -1
- package/dist/core/emit/defaults.d.ts +35 -16
- package/dist/core/emit/defaults.d.ts.map +1 -1
- package/dist/core/emit/defaults.js +66 -0
- package/dist/core/emit/defaults.js.map +1 -1
- package/dist/core/emit/index.d.ts +2 -0
- package/dist/core/emit/index.d.ts.map +1 -1
- package/dist/core/emit/index.js +2 -0
- package/dist/core/emit/index.js.map +1 -1
- package/dist/core/engine/arithmetic.d.ts +6 -25
- package/dist/core/engine/arithmetic.d.ts.map +1 -1
- package/dist/core/engine/arithmetic.js +48 -3
- package/dist/core/engine/arithmetic.js.map +1 -1
- package/dist/core/engine/index.d.ts +2 -2
- package/dist/core/engine/index.d.ts.map +1 -1
- package/dist/core/engine/index.js +2 -2
- package/dist/core/engine/index.js.map +1 -1
- package/dist/core/engine/library/arrays.d.ts.map +1 -1
- package/dist/core/engine/library/arrays.js +8 -2
- package/dist/core/engine/library/arrays.js.map +1 -1
- package/dist/core/engine/library/code-points.d.ts +40 -0
- package/dist/core/engine/library/code-points.d.ts.map +1 -0
- package/dist/core/engine/library/code-points.js +74 -0
- package/dist/core/engine/library/code-points.js.map +1 -0
- package/dist/core/engine/library/index.d.ts +5 -0
- package/dist/core/engine/library/index.d.ts.map +1 -1
- package/dist/core/engine/library/index.js +5 -0
- package/dist/core/engine/library/index.js.map +1 -1
- package/dist/core/engine/library/text.d.ts.map +1 -1
- package/dist/core/engine/library/text.js +51 -34
- package/dist/core/engine/library/text.js.map +1 -1
- package/dist/core/engine/load.d.ts +35 -1
- package/dist/core/engine/load.d.ts.map +1 -1
- package/dist/core/engine/load.js +63 -0
- package/dist/core/engine/load.js.map +1 -1
- package/dist/core/engine/verify-tables.d.ts.map +1 -1
- package/dist/core/engine/verify-tables.js +41 -0
- package/dist/core/engine/verify-tables.js.map +1 -1
- package/dist/core/index.d.ts +43 -4
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +23 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/stdlib/index.d.ts +1 -1
- package/dist/core/stdlib/index.d.ts.map +1 -1
- package/dist/core/stdlib/index.js +1 -1
- package/dist/core/stdlib/index.js.map +1 -1
- package/dist/core/stdlib/maths/index.d.ts +1 -1
- package/dist/core/stdlib/maths/index.d.ts.map +1 -1
- package/dist/core/stdlib/maths/index.js +1 -1
- package/dist/core/stdlib/maths/index.js.map +1 -1
- package/dist/core/stdlib/maths/rounding.d.ts +5 -0
- package/dist/core/stdlib/maths/rounding.d.ts.map +1 -1
- package/dist/core/stdlib/maths/rounding.js +19 -1
- package/dist/core/stdlib/maths/rounding.js.map +1 -1
- package/dist/core/version/version.generated.d.ts +1 -1
- package/dist/core/version/version.generated.js +1 -1
- package/dist/editor/complete.d.ts +40 -0
- package/dist/editor/complete.d.ts.map +1 -0
- package/dist/editor/complete.js +206 -0
- package/dist/editor/complete.js.map +1 -0
- package/dist/editor/diagnose.d.ts +18 -0
- package/dist/editor/diagnose.d.ts.map +1 -0
- package/dist/editor/diagnose.js +70 -0
- package/dist/editor/diagnose.js.map +1 -0
- package/dist/editor/format.d.ts +11 -0
- package/dist/editor/format.d.ts.map +1 -0
- package/dist/editor/format.js +50 -0
- package/dist/editor/format.js.map +1 -0
- package/dist/editor/highlight.d.ts +28 -0
- package/dist/editor/highlight.d.ts.map +1 -0
- package/dist/editor/highlight.js +65 -0
- package/dist/editor/highlight.js.map +1 -0
- package/dist/editor/hover.d.ts +40 -0
- package/dist/editor/hover.d.ts.map +1 -0
- package/dist/editor/hover.js +147 -0
- package/dist/editor/hover.js.map +1 -0
- package/dist/editor/index.d.ts +60 -0
- package/dist/editor/index.d.ts.map +1 -0
- package/dist/editor/index.js +7 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/editor/kinds.d.ts +27 -0
- package/dist/editor/kinds.d.ts.map +1 -0
- package/dist/editor/kinds.js +118 -0
- package/dist/editor/kinds.js.map +1 -0
- package/dist/editor/layout.d.ts +47 -0
- package/dist/editor/layout.d.ts.map +1 -0
- package/dist/editor/layout.js +135 -0
- package/dist/editor/layout.js.map +1 -0
- package/dist/editor/manifest.d.ts +47 -0
- package/dist/editor/manifest.d.ts.map +1 -0
- package/dist/editor/manifest.js +93 -0
- package/dist/editor/manifest.js.map +1 -0
- package/dist/editor/reading.d.ts +41 -0
- package/dist/editor/reading.d.ts.map +1 -0
- package/dist/editor/reading.js +51 -0
- package/dist/editor/reading.js.map +1 -0
- package/dist/editor/scan.d.ts +26 -0
- package/dist/editor/scan.d.ts.map +1 -0
- package/dist/editor/scan.js +139 -0
- package/dist/editor/scan.js.map +1 -0
- package/dist/editor/scope.d.ts +19 -0
- package/dist/editor/scope.d.ts.map +1 -0
- package/dist/editor/scope.js +99 -0
- package/dist/editor/scope.js.map +1 -0
- package/dist/editor/signature.d.ts +38 -0
- package/dist/editor/signature.d.ts.map +1 -0
- package/dist/editor/signature.js +112 -0
- package/dist/editor/signature.js.map +1 -0
- package/dist/editor/site.d.ts +46 -0
- package/dist/editor/site.d.ts.map +1 -0
- package/dist/editor/site.js +184 -0
- package/dist/editor/site.js.map +1 -0
- package/dist/editor/spacing.d.ts +29 -0
- package/dist/editor/spacing.d.ts.map +1 -0
- package/dist/editor/spacing.js +116 -0
- package/dist/editor/spacing.js.map +1 -0
- package/package.json +42 -3
- package/spec/README.md +2 -1
- package/spec/errors.json +141 -1
- package/src/adapters/charts/driving.ts +109 -0
- package/src/adapters/charts/run.ts +120 -28
- package/src/adapters/charts/surfaces.ts +17 -0
- package/src/adapters/charts/tables.ts +88 -0
- package/src/adapters/charts/venue.ts +132 -0
- package/src/adapters/codemirror/commands.ts +53 -0
- package/src/adapters/codemirror/completion.ts +74 -0
- package/src/adapters/codemirror/contract.ts +156 -0
- package/src/adapters/codemirror/index.ts +66 -0
- package/src/adapters/codemirror/lint.ts +66 -0
- package/src/adapters/codemirror/positions.ts +79 -0
- package/src/adapters/codemirror/stream.ts +87 -0
- package/src/adapters/codemirror/tokens.ts +64 -0
- package/src/adapters/codemirror/tooltips.ts +113 -0
- package/src/core/accounting/analysis.ts +188 -0
- package/src/core/accounting/charges.ts +452 -0
- package/src/core/accounting/equity.ts +314 -0
- package/src/core/accounting/index.ts +51 -0
- package/src/core/accounting/markers.ts +95 -0
- package/src/core/accounting/monthly.ts +137 -0
- package/src/core/accounting/report.ts +94 -0
- package/src/core/accounting/shapes.ts +73 -0
- package/src/core/accounting/statistics.ts +387 -0
- package/src/core/accounting/trades.ts +313 -0
- package/src/core/backtest/case.ts +395 -0
- package/src/core/backtest/compare.ts +246 -0
- package/src/core/backtest/declaration.ts +97 -0
- package/src/core/backtest/deliver.ts +161 -0
- package/src/core/backtest/drive.ts +468 -0
- package/src/core/backtest/index.ts +64 -0
- package/src/core/backtest/range.ts +137 -0
- package/src/core/backtest/record.ts +470 -0
- package/src/core/backtest/replay.ts +168 -0
- package/src/core/backtest/resting.ts +125 -0
- package/src/core/backtest/settings.ts +280 -0
- package/src/core/backtest/simulate.ts +499 -0
- package/src/core/catalogue/catalogue.generated.ts +6 -0
- package/src/core/catalogue/values.generated.ts +6 -0
- package/src/core/check/index.ts +3 -0
- package/src/core/check/library-orders.ts +2 -2
- package/src/core/check/library-prose.generated.ts +367 -0
- package/src/core/check/surface.ts +34 -0
- package/src/core/emit/canonical.ts +67 -9
- package/src/core/emit/defaults.ts +70 -0
- package/src/core/emit/index.ts +2 -0
- package/src/core/engine/arithmetic.ts +23 -3
- package/src/core/engine/index.ts +2 -2
- package/src/core/engine/library/arrays.ts +8 -2
- package/src/core/engine/library/code-points.ts +73 -0
- package/src/core/engine/library/index.ts +6 -0
- package/src/core/engine/library/text.ts +53 -35
- package/src/core/engine/load.ts +84 -2
- package/src/core/engine/verify-tables.ts +43 -0
- package/src/core/index.ts +100 -2
- package/src/core/stdlib/index.ts +1 -0
- package/src/core/stdlib/maths/index.ts +1 -0
- package/src/core/stdlib/maths/rounding.ts +23 -1
- package/src/core/version/version.generated.ts +1 -1
- package/src/editor/complete.ts +266 -0
- package/src/editor/diagnose.ts +71 -0
- package/src/editor/format.ts +85 -0
- package/src/editor/highlight.ts +110 -0
- package/src/editor/hover.ts +199 -0
- package/src/editor/index.ts +65 -0
- package/src/editor/kinds.ts +157 -0
- package/src/editor/layout.ts +189 -0
- package/src/editor/manifest.ts +119 -0
- package/src/editor/reading.ts +69 -0
- package/src/editor/scan.ts +162 -0
- package/src/editor/scope.ts +122 -0
- package/src/editor/signature.ts +150 -0
- package/src/editor/site.ts +233 -0
- package/src/editor/spacing.ts +132 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a fill costs, as an ordered list of lines the platform brings.
|
|
3
|
+
*
|
|
4
|
+
* **The language has three commission spellings and a slippage in ticks, and a
|
|
5
|
+
* real cost stack is not shaped like that.** It is a flat fee, a percentage, a
|
|
6
|
+
* charge levied on a charge, and a tax that applies to one side of the trade
|
|
7
|
+
* only. Teaching the language one market's stack would be teaching it a market;
|
|
8
|
+
* so the platform passes a schedule instead, and the language keeps the three
|
|
9
|
+
* spellings it has, which turn into a schedule of one line.
|
|
10
|
+
*
|
|
11
|
+
* **Order is part of the result.** The lines are applied in the order they are
|
|
12
|
+
* declared, a line charged on other lines may only name lines declared before
|
|
13
|
+
* it, and that is what makes a schedule evaluable in exactly one order. Two
|
|
14
|
+
* engines that disagree about the order disagree about the money, and a
|
|
15
|
+
* disagreement in the last bit is still a failed conformance comparison
|
|
16
|
+
* (`conformance.md` 6).
|
|
17
|
+
*
|
|
18
|
+
* **Where it is applied is not here.** `stdlib.md` 17.1 puts slippage and
|
|
19
|
+
* commission on the destination: the engine folds the price it is told and
|
|
20
|
+
* never adjusts one, so a cost model inside the ledger would be the engine
|
|
21
|
+
* moving a price, which is the one thing the invariant forbids. This module
|
|
22
|
+
* says what a charge is and works out what one fill came to; the destination is
|
|
23
|
+
* what charges it, and the slippage a schedule carries is measured and applied
|
|
24
|
+
* there, against the tick size this module only refuses the absence of.
|
|
25
|
+
*
|
|
26
|
+
* **What is charged to a fill, and only to a fill.** Every line is measured
|
|
27
|
+
* against this fill and nothing else, so a tier that changes with the month's
|
|
28
|
+
* cumulative volume, a cap counted per day rather than per application, and
|
|
29
|
+
* margin and its interest are outside this model rather than approximated
|
|
30
|
+
* inside it. A cost model that quietly approximates is a report that is wrong
|
|
31
|
+
* in the strategy's favour and says nothing about it.
|
|
32
|
+
*/
|
|
33
|
+
import { diagnosticFor } from '../diagnostics/index.js';
|
|
34
|
+
/**
|
|
35
|
+
* The most digits money is rounded to, and why there is a ceiling at all.
|
|
36
|
+
*
|
|
37
|
+
* A rounding scale is a power of ten and a binary64 holds about fifteen
|
|
38
|
+
* significant decimal digits, so past this the scale itself is approximate and
|
|
39
|
+
* the rounding stops being arithmetic and becomes noise. A currency with more
|
|
40
|
+
* than fifteen decimal places is not a currency this module is refusing to
|
|
41
|
+
* support; it is a digit count nobody stated on purpose.
|
|
42
|
+
*/
|
|
43
|
+
const MAX_DIGITS = 15;
|
|
44
|
+
/** A percentage, as the declaration states one, over the fraction a rate is. */
|
|
45
|
+
const PERCENT = 100;
|
|
46
|
+
/** What a refusal calls the setting it is about, `errors.md` OS6021. */
|
|
47
|
+
const SETTING = 'The charge schedule';
|
|
48
|
+
/**
|
|
49
|
+
* Where a refusal about a setting points.
|
|
50
|
+
*
|
|
51
|
+
* Nowhere in the script, because a schedule is not something anybody wrote in
|
|
52
|
+
* one: it is what the host stated before the first bar, and a caret drawn under
|
|
53
|
+
* a line of the strategy would blame the one party who did not choose it. The
|
|
54
|
+
* engine gives a load-time failure the same position for the same reason, and
|
|
55
|
+
* the number is written here rather than imported from it because this module
|
|
56
|
+
* imports no engine, which is what lets a stored record be reported again with
|
|
57
|
+
* no engine present.
|
|
58
|
+
*/
|
|
59
|
+
const NO_POSITION = { offset: 0, length: 0, line: 0, column: 0 };
|
|
60
|
+
/**
|
|
61
|
+
* What one fill cost, line by line and in total.
|
|
62
|
+
*
|
|
63
|
+
* **The lines are the arithmetic and the total is the money.** Each line's
|
|
64
|
+
* amount is computed in binary64 and left unrounded, and the per-fill total is
|
|
65
|
+
* rounded once, half to even, to the contract's digits. Rounding each line
|
|
66
|
+
* would round once per line, and two engines rounding in two places disagree in
|
|
67
|
+
* the last bit, which is a failed conformance comparison months later on
|
|
68
|
+
* somebody else's engine. So a reader adding the lines up by hand may land a
|
|
69
|
+
* fraction of the last digit away from the total, and that is the honest way
|
|
70
|
+
* round: the total is the figure the report accumulates.
|
|
71
|
+
*
|
|
72
|
+
* **Half to even, and not the language's own rounding.** `round()` in the
|
|
73
|
+
* language is halves away from zero, because a price a trader reads should
|
|
74
|
+
* agree with what they would write down (`stdlib.md` 8.1). Money folded over
|
|
75
|
+
* thousands of fills is a different question: away from zero biases every exact
|
|
76
|
+
* half upward, and half a unit of the last digit per fill is a bias that grows
|
|
77
|
+
* with the length of the backtest. Two rules, two reasons, both written down.
|
|
78
|
+
*
|
|
79
|
+
* **A line that does not apply to this side is not in the breakdown at all.** A
|
|
80
|
+
* name beside a zero reads as a charge that was levied and came to nothing,
|
|
81
|
+
* which is not what happened, and a later line levied on that name is levied on
|
|
82
|
+
* nothing, which is exactly what a tax on one side of the trade does.
|
|
83
|
+
*/
|
|
84
|
+
export function chargeFor(schedule, fill, contract) {
|
|
85
|
+
const turnover = fill.units * fill.price * contract.pointValue;
|
|
86
|
+
const applied = [];
|
|
87
|
+
for (const line of schedule.lines) {
|
|
88
|
+
if (line.side !== 'both' && line.side !== fill.side)
|
|
89
|
+
continue;
|
|
90
|
+
const base = baseOf(line, turnover, fill.units, applied);
|
|
91
|
+
applied.push({ name: line.name, amount: bounded(line.rate * base, line) });
|
|
92
|
+
}
|
|
93
|
+
let exact = 0;
|
|
94
|
+
for (const one of applied)
|
|
95
|
+
exact += one.amount;
|
|
96
|
+
return { lines: applied, total: roundMoney(exact, contract.digits) };
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* What a line's rate is measured against, for this fill.
|
|
100
|
+
*
|
|
101
|
+
* The earlier lines are searched rather than indexed. An index would be a map,
|
|
102
|
+
* and this module has promised to depend on no map's iteration order; a
|
|
103
|
+
* schedule is a handful of lines, so the search costs nothing and the promise
|
|
104
|
+
* costs one less thing to be careful about.
|
|
105
|
+
*/
|
|
106
|
+
function baseOf(line, turnover, units, applied) {
|
|
107
|
+
if (line.base === 'turnover')
|
|
108
|
+
return turnover;
|
|
109
|
+
if (line.base === 'units')
|
|
110
|
+
return units;
|
|
111
|
+
if (line.base === 'order')
|
|
112
|
+
return 1;
|
|
113
|
+
// 'charges': the sum of the named earlier lines, as they were charged on this
|
|
114
|
+
// fill. A name whose line did not apply to this side is absent and adds
|
|
115
|
+
// nothing, which is a charge levied on a charge that was never taken.
|
|
116
|
+
let sum = 0;
|
|
117
|
+
for (const named of line.of) {
|
|
118
|
+
for (const one of applied) {
|
|
119
|
+
if (one.name === named)
|
|
120
|
+
sum += one.amount;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return sum;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* The floor and the cap, per application.
|
|
127
|
+
*
|
|
128
|
+
* Both together is the common brokerage plan: a fraction of turnover, never
|
|
129
|
+
* less than one amount and never more than another. Which is applied first does
|
|
130
|
+
* not decide the answer, because a floor above a cap is refused before the
|
|
131
|
+
* first bar rather than resolved here by whichever comparison runs first.
|
|
132
|
+
*/
|
|
133
|
+
function bounded(raw, line) {
|
|
134
|
+
let amount = raw;
|
|
135
|
+
if (line.min !== null && amount < line.min)
|
|
136
|
+
amount = line.min;
|
|
137
|
+
if (line.max !== null && amount > line.max)
|
|
138
|
+
amount = line.max;
|
|
139
|
+
return amount;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* One money figure, rounded once, halves to even.
|
|
143
|
+
*
|
|
144
|
+
* A digit count this cannot round by is one `scheduleProblem` refuses before
|
|
145
|
+
* the first bar. If one arrives anyway the amount is returned as it stands,
|
|
146
|
+
* because a scale of ten to the power of something impossible turns money into
|
|
147
|
+
* a number JSON carries as null, and an unrounded figure is worth more.
|
|
148
|
+
*/
|
|
149
|
+
function roundMoney(amount, digits) {
|
|
150
|
+
if (!Number.isFinite(amount))
|
|
151
|
+
return amount;
|
|
152
|
+
if (!Number.isInteger(digits) || digits < 0 || digits > MAX_DIGITS)
|
|
153
|
+
return amount;
|
|
154
|
+
const scale = 10 ** digits;
|
|
155
|
+
const scaled = amount * scale;
|
|
156
|
+
const below = Math.floor(scaled);
|
|
157
|
+
const fraction = scaled - below;
|
|
158
|
+
let whole = below;
|
|
159
|
+
if (fraction > 0.5)
|
|
160
|
+
whole = below + 1;
|
|
161
|
+
else if (fraction === 0.5 && below % 2 !== 0)
|
|
162
|
+
whole = below + 1;
|
|
163
|
+
const money = whole / scale;
|
|
164
|
+
// A negative zero is the same money as a zero and a different set of bytes.
|
|
165
|
+
return money === 0 ? 0 : money;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* The declaration's own cost model, as the one schedule this module evaluates.
|
|
169
|
+
*
|
|
170
|
+
* **The declaration is not a second cost engine.** Its three commission
|
|
171
|
+
* spellings are a schedule of one line: a flat fee is a line charged per fill,
|
|
172
|
+
* a per unit fee is a line charged per unit, and a percentage is a line charged
|
|
173
|
+
* on turnover. A second evaluator for the declaration would be the same money
|
|
174
|
+
* computed two ways, and the day the two disagreed the report and the
|
|
175
|
+
* platform's own cost panel would both be defensible.
|
|
176
|
+
*
|
|
177
|
+
* **A commission of zero is no line at all**, rather than a line charging
|
|
178
|
+
* nothing. A zero line would put a name in every breakdown, and it would make a
|
|
179
|
+
* declaration that states no commission indistinguishable from one that states
|
|
180
|
+
* a commission, which is the distinction a run has to make before it accepts a
|
|
181
|
+
* schedule from the host as well.
|
|
182
|
+
*
|
|
183
|
+
* **A flat fee is charged per fill**, which is the one place `language.md` 13.3
|
|
184
|
+
* lets a reasonable person read the words two ways: per order, or per completed
|
|
185
|
+
* round trip. A charge is attributed to the fill that incurred it everywhere in
|
|
186
|
+
* this module, because that is what attributes it to a trade, so a round trip of
|
|
187
|
+
* two fills is charged twice.
|
|
188
|
+
*
|
|
189
|
+
* The currency and the digit count are parameters because neither is the
|
|
190
|
+
* declaration's to state: the declaration's currency is a label and is often
|
|
191
|
+
* left blank, and money rounding is a fact about the contract. A default here
|
|
192
|
+
* would be this module inventing a rounding rule for somebody else's market.
|
|
193
|
+
*
|
|
194
|
+
* `commissionType`'s value set is declared once, in `check/declaration.ts`, and
|
|
195
|
+
* is not restated here: what is below is a mapping from each spelling to the
|
|
196
|
+
* line it means. A program reaching this has been checked, so a fourth spelling
|
|
197
|
+
* cannot arrive, and the spelling that falls through is the declaration's own
|
|
198
|
+
* default rather than a shape this module made up.
|
|
199
|
+
*/
|
|
200
|
+
export function scheduleFromDeclaration(commission, commissionType, slippage, currency, digits) {
|
|
201
|
+
return {
|
|
202
|
+
currency,
|
|
203
|
+
digits,
|
|
204
|
+
slippageTicks: slippage,
|
|
205
|
+
lines: commission === 0 ? [] : [commissionLine(commission, commissionType)],
|
|
206
|
+
source: 'declaration',
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
/** The one line a declared commission is, in the base its spelling names. */
|
|
210
|
+
function commissionLine(commission, commissionType) {
|
|
211
|
+
if (commissionType === 'perUnit')
|
|
212
|
+
return only('units', commission);
|
|
213
|
+
if (commissionType === 'percent')
|
|
214
|
+
return only('turnover', commission / PERCENT);
|
|
215
|
+
return only('order', commission);
|
|
216
|
+
}
|
|
217
|
+
/** A line with no bounds, on both sides, levied on nothing: the declaration's shape. */
|
|
218
|
+
function only(base, rate) {
|
|
219
|
+
return { name: 'commission', base, side: 'both', rate, min: null, max: null, of: [] };
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Why this schedule cannot be carried out, or null.
|
|
223
|
+
*
|
|
224
|
+
* **Asked before the first bar, and answered once.** Everything here is a fact
|
|
225
|
+
* about the schedule rather than about any fill, so a run that would produce a
|
|
226
|
+
* number nobody can explain is refused while nothing has been computed and the
|
|
227
|
+
* cost of correcting it is one run. The contract is optional because a schedule
|
|
228
|
+
* is checkable on its own: what it adds is the three questions that need both,
|
|
229
|
+
* which are the currency the money is in, the digits it is rounded to, and the
|
|
230
|
+
* tick a slippage in ticks is measured in.
|
|
231
|
+
*
|
|
232
|
+
* The first problem found is the one reported. A list of everything wrong with
|
|
233
|
+
* a schedule reads as a worse schedule than it is, and it is corrected one line
|
|
234
|
+
* at a time regardless.
|
|
235
|
+
*/
|
|
236
|
+
export function scheduleProblem(schedule, contract = null) {
|
|
237
|
+
const problem = moneyProblem(schedule, contract) ??
|
|
238
|
+
slippageProblem(schedule, contract) ??
|
|
239
|
+
linesProblem(schedule.lines);
|
|
240
|
+
if (problem === null)
|
|
241
|
+
return null;
|
|
242
|
+
return diagnosticFor('OS6021', NO_POSITION, { setting: SETTING, problem });
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* The currency the money is in and the digits it is rounded to.
|
|
246
|
+
*
|
|
247
|
+
* A schedule states both and so does the contract, and the two are compared
|
|
248
|
+
* here rather than one of them being quietly preferred. A schedule in another
|
|
249
|
+
* currency charges a fill in money the contract is not priced in, and a total
|
|
250
|
+
* nobody can add to the profit is worse than no total. A schedule rounding to
|
|
251
|
+
* other digits is the same fact stated twice and left to disagree.
|
|
252
|
+
*/
|
|
253
|
+
function moneyProblem(schedule, contract) {
|
|
254
|
+
const digits = schedule.digits;
|
|
255
|
+
if (!Number.isInteger(digits) || digits < 0 || digits > MAX_DIGITS) {
|
|
256
|
+
return `it rounds money to ${digits} digits, and a digit count is a whole number from 0 to ${MAX_DIGITS}`;
|
|
257
|
+
}
|
|
258
|
+
if (schedule.currency.trim() === '') {
|
|
259
|
+
return 'it names no currency, so what it charges is a number with no unit on it';
|
|
260
|
+
}
|
|
261
|
+
if (contract === null)
|
|
262
|
+
return null;
|
|
263
|
+
if (schedule.currency !== contract.currency) {
|
|
264
|
+
return `it charges in ${schedule.currency} and the contract is priced in ${contract.currency}`;
|
|
265
|
+
}
|
|
266
|
+
if (digits !== contract.digits) {
|
|
267
|
+
return `it rounds money to ${digits} digits and the contract rounds to ${contract.digits}`;
|
|
268
|
+
}
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* The slippage, which this module refuses and does not apply.
|
|
273
|
+
*
|
|
274
|
+
* A slippage in ticks with no tick size to measure a tick in would charge
|
|
275
|
+
* nothing at all, and a backtest that silently charges nothing is one that lies
|
|
276
|
+
* in the strategy's favour. It is refused here, where the schedule is checked,
|
|
277
|
+
* rather than at the fill, where a zero looks like a cost model that ran.
|
|
278
|
+
*/
|
|
279
|
+
function slippageProblem(schedule, contract) {
|
|
280
|
+
const ticks = schedule.slippageTicks;
|
|
281
|
+
if (!Number.isFinite(ticks) || ticks < 0) {
|
|
282
|
+
return `it states ${ticks} ticks of slippage, and slippage is adverse, so it is never negative`;
|
|
283
|
+
}
|
|
284
|
+
if (ticks === 0 || contract === null)
|
|
285
|
+
return null;
|
|
286
|
+
const tick = contract.tickSize;
|
|
287
|
+
if (tick === null || !(tick > 0)) {
|
|
288
|
+
return `it states ${ticks} ticks of slippage and the contract has no tick size to measure a tick in`;
|
|
289
|
+
}
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
/** Every line, in the order the schedule declares them, against the ones before it. */
|
|
293
|
+
function linesProblem(lines) {
|
|
294
|
+
const declared = [];
|
|
295
|
+
for (const line of lines) {
|
|
296
|
+
const problem = lineProblem(line, declared);
|
|
297
|
+
if (problem !== null)
|
|
298
|
+
return problem;
|
|
299
|
+
declared.push(line.name);
|
|
300
|
+
}
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
/** One line, against the names declared before it. */
|
|
304
|
+
function lineProblem(line, declared) {
|
|
305
|
+
const name = line.name;
|
|
306
|
+
if (name.trim() === '') {
|
|
307
|
+
return 'a line carries no name, and a line levied on charges names the lines it is levied on';
|
|
308
|
+
}
|
|
309
|
+
if (declared.includes(name)) {
|
|
310
|
+
return `two lines are named "${name}", so a line levied on that name is levied on two answers`;
|
|
311
|
+
}
|
|
312
|
+
if (!Number.isFinite(line.rate) || line.rate < 0) {
|
|
313
|
+
return `the line "${name}" charges a rate of ${line.rate}, and a charge is money taken, never given`;
|
|
314
|
+
}
|
|
315
|
+
return boundProblem(line) ?? levyProblem(line, declared);
|
|
316
|
+
}
|
|
317
|
+
/** The floor and the cap: money, not negative, and the floor no higher than the cap. */
|
|
318
|
+
function boundProblem(line) {
|
|
319
|
+
const { max, min, name } = line;
|
|
320
|
+
if (min !== null && (!Number.isFinite(min) || min < 0)) {
|
|
321
|
+
return `the line "${name}" has a floor of ${min}, and a bound on a charge is money`;
|
|
322
|
+
}
|
|
323
|
+
if (max !== null && (!Number.isFinite(max) || max < 0)) {
|
|
324
|
+
return `the line "${name}" has a cap of ${max}, and a bound on a charge is money`;
|
|
325
|
+
}
|
|
326
|
+
if (min !== null && max !== null && min > max) {
|
|
327
|
+
return `the line "${name}" has a floor of ${min} above its cap of ${max}`;
|
|
328
|
+
}
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* What a line is levied on, which is the rule the whole ordering exists for.
|
|
333
|
+
*
|
|
334
|
+
* A line levied on lines not declared before it has no single evaluation order,
|
|
335
|
+
* so two engines would charge two different amounts and both would be
|
|
336
|
+
* defensible. Naming itself, naming a line declared after it and naming a line
|
|
337
|
+
* that is not in the schedule at all are one problem in three spellings, and
|
|
338
|
+
* they are reported as one: none of the three is declared before this line.
|
|
339
|
+
*/
|
|
340
|
+
function levyProblem(line, declared) {
|
|
341
|
+
const name = line.name;
|
|
342
|
+
if (line.base !== 'charges') {
|
|
343
|
+
if (line.of.length === 0)
|
|
344
|
+
return null;
|
|
345
|
+
return `the line "${name}" names ${line.of.length} lines to be levied on and its base is ${line.base}, so the names are read by nothing`;
|
|
346
|
+
}
|
|
347
|
+
if (line.of.length === 0) {
|
|
348
|
+
return `the line "${name}" is levied on charges and names none, so it is levied on nothing`;
|
|
349
|
+
}
|
|
350
|
+
const seen = [];
|
|
351
|
+
for (const named of line.of) {
|
|
352
|
+
if (!declared.includes(named)) {
|
|
353
|
+
return `the line "${name}" is levied on "${named}", which is not declared before it`;
|
|
354
|
+
}
|
|
355
|
+
if (seen.includes(named)) {
|
|
356
|
+
return `the line "${name}" is levied on "${named}" twice, so that line is charged on twice over`;
|
|
357
|
+
}
|
|
358
|
+
seen.push(named);
|
|
359
|
+
}
|
|
360
|
+
return null;
|
|
361
|
+
}
|
|
362
|
+
//# sourceMappingURL=charges.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"charges.js","sourceRoot":"","sources":["../../../src/core/accounting/charges.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The equity curve: one point per bar in the report window.
|
|
3
|
+
*
|
|
4
|
+
* **Marked to the close and to nothing else.** An intrabar extreme is a price
|
|
5
|
+
* the strategy could not have acted on, so it is not a profit it had, and a
|
|
6
|
+
* curve drawn through the extremes flatters every run that ever held a losing
|
|
7
|
+
* position. Where a bar's close is absent the previous mark carries and the
|
|
8
|
+
* point says so, rather than a zero a reader would compare against.
|
|
9
|
+
*
|
|
10
|
+
* **Drawdown is stated on equity including open profit**, and the basis is
|
|
11
|
+
* carried on every point rather than left to the reader: `drawdown` is the
|
|
12
|
+
* distance below the running peak, zero or negative, and `drawdownPercent` is
|
|
13
|
+
* that distance against the peak. A report whose drawdown basis is not written
|
|
14
|
+
* down is a report whose worst figure means a different thing to each reader.
|
|
15
|
+
*
|
|
16
|
+
* ## What the curve is folded from, and when each figure lands
|
|
17
|
+
*
|
|
18
|
+
* A trade list and a list of bar closes, and nothing else. A trade carries its
|
|
19
|
+
* own gross, its own charges and the two bars it lived between, so the fold is
|
|
20
|
+
* a sweep: bars in the order they arrived, trades in the order they opened.
|
|
21
|
+
*
|
|
22
|
+
* - **A trade's charges land on the bar it opened.** The trade list does not
|
|
23
|
+
* carry the timing of the individual fills underneath it, so the cost has to
|
|
24
|
+
* land somewhere, and the open is the one place that is never later than the
|
|
25
|
+
* truth: an entry charge is paid the moment the trade is taken on, and an
|
|
26
|
+
* exit charge cannot be paid before it. The alternative, landing the whole
|
|
27
|
+
* cost at the close, shows a run carrying a position for two hundred bars as
|
|
28
|
+
* having paid nothing for it, and leaves a trade that never closed paying
|
|
29
|
+
* nothing at all.
|
|
30
|
+
* - **A trade's gross lands on the bar it closed**, because that is the bar it
|
|
31
|
+
* stopped being an opinion and became a number. While it is open it is in
|
|
32
|
+
* `openProfit` instead, marked to the close, and the two never overlap.
|
|
33
|
+
*
|
|
34
|
+
* So the last point of a full run carries every charge the run paid, open
|
|
35
|
+
* trades included, and every gross it realised, which is an identity the
|
|
36
|
+
* summary is asserted against rather than assumed to share.
|
|
37
|
+
*
|
|
38
|
+
* ## What a trade list cannot say, said here rather than discovered later
|
|
39
|
+
*
|
|
40
|
+
* A trade holds one entry price weighted over its entry fills and one exit
|
|
41
|
+
* price weighted over its exit fills, so a trade whose size changed while it
|
|
42
|
+
* was open is not visible in it: the size a trade held between its open and its
|
|
43
|
+
* close is the size it ended up entering, at the average price it ended up
|
|
44
|
+
* entering at. Both directions are wrong and they are wrong differently.
|
|
45
|
+
*
|
|
46
|
+
* - **A partial close** is marked at the full size from the bar the reduction
|
|
47
|
+
* settled on, so the open profit of the part already closed is counted twice
|
|
48
|
+
* over, once here and once in the realised total.
|
|
49
|
+
* - **A scale-in is the worse of the two**, because it is wrong from the
|
|
50
|
+
* beginning rather than from the middle. A trade that buys a hundred at ten
|
|
51
|
+
* and another hundred at twenty is marked, from the bar it first opened, as
|
|
52
|
+
* two hundred units bought at fifteen. On the bars before the second entry it
|
|
53
|
+
* is therefore marked five points under water on units it did not hold, and
|
|
54
|
+
* the curve reports a drawdown the account never had. The summary's
|
|
55
|
+
* `maxDrawdown` and `maxDrawdownPercent` are folded from this curve, so a
|
|
56
|
+
* pyramiding strategy is reported as having risked more than it did.
|
|
57
|
+
*
|
|
58
|
+
* Neither reaches the realised total, which is folded from the fills: what is
|
|
59
|
+
* affected is `openProfit`, `exposure`, `equity` and every drawdown figure
|
|
60
|
+
* taken off the curve, on the bars a trade's size was not what it ended as.
|
|
61
|
+
*
|
|
62
|
+
* A curve folded from the fills rather than from the trades would have neither,
|
|
63
|
+
* and that is what fixes it: it needs each entry, exit and charge to land on
|
|
64
|
+
* the bar it settled on, which is a different fold from this one rather than a
|
|
65
|
+
* correction to it. It is written here because a limitation nobody wrote down
|
|
66
|
+
* is a limitation somebody finds inside a report they had already believed.
|
|
67
|
+
*
|
|
68
|
+
* ## Two preconditions, both of them the caller's
|
|
69
|
+
*
|
|
70
|
+
* The trades arrive in the order they opened, which is the order `Trade.index`
|
|
71
|
+
* states, and the bars arrive in the order they were loaded. Both are swept
|
|
72
|
+
* with a pointer rather than searched, because a report over fifty thousand
|
|
73
|
+
* bars that rescans its trade list on every one of them is a report nobody
|
|
74
|
+
* waits for.
|
|
75
|
+
*
|
|
76
|
+
* ## And a percentage here is a fraction of its basis
|
|
77
|
+
*
|
|
78
|
+
* `drawdownPercent` is `drawdown / runningPeak`, which is a fraction: a
|
|
79
|
+
* hundredth of a percent down is written `-0.0001` and not `-0.01`. One
|
|
80
|
+
* convention for every figure in this module that divides, because two figures
|
|
81
|
+
* spelled the same way in two units is a number a reader gets wrong once and
|
|
82
|
+
* never trusts again. The multiplication by a hundred belongs to whatever
|
|
83
|
+
* prints it.
|
|
84
|
+
*/
|
|
85
|
+
import type { BarMark, Contract, Money } from './shapes.js';
|
|
86
|
+
import type { Trade } from './trades.js';
|
|
87
|
+
/** One report bar's standing, folded from the fills settled up to it. */
|
|
88
|
+
export interface EquityPoint {
|
|
89
|
+
readonly barIndex: number;
|
|
90
|
+
readonly time: number | null;
|
|
91
|
+
/** Cumulative gross of closed trades. */
|
|
92
|
+
readonly realised: Money;
|
|
93
|
+
/** Cumulative. */
|
|
94
|
+
readonly charges: Money;
|
|
95
|
+
/** Marked to this bar's close. */
|
|
96
|
+
readonly openProfit: Money;
|
|
97
|
+
/** capital + realised - charges. */
|
|
98
|
+
readonly cash: Money;
|
|
99
|
+
/** cash + openProfit. */
|
|
100
|
+
readonly equity: Money;
|
|
101
|
+
/** The open position's magnitude at this close. */
|
|
102
|
+
readonly exposure: Money;
|
|
103
|
+
/** equity - runningPeak, zero or negative. */
|
|
104
|
+
readonly drawdown: Money;
|
|
105
|
+
/** `drawdown / runningPeak`, a fraction and not a figure times a hundred. */
|
|
106
|
+
readonly drawdownPercent: number;
|
|
107
|
+
/**
|
|
108
|
+
* The distance above the running trough, zero or positive.
|
|
109
|
+
*
|
|
110
|
+
* Drawdown's mirror, and carried for the same reason drawdown is: it is the
|
|
111
|
+
* run's best stretch measured the same way its worst one is, so the two can
|
|
112
|
+
* be read against each other. A reader handed only the depth learns how bad
|
|
113
|
+
* it got and nothing about whether the run ever climbed far enough for that
|
|
114
|
+
* depth to be a giving back rather than a steady bleed.
|
|
115
|
+
*/
|
|
116
|
+
readonly runUp: Money;
|
|
117
|
+
/**
|
|
118
|
+
* `runUp / runningTrough`, a fraction and not a figure times a hundred, and
|
|
119
|
+
* zero where the trough is not above zero.
|
|
120
|
+
*
|
|
121
|
+
* Not the same guard drawdown gets, because the two bases are not the same
|
|
122
|
+
* kind of number. The running peak starts at the capital and only ever rises,
|
|
123
|
+
* so a run with capital above zero has a peak above zero at every point. The
|
|
124
|
+
* running trough starts there and only ever falls, so an account that lost
|
|
125
|
+
* everything has a trough at or below zero, and from that bar on this figure
|
|
126
|
+
* is zero rather than a fraction. Zero is the wrong answer for a run that
|
|
127
|
+
* recovered, and it is reported anyway, because the alternative is a
|
|
128
|
+
* percentage against a negative basis: a positive climb reported as a
|
|
129
|
+
* negative fraction, which is the shape that once gave a profit factor of
|
|
130
|
+
* minus a half. `runUp` itself is unaffected and stays the figure to read on
|
|
131
|
+
* such a run.
|
|
132
|
+
*/
|
|
133
|
+
readonly runUpPercent: number;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Whether this trade was still held at the close of this bar.
|
|
137
|
+
*
|
|
138
|
+
* The boundaries are the whole of the rule and both are decisions. A trade is
|
|
139
|
+
* held from the close of the bar it opened on, because an entry that settled
|
|
140
|
+
* during a bar is a position that bar ended holding. It is not held at the
|
|
141
|
+
* close of the bar it closed on, because that bar ended flat. So a trade
|
|
142
|
+
* opened and closed inside one bar is held at no close at all, which is what a
|
|
143
|
+
* run that was flat at every mark should report.
|
|
144
|
+
*
|
|
145
|
+
* Every figure in this module that asks which trades are open asks it here, so
|
|
146
|
+
* the curve, the exposure and the count of bars in the market cannot come to
|
|
147
|
+
* three different answers about one bar.
|
|
148
|
+
*/
|
|
149
|
+
export declare function openOnBar(trade: Trade, barIndex: number): boolean;
|
|
150
|
+
/**
|
|
151
|
+
* A ratio against a basis that may not be there to divide by.
|
|
152
|
+
*
|
|
153
|
+
* Capital of zero and a peak of zero are both reachable, and both turn an
|
|
154
|
+
* honest division into a value JSON cannot carry: a report whose worst figure
|
|
155
|
+
* comes back `null` from a round trip is worse than one that says zero. A basis
|
|
156
|
+
* that is not positive has no ratio to state, so the figure beside it, which is
|
|
157
|
+
* money and is always true, is the one a reader is left with.
|
|
158
|
+
*/
|
|
159
|
+
export declare function ratioOf(value: number, basis: number): number;
|
|
160
|
+
/**
|
|
161
|
+
* The curve, one point per report bar, in the order the bars arrived.
|
|
162
|
+
*
|
|
163
|
+
* Warmup bars are swept and not reported: their orders were real, so a trade
|
|
164
|
+
* opened during the warmup is already in the fold at the first point, with its
|
|
165
|
+
* charges already paid and its position already marked. A curve that began its
|
|
166
|
+
* fold at the first report bar would lose both, and would lose them silently.
|
|
167
|
+
*
|
|
168
|
+
* The running peak starts at the capital rather than at the first point, so a
|
|
169
|
+
* run that is down from its first bar is in drawdown at its first bar. Starting
|
|
170
|
+
* it at the first point would report every run as having begun at its high.
|
|
171
|
+
*
|
|
172
|
+
* The running trough starts at the capital for the same reason and not for a
|
|
173
|
+
* symmetrical one: a run that is up from its first bar has run up from the
|
|
174
|
+
* money it was given, which is the figure a reader is measuring against. Anchor
|
|
175
|
+
* it at the first point instead and a run that gapped up on bar zero reports
|
|
176
|
+
* that gain as having come from nowhere.
|
|
177
|
+
*/
|
|
178
|
+
export declare function equityOver(trades: readonly Trade[], marks: readonly BarMark[], contract: Contract, capital: Money): readonly EquityPoint[];
|
|
179
|
+
/**
|
|
180
|
+
* How many of these bars ended with something held.
|
|
181
|
+
*
|
|
182
|
+
* Swept rather than searched: a sorted list of the bars trades opened on, a
|
|
183
|
+
* sorted list of the bars they closed on, and the running difference between
|
|
184
|
+
* how many of each have gone by. That is the boundary rule `openOnBar` states,
|
|
185
|
+
* arrived at from the other side, and the two are asserted to agree over a
|
|
186
|
+
* generated corpus rather than trusted to. A count that disagrees with the
|
|
187
|
+
* curve beside it about which bars were in the market is exactly the kind of
|
|
188
|
+
* defect a reader finds by adding two of the printed figures up.
|
|
189
|
+
*/
|
|
190
|
+
export declare function barsInMarketOver(trades: readonly Trade[], equity: readonly EquityPoint[]): number;
|
|
191
|
+
//# sourceMappingURL=equity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"equity.d.ts","sourceRoot":"","sources":["../../../src/core/accounting/equity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,yEAAyE;AACzE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,yCAAyC;IACzC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IACzB,kBAAkB;IAClB,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IACxB,kCAAkC;IAClC,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,yBAAyB;IACzB,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IACvB,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IACzB,8CAA8C;IAC9C,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IACzB,6EAA6E;IAC7E,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,KAAK,EAAE,EACxB,KAAK,EAAE,SAAS,OAAO,EAAE,EACzB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,KAAK,GACb,SAAS,WAAW,EAAE,CAyExB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,KAAK,EAAE,EACxB,MAAM,EAAE,SAAS,WAAW,EAAE,GAC7B,MAAM,CAuBR"}
|