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,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The destination a backtest runs against: intents in, frames out.
|
|
3
|
+
*
|
|
4
|
+
* **This is a host, not part of the engine**, and the division is the one thing
|
|
5
|
+
* to keep straight while reading it. `stdlib.md` 17.1 puts slippage and
|
|
6
|
+
* commission on the destination: the engine folds the price it is told and
|
|
7
|
+
* never adjusts one, so the price worsening below is a venue giving a worse
|
|
8
|
+
* fill, which is what a venue does, and not an engine moving a number, which is
|
|
9
|
+
* what the invariant forbids. Everything here could be a broker.
|
|
10
|
+
*
|
|
11
|
+
* **A frame is cumulative and reaches the engine between bars.** Every frame
|
|
12
|
+
* restates the whole life of one order from its beginning, so a repeat costs
|
|
13
|
+
* nothing, and none of them is handed over during an execution: they are
|
|
14
|
+
* answered here and collected at the boundary, which is where
|
|
15
|
+
* `host-interface.md` 7.4 puts the intake.
|
|
16
|
+
*
|
|
17
|
+
* **When a fill is known is not when it happened.** A market order decided at
|
|
18
|
+
* the close of a bar and filled at the next bar's open is known at that open,
|
|
19
|
+
* so its frame is delivered before that bar executes and the strategy holds the
|
|
20
|
+
* position for the whole of it. An order that rested and traded somewhere
|
|
21
|
+
* inside a bar is only known to have traded once that bar is complete, so its
|
|
22
|
+
* frame is delivered before the bar after it. Both are the truthful reading of
|
|
23
|
+
* what a venue could have told anybody at the time, and the difference between
|
|
24
|
+
* them is why they are not folded together.
|
|
25
|
+
*
|
|
26
|
+
* **A bracket is answered with nothing at all**, exactly as a venue with no
|
|
27
|
+
* order to report would answer. A bracket reaches a destination as a protective
|
|
28
|
+
* instruction attached to a tag and the engine appends no row for it, so there
|
|
29
|
+
* is nothing for a frame to be about: a fill reported against one would name an
|
|
30
|
+
* intent no row holds and the fold would refuse it. The row a bracket wants is
|
|
31
|
+
* decision 55 and it is not in this release, so a stop cannot fill here and a
|
|
32
|
+
* page that says it can is ahead of the engine.
|
|
33
|
+
*
|
|
34
|
+
* **A destination that behaves badly does it on a schedule, stated before the
|
|
35
|
+
* run and never by chance.** Every case harvested before this one ran against a
|
|
36
|
+
* venue that filled every order whole and on time, so two engines were proved
|
|
37
|
+
* to agree about the half of a day that costs nobody anything. The other half
|
|
38
|
+
* is a partial fill, an order arriving in pieces, a rejection, a cancellation,
|
|
39
|
+
* an expiry and a fill that turns up after the order has ended, and
|
|
40
|
+
* `SimulatorOptions.fill` carries the schedule saying which order each of those
|
|
41
|
+
* happens to and at which boundary. There is no random number here and there
|
|
42
|
+
* will not be one: `stdlib.md` 8.2 keeps a script that answers differently on a
|
|
43
|
+
* second run out of a conformance suite, and a venue rolling a die would make
|
|
44
|
+
* every case it wrote unreproducible in the same breath. **An order the
|
|
45
|
+
* schedule names is answered by the schedule and by nothing else**, so a run
|
|
46
|
+
* stating none is the run the cases before this one were harvested from, to the
|
|
47
|
+
* bit, which is what lets this exist at all.
|
|
48
|
+
*/
|
|
49
|
+
import type { Contract } from '../accounting/index.js';
|
|
50
|
+
import type { OrderFrame, OrderIntent, RoutedEffect } from '../engine/index.js';
|
|
51
|
+
import type { RecordedBar } from './record.js';
|
|
52
|
+
import type { FillPolicy } from './settings.js';
|
|
53
|
+
/**
|
|
54
|
+
* What this destination does to one order, at one boundary.
|
|
55
|
+
*
|
|
56
|
+
* Four words reaching every status of `stdlib.md` 17.7 a host may send. `fill`
|
|
57
|
+
* carries the cumulative quantity, so one word covers the acknowledgement
|
|
58
|
+
* before anything has traded, a fill of part of the order and a fill of the
|
|
59
|
+
* whole of it: `working` and `filled` are that quantity read against the
|
|
60
|
+
* order's own rather than two instructions. The other three are the three ways
|
|
61
|
+
* an order ends carrying less than it asked for, and an engine never handed
|
|
62
|
+
* one has never been asked what it does with the quantity still working.
|
|
63
|
+
*/
|
|
64
|
+
export type VenueDoes = 'fill' | 'reject' | 'cancel' | 'expire';
|
|
65
|
+
/** One act of the schedule: what the destination does, to which order, when. */
|
|
66
|
+
export interface VenueAct {
|
|
67
|
+
/**
|
|
68
|
+
* The nth order this destination took, counting from one.
|
|
69
|
+
*
|
|
70
|
+
* Orders and not intents: a bracket is never taken and a cancellation is
|
|
71
|
+
* answered without being held, so neither is counted and neither can be named
|
|
72
|
+
* here. An ordinal for the reason `conformance.md` section 3 gives a case's
|
|
73
|
+
* own frames: nobody writing a schedule knows the id an engine will mint.
|
|
74
|
+
*/
|
|
75
|
+
readonly order: number;
|
|
76
|
+
/**
|
|
77
|
+
* Boundaries after the one the order arrived at, `0` being that boundary.
|
|
78
|
+
*
|
|
79
|
+
* Counted from the order rather than stated as a bar index, because the bar
|
|
80
|
+
* a strategy decides an order on moves the moment anything else about the run
|
|
81
|
+
* does, and a schedule in bar indices is one nobody can read back.
|
|
82
|
+
*/
|
|
83
|
+
readonly afterBars: number;
|
|
84
|
+
readonly does: VenueDoes;
|
|
85
|
+
/**
|
|
86
|
+
* The cumulative quantity a fill reports, in units, or absent for all of it.
|
|
87
|
+
*
|
|
88
|
+
* Cumulative because a frame is (`stdlib.md` 17.8): `0` is the
|
|
89
|
+
* acknowledgement a venue sends before anything has traded, a number below
|
|
90
|
+
* the order's own is a partial fill, and one at or above it completes the
|
|
91
|
+
* order. A quantity below what this venue has already reported is a stale
|
|
92
|
+
* frame, which a venue really sends and the fold has to swallow, so it is
|
|
93
|
+
* stated here rather than refused.
|
|
94
|
+
*/
|
|
95
|
+
readonly units?: number | null;
|
|
96
|
+
/** The destination's own text, which the ledger records against the row. */
|
|
97
|
+
readonly text?: string;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The fill policy, and what this destination does to the orders it names.
|
|
101
|
+
*
|
|
102
|
+
* The schedule sits on the policy because it is the same kind of fact: how this
|
|
103
|
+
* destination decides a fill, chosen before the first bar and carried in the
|
|
104
|
+
* record beside the policy's own version, so a stored run replays as it ran.
|
|
105
|
+
*/
|
|
106
|
+
export interface VenuePolicy extends FillPolicy {
|
|
107
|
+
readonly schedule?: readonly VenueAct[];
|
|
108
|
+
}
|
|
109
|
+
/** What the venue prices against and how it decides a fill. */
|
|
110
|
+
export interface SimulatorOptions {
|
|
111
|
+
readonly bars: readonly RecordedBar[];
|
|
112
|
+
readonly contract: Contract;
|
|
113
|
+
readonly fill: VenuePolicy;
|
|
114
|
+
/** Adverse always, in ticks, applied to a market fill and to a stop. */
|
|
115
|
+
readonly slippageTicks: number;
|
|
116
|
+
/** The declaration's own fill rule: where a market order is priced. */
|
|
117
|
+
readonly fillOn: string;
|
|
118
|
+
/**
|
|
119
|
+
* The unit the declaration's quantity is stated in, `language.md` 13.3.
|
|
120
|
+
*
|
|
121
|
+
* Here because converting it is the destination's job and a fill is counted
|
|
122
|
+
* in units. Only the units this destination can arrive at reach it: the rest
|
|
123
|
+
* are refused before the first bar by `checkSettings`.
|
|
124
|
+
*/
|
|
125
|
+
readonly qtyType: string;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* A venue, for one run.
|
|
129
|
+
*
|
|
130
|
+
* It holds the orders it was handed and nothing else: no position, no money and
|
|
131
|
+
* no view of what the strategy is doing, because a destination has none of
|
|
132
|
+
* those about somebody else's strategy.
|
|
133
|
+
*/
|
|
134
|
+
export declare class Simulator {
|
|
135
|
+
private readonly options;
|
|
136
|
+
private readonly orders;
|
|
137
|
+
/** The intents handed over, in the order they were, whatever became of them. */
|
|
138
|
+
readonly intents: OrderIntent[];
|
|
139
|
+
/** Brackets, held so that a run can say how many it was handed and answered. */
|
|
140
|
+
readonly brackets: OrderIntent[];
|
|
141
|
+
private queued;
|
|
142
|
+
private answered;
|
|
143
|
+
private refs;
|
|
144
|
+
private seq;
|
|
145
|
+
constructor(options: SimulatorOptions);
|
|
146
|
+
/** Step 9: what the strategy decided reaches the venue. */
|
|
147
|
+
route(effect: RoutedEffect, barIndex: number): void;
|
|
148
|
+
/**
|
|
149
|
+
* The frames a boundary hands over: everything this venue can say now.
|
|
150
|
+
*
|
|
151
|
+
* The orders that were already resting are decided against this bar first and
|
|
152
|
+
* the orders this bar sent are answered after, which is the order the venue
|
|
153
|
+
* learned of them in.
|
|
154
|
+
*/
|
|
155
|
+
framesFor(barIndex: number): readonly OrderFrame[];
|
|
156
|
+
/** How many orders this venue is still holding, which a run reports. */
|
|
157
|
+
get working(): number;
|
|
158
|
+
/** An order the strategy sent, which this venue now holds. */
|
|
159
|
+
private accept;
|
|
160
|
+
/**
|
|
161
|
+
* A cancellation, which is about the orders a tag names and not about itself.
|
|
162
|
+
*
|
|
163
|
+
* Every live order carrying the tag is withdrawn and answered, which is what
|
|
164
|
+
* releases the position they were claiming, and the cancellation is then
|
|
165
|
+
* answered as an order of its own, because the engine appended a row for it
|
|
166
|
+
* and a row nothing ever answers stays at `placed` for the life of the run.
|
|
167
|
+
*/
|
|
168
|
+
private withdraw;
|
|
169
|
+
/**
|
|
170
|
+
* The first thing a venue says about an order it has taken.
|
|
171
|
+
*
|
|
172
|
+
* A working frame before any fill, because 7.4 asks for a frame on every
|
|
173
|
+
* change of status and a script waiting for a working order to clear waits
|
|
174
|
+
* blind without one. A market order is then filled in the same breath where
|
|
175
|
+
* the declaration prices it at this bar's close, and at the next bar's open
|
|
176
|
+
* where it does not.
|
|
177
|
+
*/
|
|
178
|
+
private open;
|
|
179
|
+
/** One resting order against one bar. */
|
|
180
|
+
private decide;
|
|
181
|
+
/**
|
|
182
|
+
* The whole of an order, filled at one price.
|
|
183
|
+
*
|
|
184
|
+
* **The quantity is converted into units here, because that is what a fill
|
|
185
|
+
* is counted in and what every money figure is folded over.** A quantity
|
|
186
|
+
* travels in the declaration's own unit (`host-interface.md` 7.1) and the
|
|
187
|
+
* destination is the party that converts it. This filled the number verbatim,
|
|
188
|
+
* so a strategy sizing in lots on a lot of sixty five traded one sixty fifth
|
|
189
|
+
* of what it asked for and the whole report was out by that factor. The units
|
|
190
|
+
* this destination cannot arrive at are refused before the first bar rather
|
|
191
|
+
* than guessed at here, so by this point the unit is one of two.
|
|
192
|
+
*/
|
|
193
|
+
private complete;
|
|
194
|
+
/**
|
|
195
|
+
* The acts due at this boundary, in the order the schedule stated them.
|
|
196
|
+
*
|
|
197
|
+
* Due is counted from the bar that sent the order, so an act names a moment
|
|
198
|
+
* in the life of its own order rather than a bar of the run. Two acts due
|
|
199
|
+
* together are answered as written, which is how a schedule states a
|
|
200
|
+
* cancellation and the fill that raced it.
|
|
201
|
+
*
|
|
202
|
+
* Liveness is not consulted. An order that has ended can still be spoken
|
|
203
|
+
* about, because the frame that arrives after it ended is the whole reason
|
|
204
|
+
* this is here: `stdlib.md` 17.8's fill after a terminal status, which a
|
|
205
|
+
* venue sends whenever a cancel races a fill and which an engine refusing it
|
|
206
|
+
* loses, leaving a position the strategy cannot see.
|
|
207
|
+
*/
|
|
208
|
+
private perform;
|
|
209
|
+
/**
|
|
210
|
+
* A fill the schedule stated, at this bar's close and worsened like any other.
|
|
211
|
+
*
|
|
212
|
+
* **The average is this venue's own, over the cumulative quantity**, the
|
|
213
|
+
* figure `stdlib.md` 17.8 step 3 says the row takes whole. A venue reporting
|
|
214
|
+
* the last piece's price and calling it an average hands the engine a number
|
|
215
|
+
* that is not one, and the engine may not work its own out from two of them,
|
|
216
|
+
* so the lie settles into the ledger and into every trade folded from it.
|
|
217
|
+
*
|
|
218
|
+
* A stated quantity at or below what this venue has already reported adds
|
|
219
|
+
* nothing and moves nothing: that is a repeated or a stale frame, which a real
|
|
220
|
+
* destination sends and the fold has to swallow. It carries the average this
|
|
221
|
+
* venue holds now rather than then, because it keeps no history of its own
|
|
222
|
+
* averages and the fold ignores the price of a frame adding no quantity. A
|
|
223
|
+
* bar with no close prices nothing, so an act due at one says nothing rather
|
|
224
|
+
* than raising a quantity with no price against it, which step 3 refuses.
|
|
225
|
+
*/
|
|
226
|
+
private report;
|
|
227
|
+
/**
|
|
228
|
+
* The order's quantity in units, which is what a fill is counted in.
|
|
229
|
+
*
|
|
230
|
+
* The conversion `complete` did inline, wanted in two places the moment a
|
|
231
|
+
* schedule can fill an order in pieces: the whole a piece is measured
|
|
232
|
+
* against has to be the number the fill path would have reported.
|
|
233
|
+
*/
|
|
234
|
+
private unitsOf;
|
|
235
|
+
/**
|
|
236
|
+
* A price worsened by the slippage the run was carried out under.
|
|
237
|
+
*
|
|
238
|
+
* **Adverse always: a buy pays more and a sell receives less.** The sign is
|
|
239
|
+
* taken as written rather than as a magnitude, because a slippage below zero
|
|
240
|
+
* is refused before the first bar and taking its magnitude here would be this
|
|
241
|
+
* function quietly covering for a hole in that refusal. It went uncovered for
|
|
242
|
+
* a while: `scheduleProblem` has always refused a negative rate, and
|
|
243
|
+
* `checkSettings` asked it only about a schedule the host supplied, so a
|
|
244
|
+
* declaration stating a slippage of minus one improved both sides of every
|
|
245
|
+
* fill and the backtest paid the strategy to trade.
|
|
246
|
+
*
|
|
247
|
+
* A slippage in ticks with no tick size to measure a tick in charges nothing.
|
|
248
|
+
* The comment here once said that was refused before the first bar and it was
|
|
249
|
+
* not; it still is not, because an instrument with no tick is a fact a host
|
|
250
|
+
* may legitimately not hold, and a run that charges no slippage is a study
|
|
251
|
+
* before slippage rather than a wrong answer. What has changed is that this
|
|
252
|
+
* says so instead of claiming a refusal that never existed.
|
|
253
|
+
*/
|
|
254
|
+
private worsen;
|
|
255
|
+
/** One frame, cumulative, in the order this venue spoke. */
|
|
256
|
+
private say;
|
|
257
|
+
}
|
|
258
|
+
//# sourceMappingURL=simulate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simulate.d.ts","sourceRoot":"","sources":["../../../src/core/backtest/simulate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAa,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC3F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEhE,gFAAgF;AAChF,MAAM,WAAW,QAAQ;IACvB;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB;;;;;;;;;OASG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,WAAY,SAAQ,UAAU;IAC7C,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;CACzC;AAED,+DAA+D;AAC/D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAoCD;;;;;;GAMG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,WAAW,EAAE,CAAM;IACrC,gFAAgF;IAChF,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAM;IACtC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,GAAG,CAAK;gBAEJ,OAAO,EAAE,gBAAgB;IAIrC,2DAA2D;IAC3D,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAenD;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,UAAU,EAAE;IAyBlD,wEAAwE;IACxE,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,8DAA8D;IAC9D,OAAO,CAAC,MAAM;IAoBd;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ;IAYhB;;;;;;;;OAQG;IACH,OAAO,CAAC,IAAI;IAuBZ,yCAAyC;IACzC,OAAO,CAAC,MAAM;IAYd;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,QAAQ;IAQhB;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,OAAO;IAiBf;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,MAAM;IAsBd;;;;;;OAMG;IACH,OAAO,CAAC,OAAO;IAMf;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,MAAM;IAOd,4DAA4D;IAC5D,OAAO,CAAC,GAAG;CAuBZ"}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { testResting } from './resting.js';
|
|
2
|
+
/** `language.md` 13.3: a market order priced at the close of its own bar. */
|
|
3
|
+
const AT_CLOSE = 'close';
|
|
4
|
+
/**
|
|
5
|
+
* The word this venue reports each ending under.
|
|
6
|
+
*
|
|
7
|
+
* A destination with words of its own maps them onto the vocabulary in its
|
|
8
|
+
* adapter, which is where `stdlib.md` 17.7 puts the mapping because a status
|
|
9
|
+
* vocabulary differs per destination. This is this one's, and the whole of what
|
|
10
|
+
* a schedule's verb means.
|
|
11
|
+
*/
|
|
12
|
+
const ENDED = {
|
|
13
|
+
reject: 'rejected',
|
|
14
|
+
cancel: 'cancelled',
|
|
15
|
+
expire: 'expired',
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* A venue, for one run.
|
|
19
|
+
*
|
|
20
|
+
* It holds the orders it was handed and nothing else: no position, no money and
|
|
21
|
+
* no view of what the strategy is doing, because a destination has none of
|
|
22
|
+
* those about somebody else's strategy.
|
|
23
|
+
*/
|
|
24
|
+
export class Simulator {
|
|
25
|
+
options;
|
|
26
|
+
orders = [];
|
|
27
|
+
/** The intents handed over, in the order they were, whatever became of them. */
|
|
28
|
+
intents = [];
|
|
29
|
+
/** Brackets, held so that a run can say how many it was handed and answered. */
|
|
30
|
+
brackets = [];
|
|
31
|
+
queued = [];
|
|
32
|
+
answered = [];
|
|
33
|
+
refs = 0;
|
|
34
|
+
seq = 0;
|
|
35
|
+
constructor(options) {
|
|
36
|
+
this.options = options;
|
|
37
|
+
}
|
|
38
|
+
/** Step 9: what the strategy decided reaches the venue. */
|
|
39
|
+
route(effect, barIndex) {
|
|
40
|
+
for (const intent of effect.intents) {
|
|
41
|
+
this.intents.push(intent);
|
|
42
|
+
if (intent.kind === 'bracket') {
|
|
43
|
+
this.brackets.push(intent);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (intent.kind === 'cancel') {
|
|
47
|
+
this.withdraw(intent, barIndex);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
this.accept(intent, barIndex);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The frames a boundary hands over: everything this venue can say now.
|
|
55
|
+
*
|
|
56
|
+
* The orders that were already resting are decided against this bar first and
|
|
57
|
+
* the orders this bar sent are answered after, which is the order the venue
|
|
58
|
+
* learned of them in.
|
|
59
|
+
*/
|
|
60
|
+
framesFor(barIndex) {
|
|
61
|
+
const bar = this.options.bars[barIndex];
|
|
62
|
+
if (bar !== undefined) {
|
|
63
|
+
for (const order of this.orders) {
|
|
64
|
+
// An order the schedule names is answered by the schedule, whether or
|
|
65
|
+
// not it is still live: a fill after a cancellation is the one thing
|
|
66
|
+
// this exists for and the order is dead by then.
|
|
67
|
+
if (order.acts.length > 0) {
|
|
68
|
+
if (order.placedOn < barIndex)
|
|
69
|
+
this.perform(order, bar, barIndex);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (!order.live || order.rest === null || order.placedOn >= barIndex)
|
|
73
|
+
continue;
|
|
74
|
+
this.decide(order, bar, barIndex);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const sent = this.queued;
|
|
78
|
+
this.queued = [];
|
|
79
|
+
for (const order of sent)
|
|
80
|
+
this.open(order, barIndex);
|
|
81
|
+
const out = this.answered;
|
|
82
|
+
this.answered = [];
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
/** How many orders this venue is still holding, which a run reports. */
|
|
86
|
+
get working() {
|
|
87
|
+
return this.orders.filter((order) => order.live).length;
|
|
88
|
+
}
|
|
89
|
+
/** An order the strategy sent, which this venue now holds. */
|
|
90
|
+
accept(intent, barIndex) {
|
|
91
|
+
this.refs += 1;
|
|
92
|
+
// The ordinal of this order among the orders taken, which is what an act
|
|
93
|
+
// names. Read before the order joins them, so the first is one.
|
|
94
|
+
const ordinal = this.orders.length + 1;
|
|
95
|
+
const order = {
|
|
96
|
+
intent,
|
|
97
|
+
ref: refOf(this.refs),
|
|
98
|
+
placedOn: barIndex,
|
|
99
|
+
rest: restingFor(intent),
|
|
100
|
+
acts: (this.options.fill.schedule ?? []).filter((act) => act.order === ordinal),
|
|
101
|
+
filledQty: 0,
|
|
102
|
+
avgPrice: null,
|
|
103
|
+
live: true,
|
|
104
|
+
triggered: false,
|
|
105
|
+
};
|
|
106
|
+
this.orders.push(order);
|
|
107
|
+
this.queued.push(order);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* A cancellation, which is about the orders a tag names and not about itself.
|
|
111
|
+
*
|
|
112
|
+
* Every live order carrying the tag is withdrawn and answered, which is what
|
|
113
|
+
* releases the position they were claiming, and the cancellation is then
|
|
114
|
+
* answered as an order of its own, because the engine appended a row for it
|
|
115
|
+
* and a row nothing ever answers stays at `placed` for the life of the run.
|
|
116
|
+
*/
|
|
117
|
+
withdraw(intent, barIndex) {
|
|
118
|
+
for (const order of this.orders) {
|
|
119
|
+
if (!order.live || order.intent.tag !== intent.tag)
|
|
120
|
+
continue;
|
|
121
|
+
order.live = false;
|
|
122
|
+
this.say(order.intent, order.ref, 'cancelled', order.filledQty, null, barIndex);
|
|
123
|
+
}
|
|
124
|
+
// The cancellation is confirmed after what it withdrew, which is the order
|
|
125
|
+
// a venue does it in: the request is answered once it has been carried out.
|
|
126
|
+
this.refs += 1;
|
|
127
|
+
this.say(intent, refOf(this.refs), 'cancelled', 0, null, barIndex);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* The first thing a venue says about an order it has taken.
|
|
131
|
+
*
|
|
132
|
+
* A working frame before any fill, because 7.4 asks for a frame on every
|
|
133
|
+
* change of status and a script waiting for a working order to clear waits
|
|
134
|
+
* blind without one. A market order is then filled in the same breath where
|
|
135
|
+
* the declaration prices it at this bar's close, and at the next bar's open
|
|
136
|
+
* where it does not.
|
|
137
|
+
*/
|
|
138
|
+
open(order, barIndex) {
|
|
139
|
+
// A scheduled order is answered by its schedule from its first breath. The
|
|
140
|
+
// acknowledgement below is a thing this venue chooses to say, so a schedule
|
|
141
|
+
// that wants one states it, and one that wants the destination to sit on an
|
|
142
|
+
// order and say nothing gets that instead.
|
|
143
|
+
if (order.acts.length > 0) {
|
|
144
|
+
const bar = this.options.bars[barIndex];
|
|
145
|
+
if (bar !== undefined)
|
|
146
|
+
this.perform(order, bar, barIndex);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
this.say(order.intent, order.ref, 'working', 0, null, barIndex);
|
|
150
|
+
if (order.rest !== null)
|
|
151
|
+
return;
|
|
152
|
+
const atClose = this.options.fillOn === AT_CLOSE;
|
|
153
|
+
const bar = this.options.bars[atClose ? barIndex : barIndex + 1];
|
|
154
|
+
const price = atClose ? (bar?.close ?? null) : (bar?.open ?? null);
|
|
155
|
+
// A market order sent on the last bar of a run and priced at the next open
|
|
156
|
+
// has no next open. It stays working and is reported as an order the run
|
|
157
|
+
// ended holding, which is what it is.
|
|
158
|
+
if (price === null)
|
|
159
|
+
return;
|
|
160
|
+
this.complete(order, this.worsen(price, order.intent.side), barIndex);
|
|
161
|
+
}
|
|
162
|
+
/** One resting order against one bar. */
|
|
163
|
+
decide(order, bar, barIndex) {
|
|
164
|
+
const rest = order.rest;
|
|
165
|
+
if (rest === null)
|
|
166
|
+
return;
|
|
167
|
+
const outcome = testResting(order.triggered ? asLimit(rest) : rest, bar, this.options.fill);
|
|
168
|
+
if (!outcome.filled) {
|
|
169
|
+
if (outcome.triggered)
|
|
170
|
+
order.triggered = true;
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const price = outcome.slips ? this.worsen(outcome.price, order.intent.side) : outcome.price;
|
|
174
|
+
this.complete(order, price, barIndex);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* The whole of an order, filled at one price.
|
|
178
|
+
*
|
|
179
|
+
* **The quantity is converted into units here, because that is what a fill
|
|
180
|
+
* is counted in and what every money figure is folded over.** A quantity
|
|
181
|
+
* travels in the declaration's own unit (`host-interface.md` 7.1) and the
|
|
182
|
+
* destination is the party that converts it. This filled the number verbatim,
|
|
183
|
+
* so a strategy sizing in lots on a lot of sixty five traded one sixty fifth
|
|
184
|
+
* of what it asked for and the whole report was out by that factor. The units
|
|
185
|
+
* this destination cannot arrive at are refused before the first bar rather
|
|
186
|
+
* than guessed at here, so by this point the unit is one of two.
|
|
187
|
+
*/
|
|
188
|
+
complete(order, price, barIndex) {
|
|
189
|
+
const qty = this.unitsOf(order.intent);
|
|
190
|
+
order.filledQty = qty;
|
|
191
|
+
order.avgPrice = price;
|
|
192
|
+
order.live = false;
|
|
193
|
+
this.say(order.intent, order.ref, 'filled', qty, price, barIndex);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* The acts due at this boundary, in the order the schedule stated them.
|
|
197
|
+
*
|
|
198
|
+
* Due is counted from the bar that sent the order, so an act names a moment
|
|
199
|
+
* in the life of its own order rather than a bar of the run. Two acts due
|
|
200
|
+
* together are answered as written, which is how a schedule states a
|
|
201
|
+
* cancellation and the fill that raced it.
|
|
202
|
+
*
|
|
203
|
+
* Liveness is not consulted. An order that has ended can still be spoken
|
|
204
|
+
* about, because the frame that arrives after it ended is the whole reason
|
|
205
|
+
* this is here: `stdlib.md` 17.8's fill after a terminal status, which a
|
|
206
|
+
* venue sends whenever a cancel races a fill and which an engine refusing it
|
|
207
|
+
* loses, leaving a position the strategy cannot see.
|
|
208
|
+
*/
|
|
209
|
+
perform(order, bar, barIndex) {
|
|
210
|
+
for (const act of order.acts) {
|
|
211
|
+
if (order.placedOn + act.afterBars !== barIndex)
|
|
212
|
+
continue;
|
|
213
|
+
if (act.does === 'fill') {
|
|
214
|
+
this.report(order, act, bar, barIndex);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
// The order ends, reporting what it filled before it ended, because a
|
|
218
|
+
// frame is cumulative: `stdlib.md` 17.8 has the row keeping the terminal
|
|
219
|
+
// word and the quantity recording what traded, both true at once.
|
|
220
|
+
order.live = false;
|
|
221
|
+
const ended = ENDED[act.does];
|
|
222
|
+
const price = order.filledQty > 0 ? order.avgPrice : null;
|
|
223
|
+
this.say(order.intent, order.ref, ended, order.filledQty, price, barIndex, act.text ?? '');
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* A fill the schedule stated, at this bar's close and worsened like any other.
|
|
228
|
+
*
|
|
229
|
+
* **The average is this venue's own, over the cumulative quantity**, the
|
|
230
|
+
* figure `stdlib.md` 17.8 step 3 says the row takes whole. A venue reporting
|
|
231
|
+
* the last piece's price and calling it an average hands the engine a number
|
|
232
|
+
* that is not one, and the engine may not work its own out from two of them,
|
|
233
|
+
* so the lie settles into the ledger and into every trade folded from it.
|
|
234
|
+
*
|
|
235
|
+
* A stated quantity at or below what this venue has already reported adds
|
|
236
|
+
* nothing and moves nothing: that is a repeated or a stale frame, which a real
|
|
237
|
+
* destination sends and the fold has to swallow. It carries the average this
|
|
238
|
+
* venue holds now rather than then, because it keeps no history of its own
|
|
239
|
+
* averages and the fold ignores the price of a frame adding no quantity. A
|
|
240
|
+
* bar with no close prices nothing, so an act due at one says nothing rather
|
|
241
|
+
* than raising a quantity with no price against it, which step 3 refuses.
|
|
242
|
+
*/
|
|
243
|
+
report(order, act, bar, barIndex) {
|
|
244
|
+
const whole = this.unitsOf(order.intent);
|
|
245
|
+
const stated = act.units ?? whole;
|
|
246
|
+
const delta = stated - order.filledQty;
|
|
247
|
+
if (delta > 0) {
|
|
248
|
+
if (bar.close === null)
|
|
249
|
+
return;
|
|
250
|
+
// Written in this order and left in it: the source order of a sum is
|
|
251
|
+
// what decides its last bit, and a case harvested from this venue is
|
|
252
|
+
// asserted to the bit.
|
|
253
|
+
const price = this.worsen(bar.close, order.intent.side);
|
|
254
|
+
order.avgPrice = ((order.avgPrice ?? 0) * order.filledQty + price * delta) / stated;
|
|
255
|
+
order.filledQty = stated;
|
|
256
|
+
if (order.filledQty >= whole)
|
|
257
|
+
order.live = false;
|
|
258
|
+
}
|
|
259
|
+
// `working` is live and not completely filled, `filled` is the whole
|
|
260
|
+
// quantity: 17.7's two words read off the quantity rather than stated
|
|
261
|
+
// twice by a schedule that could disagree with the number beside them.
|
|
262
|
+
const status = order.filledQty >= whole ? 'filled' : 'working';
|
|
263
|
+
const price = stated > 0 ? order.avgPrice : null;
|
|
264
|
+
this.say(order.intent, order.ref, status, stated, price, barIndex, act.text ?? '');
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* The order's quantity in units, which is what a fill is counted in.
|
|
268
|
+
*
|
|
269
|
+
* The conversion `complete` did inline, wanted in two places the moment a
|
|
270
|
+
* schedule can fill an order in pieces: the whole a piece is measured
|
|
271
|
+
* against has to be the number the fill path would have reported.
|
|
272
|
+
*/
|
|
273
|
+
unitsOf(intent) {
|
|
274
|
+
const stated = intent.qty ?? 0;
|
|
275
|
+
const lot = this.options.contract.lotSize;
|
|
276
|
+
return this.options.qtyType === 'lots' && lot !== null && lot > 0 ? stated * lot : stated;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* A price worsened by the slippage the run was carried out under.
|
|
280
|
+
*
|
|
281
|
+
* **Adverse always: a buy pays more and a sell receives less.** The sign is
|
|
282
|
+
* taken as written rather than as a magnitude, because a slippage below zero
|
|
283
|
+
* is refused before the first bar and taking its magnitude here would be this
|
|
284
|
+
* function quietly covering for a hole in that refusal. It went uncovered for
|
|
285
|
+
* a while: `scheduleProblem` has always refused a negative rate, and
|
|
286
|
+
* `checkSettings` asked it only about a schedule the host supplied, so a
|
|
287
|
+
* declaration stating a slippage of minus one improved both sides of every
|
|
288
|
+
* fill and the backtest paid the strategy to trade.
|
|
289
|
+
*
|
|
290
|
+
* A slippage in ticks with no tick size to measure a tick in charges nothing.
|
|
291
|
+
* The comment here once said that was refused before the first bar and it was
|
|
292
|
+
* not; it still is not, because an instrument with no tick is a fact a host
|
|
293
|
+
* may legitimately not hold, and a run that charges no slippage is a study
|
|
294
|
+
* before slippage rather than a wrong answer. What has changed is that this
|
|
295
|
+
* says so instead of claiming a refusal that never existed.
|
|
296
|
+
*/
|
|
297
|
+
worsen(price, side) {
|
|
298
|
+
const tick = this.options.contract.tickSize;
|
|
299
|
+
if (tick === null || this.options.slippageTicks === 0)
|
|
300
|
+
return price;
|
|
301
|
+
const move = this.options.slippageTicks * tick;
|
|
302
|
+
return side === 'sell' ? price - move : price + move;
|
|
303
|
+
}
|
|
304
|
+
/** One frame, cumulative, in the order this venue spoke. */
|
|
305
|
+
say(intent, ref, status, filledQty, avgFillPrice, barIndex, text = '') {
|
|
306
|
+
this.seq += 1;
|
|
307
|
+
this.answered.push({
|
|
308
|
+
intentId: intent.intentId,
|
|
309
|
+
status,
|
|
310
|
+
filledQty,
|
|
311
|
+
avgFillPrice,
|
|
312
|
+
orderRef: ref,
|
|
313
|
+
sentInstrument: intent.instrument,
|
|
314
|
+
sentProduct: intent.product,
|
|
315
|
+
time: this.options.bars[barIndex]?.time ?? null,
|
|
316
|
+
text,
|
|
317
|
+
seq: this.seq,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/** This venue's own reference for an order, which the engine records and never parses. */
|
|
322
|
+
function refOf(count) {
|
|
323
|
+
return 'ORD-' + String(count);
|
|
324
|
+
}
|
|
325
|
+
/** The resting order an intent is, or nothing where it is a market order. */
|
|
326
|
+
function restingFor(intent) {
|
|
327
|
+
if (intent.type === null || intent.type === 'market' || intent.side === null)
|
|
328
|
+
return null;
|
|
329
|
+
return { side: intent.side, type: intent.type, limit: intent.limit, trigger: intent.trigger };
|
|
330
|
+
}
|
|
331
|
+
/** A stop limit that has triggered, which is a limit from that moment on. */
|
|
332
|
+
function asLimit(rest) {
|
|
333
|
+
return { side: rest.side, type: 'limit', limit: rest.limit, trigger: null };
|
|
334
|
+
}
|
|
335
|
+
//# sourceMappingURL=simulate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simulate.js","sourceRoot":"","sources":["../../../src/core/backtest/simulate.ts"],"names":[],"mappings":"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"}
|