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,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Highlighting, as the editor's line at a time tokenizer.
|
|
3
|
+
*
|
|
4
|
+
* The editor asks for one line's tokens at a time and remembers nothing between
|
|
5
|
+
* lines except the state this file hands back. The tier's `highlight` takes a
|
|
6
|
+
* whole file. So the line is what is lexed here, by the real lexer, through the
|
|
7
|
+
* same `highlight` a host would call itself.
|
|
8
|
+
*
|
|
9
|
+
* **That is an equivalence rather than an approximation, and it is measured.**
|
|
10
|
+
* `tests/adapters/codemirror/stream.test.ts` puts every script in the repository
|
|
11
|
+
* and the malformed corpus through both routes and compares them piece for
|
|
12
|
+
* piece: 4279 lines of real scripts, and not one of them differs. It holds
|
|
13
|
+
* because nothing in this language crosses a line ending: a string literal is
|
|
14
|
+
* refused at the end of its line, there is no block comment, and the layout
|
|
15
|
+
* tokens that do depend on the lines above are painted as whitespace either way.
|
|
16
|
+
* If the language ever grows something that does cross one, that test fails on
|
|
17
|
+
* the day it is added rather than on the day somebody notices a half painted
|
|
18
|
+
* line, and this becomes a line the narrowings file has to carry.
|
|
19
|
+
*
|
|
20
|
+
* A line is lexed once, not once per token: the pieces are computed when the
|
|
21
|
+
* editor arrives at the start of a line and walked from there. Without that, a
|
|
22
|
+
* line of twenty tokens would be lexed twenty times, which is the shape that
|
|
23
|
+
* makes a tokenizer show up in a frame budget.
|
|
24
|
+
*/
|
|
25
|
+
import { highlight } from '../../editor/index.js';
|
|
26
|
+
import type { Highlight } from '../../editor/index.js';
|
|
27
|
+
import type { EditorStreamParser, EditorStringStream } from './contract.js';
|
|
28
|
+
import { HIGHLIGHT_TOKENS } from './tokens.js';
|
|
29
|
+
|
|
30
|
+
/** What is carried from one call to the next: the line, and its pieces. */
|
|
31
|
+
export interface StreamState {
|
|
32
|
+
/** The line the pieces were computed from, so a changed line is redone. */
|
|
33
|
+
line: string;
|
|
34
|
+
pieces: readonly Highlight[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** The pieces of one line, computed once and kept until the line changes. */
|
|
38
|
+
function piecesFor(state: StreamState, line: string): readonly Highlight[] {
|
|
39
|
+
if (state.line !== line || state.pieces.length === 0) {
|
|
40
|
+
state.line = line;
|
|
41
|
+
state.pieces = highlight(line);
|
|
42
|
+
}
|
|
43
|
+
return state.pieces;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The tokenizer, which a host turns into a language with one call.
|
|
48
|
+
*
|
|
49
|
+
* ```ts
|
|
50
|
+
* const openscript = StreamLanguage.define(openscriptStream);
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* `token` moves the stream to the end of the piece that starts where it is and
|
|
54
|
+
* returns that piece's style. A stream that has somehow been left inside a piece,
|
|
55
|
+
* which the editor does when it re-tokenizes from a column rather than from the
|
|
56
|
+
* start of a line, is moved to the end of the piece containing it, so the
|
|
57
|
+
* tokenizer always advances and the editor cannot be made to loop.
|
|
58
|
+
*/
|
|
59
|
+
export const openscriptStream: EditorStreamParser<StreamState> = {
|
|
60
|
+
name: 'openscript',
|
|
61
|
+
|
|
62
|
+
startState: (): StreamState => ({ line: '', pieces: [] }),
|
|
63
|
+
|
|
64
|
+
copyState: (state: StreamState): StreamState => ({ line: state.line, pieces: state.pieces }),
|
|
65
|
+
|
|
66
|
+
token(stream: EditorStringStream, state: StreamState): string | null {
|
|
67
|
+
if (stream.eol()) return null;
|
|
68
|
+
|
|
69
|
+
const pieces = piecesFor(state, stream.string);
|
|
70
|
+
const at = stream.pos;
|
|
71
|
+
const piece = pieces.find(
|
|
72
|
+
(one) => at >= one.span.offset && at < one.span.offset + one.span.length,
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
if (piece === undefined) {
|
|
76
|
+
// No piece covers the position, which cannot happen for a line the tier
|
|
77
|
+
// has covered and is still answered rather than trusted: the pieces tile
|
|
78
|
+
// the line, so this is a position outside it. Moving to the end leaves the
|
|
79
|
+
// editor with an unstyled remainder instead of an infinite loop.
|
|
80
|
+
stream.pos = stream.string.length;
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
stream.pos = piece.span.offset + piece.span.length;
|
|
85
|
+
return HIGHLIGHT_TOKENS[piece.kind];
|
|
86
|
+
},
|
|
87
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The eleven kinds, as the editor's own highlighting tags.
|
|
3
|
+
*
|
|
4
|
+
* This is the translation an adapter exists to do: the language has eleven
|
|
5
|
+
* kinds, closed, and the editor has a vocabulary of tags its themes are written
|
|
6
|
+
* against. Neither knows about the other, and this file is the only place that
|
|
7
|
+
* knows both.
|
|
8
|
+
*
|
|
9
|
+
* **It is one record rather than a switch on purpose.** A style name is the one
|
|
10
|
+
* thing in this adapter that no type can hold: the editor looks a name up in its
|
|
11
|
+
* own tag table at run time and warns on a console about one it does not know,
|
|
12
|
+
* so a name that is wrong here is invisible to every check in this repository
|
|
13
|
+
* and shows up as an unpainted keyword in somebody's product. A host that
|
|
14
|
+
* disagrees with any of these, or whose theme is written against different
|
|
15
|
+
* names, replaces the row in one line:
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* const tokens = { ...HIGHLIGHT_TOKENS, unknown: "invalid" };
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Two of the eleven are deliberately unstyled. `whitespace` has nothing to
|
|
22
|
+
* paint. `unknown` is the honest name for source the lexer took no token from,
|
|
23
|
+
* which is a character the language does not have, a region somebody wrote as a
|
|
24
|
+
* block comment, or a line continuation backslash: the first is a mistake and
|
|
25
|
+
* the last is not, so painting all three as invalid would paint a correct line
|
|
26
|
+
* red. `diagnose` is what says which of them is wrong, and the linter below is
|
|
27
|
+
* how a host shows that.
|
|
28
|
+
*/
|
|
29
|
+
import type { HighlightKind } from '../../editor/index.js';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A style name per kind, or null for one the editor should leave alone.
|
|
33
|
+
*
|
|
34
|
+
* `builtin` uses the editor's modifier syntax for a name the environment
|
|
35
|
+
* supplies rather than the file, which is what a library name is.
|
|
36
|
+
*/
|
|
37
|
+
export const HIGHLIGHT_TOKENS: Readonly<Record<HighlightKind, string | null>> = {
|
|
38
|
+
keyword: 'keyword',
|
|
39
|
+
builtin: 'variableName.standard',
|
|
40
|
+
name: 'variableName',
|
|
41
|
+
number: 'number',
|
|
42
|
+
string: 'string',
|
|
43
|
+
color: 'color',
|
|
44
|
+
comment: 'comment',
|
|
45
|
+
operator: 'operator',
|
|
46
|
+
punctuation: 'punctuation',
|
|
47
|
+
whitespace: null,
|
|
48
|
+
unknown: null,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The editor's name for the icon beside a completion row, per kind.
|
|
53
|
+
*
|
|
54
|
+
* The editor ships icons for a fixed set of names and shows none for a name it
|
|
55
|
+
* does not know, which is a missing icon rather than a missing row.
|
|
56
|
+
*/
|
|
57
|
+
export const COMPLETION_TYPES: Readonly<Record<string, string>> = {
|
|
58
|
+
function: 'function',
|
|
59
|
+
value: 'constant',
|
|
60
|
+
namespace: 'namespace',
|
|
61
|
+
member: 'property',
|
|
62
|
+
variable: 'variable',
|
|
63
|
+
argument: 'property',
|
|
64
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hover and signature, as the editor's tooltips.
|
|
3
|
+
*
|
|
4
|
+
* This is the one part of the adapter that would put something on screen, and it
|
|
5
|
+
* is the one part that does not: the markup is a parameter, and there is no
|
|
6
|
+
* default for it. So nothing in this package, at any tier, names a browser
|
|
7
|
+
* global, and `scripts/check-layering.mjs` fails the build if anything under
|
|
8
|
+
* `src` does. The same files load in a worker, on a server and inside somebody
|
|
9
|
+
* else's application.
|
|
10
|
+
*
|
|
11
|
+
* It costs a host four lines and it is the whole point of the split. Every
|
|
12
|
+
* platform has a design system and none of them wants to fight a styled panel
|
|
13
|
+
* that arrived with a language package; a default renderer here would be that
|
|
14
|
+
* panel, and it would be the one thing in this adapter a host could not replace
|
|
15
|
+
* without replacing the adapter.
|
|
16
|
+
*
|
|
17
|
+
* What is not a parameter is the content. `hoverLines` and `signatureLines`
|
|
18
|
+
* below are what a tooltip says, in order, and every line of it came from the
|
|
19
|
+
* compiler: the signatures from the library manifest, the sentence and the
|
|
20
|
+
* warmup from the specification's own tables, the type from the checker, and the
|
|
21
|
+
* refusal from the error catalogue.
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* hoverTooltip(openscriptHoverTooltip((held) => ({ dom: yourPanel(hoverLines(held)) })))
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
import { hover, signature } from '../../editor/index.js';
|
|
28
|
+
import type { Hover, SignatureHelp } from '../../editor/index.js';
|
|
29
|
+
import type { EditorState, EditorTooltip, EditorTooltipView, EditorView } from './contract.js';
|
|
30
|
+
import { documentOf, normalisedOffset } from './positions.js';
|
|
31
|
+
|
|
32
|
+
/** What a host supplies to draw a tooltip, which is the whole of the markup. */
|
|
33
|
+
export interface Renderer<Held> {
|
|
34
|
+
(held: Held): EditorTooltipView;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The lines a hover shows, in the order it shows them.
|
|
39
|
+
*
|
|
40
|
+
* Every one of them came from the compiler: the signatures from the library
|
|
41
|
+
* manifest, the sentence and the warmup from the specification's own tables, the
|
|
42
|
+
* type from the checker, and the refusal from the error catalogue. Nothing is
|
|
43
|
+
* written here, which is why this function is a join rather than a template.
|
|
44
|
+
*/
|
|
45
|
+
export function hoverLines(held: Hover): readonly string[] {
|
|
46
|
+
const lines = [...held.signatures];
|
|
47
|
+
if (held.summary !== undefined) lines.push(held.summary);
|
|
48
|
+
if (held.warmup !== undefined) lines.push(`First value: ${held.warmup}`);
|
|
49
|
+
if (held.refusal !== undefined) lines.push(held.refusal);
|
|
50
|
+
if (held.kind === 'keyword') lines.push('A reserved word of the language.');
|
|
51
|
+
return lines;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** The lines a signature tooltip shows, with the active parameter named. */
|
|
55
|
+
export function signatureLines(held: SignatureHelp): readonly string[] {
|
|
56
|
+
const lines = [held.signature];
|
|
57
|
+
const active = held.parameters[held.active];
|
|
58
|
+
if (active !== undefined) {
|
|
59
|
+
const value = active.defaultText === undefined ? '' : ` = ${active.defaultText}`;
|
|
60
|
+
const need = active.required ? 'required' : 'optional';
|
|
61
|
+
lines.push(`${active.name}: ${active.type}${value} (${need})`);
|
|
62
|
+
if (active.values.length > 0) lines.push(`One of: ${active.values.join(', ')}`);
|
|
63
|
+
}
|
|
64
|
+
if (held.summary !== undefined) lines.push(held.summary);
|
|
65
|
+
if (held.refusal !== undefined) lines.push(held.refusal);
|
|
66
|
+
return lines;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* A hover tooltip source, which a host wires in one line.
|
|
71
|
+
*
|
|
72
|
+
* ```ts
|
|
73
|
+
* hoverTooltip(openscriptHoverTooltip(render))
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export function openscriptHoverTooltip(
|
|
77
|
+
render: Renderer<Hover>,
|
|
78
|
+
): (view: EditorView, pos: number) => EditorTooltip | null {
|
|
79
|
+
return (view, pos) => {
|
|
80
|
+
const held = documentOf(view.state.doc.toString());
|
|
81
|
+
const found = hover(held.text, normalisedOffset(held, pos));
|
|
82
|
+
if (found === undefined) return null;
|
|
83
|
+
return {
|
|
84
|
+
pos: held.at(found.span.offset),
|
|
85
|
+
end: held.at(found.span.offset + found.span.length),
|
|
86
|
+
create: () => render(found),
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* A signature tooltip for wherever the cursor is, or nothing where it is in no
|
|
93
|
+
* call.
|
|
94
|
+
*
|
|
95
|
+
* ```ts
|
|
96
|
+
* showTooltip.compute(["doc", "selection"], openscriptSignatureTooltip(render))
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
export function openscriptSignatureTooltip(
|
|
100
|
+
render: Renderer<SignatureHelp>,
|
|
101
|
+
): (state: EditorState) => EditorTooltip | null {
|
|
102
|
+
return (state) => {
|
|
103
|
+
const held = documentOf(state.doc.toString());
|
|
104
|
+
const at = normalisedOffset(held, state.selection.main.head);
|
|
105
|
+
const found = signature(held.text, at);
|
|
106
|
+
if (found === undefined) return null;
|
|
107
|
+
return {
|
|
108
|
+
pos: state.selection.main.head,
|
|
109
|
+
above: true,
|
|
110
|
+
create: () => render(found),
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The trades taken apart: by direction, by extreme, and by run.
|
|
3
|
+
*
|
|
4
|
+
* The summary answers what the whole run did. Three questions it cannot answer
|
|
5
|
+
* are asked here, and each of them is a question about whether the summary
|
|
6
|
+
* means what it looks like it means.
|
|
7
|
+
*
|
|
8
|
+
* **Which side made the money.** A run whose long trades paid for its short
|
|
9
|
+
* ones reports a healthy net and is two strategies, one of which is losing. The
|
|
10
|
+
* summary cannot show that, because every figure in it is folded over both
|
|
11
|
+
* sides at once. Splitting it is not a refinement of the headline number, it is
|
|
12
|
+
* the first thing that can contradict it.
|
|
13
|
+
*
|
|
14
|
+
* **Whether one trade is the result.** A hundred trades and a profit factor of
|
|
15
|
+
* two reads as an edge until the largest win is the whole of the net. The
|
|
16
|
+
* expectancy's standard error already says how wide the spread is; the largest
|
|
17
|
+
* win and the largest loss say where the width came from, which is the part a
|
|
18
|
+
* reader can act on.
|
|
19
|
+
*
|
|
20
|
+
* **What the run of losses was.** The deepest drawdown is a money figure and
|
|
21
|
+
* the longest one is a bar count, and neither is the number that actually stops
|
|
22
|
+
* somebody trading a strategy. That number is how many times in a row it was
|
|
23
|
+
* wrong. It is not derivable from anything in the summary: the same win rate
|
|
24
|
+
* over the same trades gives a streak of two or a streak of eleven depending on
|
|
25
|
+
* an ordering the summary folds away.
|
|
26
|
+
*
|
|
27
|
+
* ## Every figure here is over closed trades, and that is the whole rule
|
|
28
|
+
*
|
|
29
|
+
* An open trade has no net to win or lose by, so it is in none of these counts,
|
|
30
|
+
* on either side, in no streak and in no extreme. `statistics.ts` has three
|
|
31
|
+
* different answers to which trades a figure is counted over, because a summary
|
|
32
|
+
* carries a capital figure and a bar count that are facts about the run rather
|
|
33
|
+
* than about its trades. Nothing here is a fact about the run, so there is one
|
|
34
|
+
* answer, and a reader can hold it.
|
|
35
|
+
*
|
|
36
|
+
* The consequence worth stating: `longCount + shortCount` is `tradeCount` and
|
|
37
|
+
* not the length of the list folded. A run holding an open position reports
|
|
38
|
+
* fewer trades here than it has, and the summary's `openTradeCount` is where
|
|
39
|
+
* the difference is accounted for.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
import type { Money } from './shapes.js';
|
|
43
|
+
import type { Trade } from './trades.js';
|
|
44
|
+
|
|
45
|
+
/** One direction's own figures, folded over that side's closed trades. */
|
|
46
|
+
export interface SideAnalysis {
|
|
47
|
+
readonly count: number;
|
|
48
|
+
readonly wins: number;
|
|
49
|
+
readonly losses: number;
|
|
50
|
+
/** Exactly zero net, counted in neither half, as in the summary. */
|
|
51
|
+
readonly scratches: number;
|
|
52
|
+
/** Net after charges, which is the figure the sides are compared on. */
|
|
53
|
+
readonly netProfit: Money;
|
|
54
|
+
/** `wins / (wins + losses)`, null where this side decided nothing. */
|
|
55
|
+
readonly winRate: number | null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The trades by direction, by extreme and by run.
|
|
60
|
+
*
|
|
61
|
+
* `long` and `short` partition the closed trades, so their counts sum to the
|
|
62
|
+
* summary's `tradeCount` and their nets sum to its `netProfit`. That is
|
|
63
|
+
* asserted rather than assumed, because a partition that stops partitioning is
|
|
64
|
+
* the defect this shape exists to make visible and it would otherwise show up
|
|
65
|
+
* as two panels that quietly disagree.
|
|
66
|
+
*/
|
|
67
|
+
export interface TradeAnalysis {
|
|
68
|
+
readonly long: SideAnalysis;
|
|
69
|
+
readonly short: SideAnalysis;
|
|
70
|
+
/**
|
|
71
|
+
* The best closed trade's net, zero where none closed and zero where every
|
|
72
|
+
* closed trade lost.
|
|
73
|
+
*
|
|
74
|
+
* Zero rather than null, and it is the one place here that is worth arguing
|
|
75
|
+
* about. A run whose every trade lost has no winning trade to name, and null
|
|
76
|
+
* would say so. It reports zero because the figure is read beside
|
|
77
|
+
* `largestLoss` and against `netProfit`, and a null in a column of money
|
|
78
|
+
* forces every reader of the report to handle a case that means "nothing
|
|
79
|
+
* won", which is what zero already means in this column.
|
|
80
|
+
*/
|
|
81
|
+
readonly largestWin: Money;
|
|
82
|
+
/** The worst closed trade's net as a positive magnitude, zero where none lost. */
|
|
83
|
+
readonly largestLoss: Money;
|
|
84
|
+
/**
|
|
85
|
+
* The longest run of consecutive winning closed trades, in the order they
|
|
86
|
+
* closed.
|
|
87
|
+
*
|
|
88
|
+
* In the order they closed, and not the order they opened, because that is
|
|
89
|
+
* the order the account experienced them in and the streak is a fact about
|
|
90
|
+
* what the account experienced. The two orders differ whenever a trade is
|
|
91
|
+
* held across another one's whole life, which is every scaling strategy.
|
|
92
|
+
*/
|
|
93
|
+
readonly maxConsecutiveWins: number;
|
|
94
|
+
/** The same, for losses. */
|
|
95
|
+
readonly maxConsecutiveLosses: number;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** A side's figures under construction, before the rates are taken. */
|
|
99
|
+
interface SideTally {
|
|
100
|
+
count: number;
|
|
101
|
+
wins: number;
|
|
102
|
+
losses: number;
|
|
103
|
+
scratches: number;
|
|
104
|
+
netProfit: Money;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function emptySide(): SideTally {
|
|
108
|
+
return { count: 0, wins: 0, losses: 0, scratches: 0, netProfit: 0 };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function sideOf(tally: SideTally): SideAnalysis {
|
|
112
|
+
const decided = tally.wins + tally.losses;
|
|
113
|
+
return {
|
|
114
|
+
count: tally.count,
|
|
115
|
+
wins: tally.wins,
|
|
116
|
+
losses: tally.losses,
|
|
117
|
+
scratches: tally.scratches,
|
|
118
|
+
netProfit: tally.netProfit,
|
|
119
|
+
winRate: decided === 0 ? null : tally.wins / decided,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* One pass over the closed trades, in closing order.
|
|
125
|
+
*
|
|
126
|
+
* The list arrives in opening order, which is what the equity fold needs and
|
|
127
|
+
* what `tradesOf` produces. The streaks need closing order, so the closed
|
|
128
|
+
* trades are ordered here rather than anywhere else: reordering the list the
|
|
129
|
+
* caller holds would change the equity curve, and taking a second list in
|
|
130
|
+
* opening order and calling its streaks correct would be the defect this
|
|
131
|
+
* function is supposed to have caught.
|
|
132
|
+
*
|
|
133
|
+
* A trade whose net is exactly zero is a scratch, which is the summary's rule
|
|
134
|
+
* and is applied here for the same reason. A scratch **breaks** a streak
|
|
135
|
+
* without extending either one: a strategy that went right, flat, right was not
|
|
136
|
+
* right twice running, and counting the flat trade as either would make the
|
|
137
|
+
* streak a figure that depends on a rounding at the last digit.
|
|
138
|
+
*/
|
|
139
|
+
export function analysisOf(trades: readonly Trade[]): TradeAnalysis {
|
|
140
|
+
const long = emptySide();
|
|
141
|
+
const short = emptySide();
|
|
142
|
+
let largestWin = 0;
|
|
143
|
+
let largestLoss = 0;
|
|
144
|
+
let maxConsecutiveWins = 0;
|
|
145
|
+
let maxConsecutiveLosses = 0;
|
|
146
|
+
let winStreak = 0;
|
|
147
|
+
let lossStreak = 0;
|
|
148
|
+
|
|
149
|
+
const closed = trades.filter((trade) => !trade.isOpen).slice();
|
|
150
|
+
// A trade closes on a bar, and two can close on the same one. The opening
|
|
151
|
+
// order breaks the tie, because it is the order the list arrived in and the
|
|
152
|
+
// only other fact available: a sort that is not total gives two engines two
|
|
153
|
+
// different streaks from one list of trades.
|
|
154
|
+
closed.sort((a, b) => (a.closedOnBar ?? 0) - (b.closedOnBar ?? 0) || a.index - b.index);
|
|
155
|
+
|
|
156
|
+
for (const trade of closed) {
|
|
157
|
+
const side = trade.side === 'long' ? long : short;
|
|
158
|
+
side.count += 1;
|
|
159
|
+
side.netProfit += trade.netProfit;
|
|
160
|
+
|
|
161
|
+
if (trade.netProfit > 0) {
|
|
162
|
+
side.wins += 1;
|
|
163
|
+
if (trade.netProfit > largestWin) largestWin = trade.netProfit;
|
|
164
|
+
winStreak += 1;
|
|
165
|
+
lossStreak = 0;
|
|
166
|
+
if (winStreak > maxConsecutiveWins) maxConsecutiveWins = winStreak;
|
|
167
|
+
} else if (trade.netProfit < 0) {
|
|
168
|
+
side.losses += 1;
|
|
169
|
+
if (-trade.netProfit > largestLoss) largestLoss = -trade.netProfit;
|
|
170
|
+
lossStreak += 1;
|
|
171
|
+
winStreak = 0;
|
|
172
|
+
if (lossStreak > maxConsecutiveLosses) maxConsecutiveLosses = lossStreak;
|
|
173
|
+
} else {
|
|
174
|
+
side.scratches += 1;
|
|
175
|
+
winStreak = 0;
|
|
176
|
+
lossStreak = 0;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
long: sideOf(long),
|
|
182
|
+
short: sideOf(short),
|
|
183
|
+
largestWin,
|
|
184
|
+
largestLoss,
|
|
185
|
+
maxConsecutiveWins,
|
|
186
|
+
maxConsecutiveLosses,
|
|
187
|
+
};
|
|
188
|
+
}
|