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.
Files changed (357) hide show
  1. package/CHANGELOG.md +1198 -0
  2. package/README.md +127 -40
  3. package/dist/adapters/charts/driving.d.ts +50 -0
  4. package/dist/adapters/charts/driving.d.ts.map +1 -0
  5. package/dist/adapters/charts/driving.js +57 -0
  6. package/dist/adapters/charts/driving.js.map +1 -0
  7. package/dist/adapters/charts/run.d.ts +20 -0
  8. package/dist/adapters/charts/run.d.ts.map +1 -1
  9. package/dist/adapters/charts/run.js +83 -16
  10. package/dist/adapters/charts/run.js.map +1 -1
  11. package/dist/adapters/charts/surfaces.d.ts +17 -0
  12. package/dist/adapters/charts/surfaces.d.ts.map +1 -1
  13. package/dist/adapters/charts/tables.js +82 -0
  14. package/dist/adapters/charts/tables.js.map +1 -1
  15. package/dist/adapters/charts/venue.d.ts +73 -0
  16. package/dist/adapters/charts/venue.d.ts.map +1 -0
  17. package/dist/adapters/charts/venue.js +104 -0
  18. package/dist/adapters/charts/venue.js.map +1 -0
  19. package/dist/adapters/codemirror/commands.d.ts +14 -0
  20. package/dist/adapters/codemirror/commands.d.ts.map +1 -0
  21. package/dist/adapters/codemirror/commands.js +52 -0
  22. package/dist/adapters/codemirror/commands.js.map +1 -0
  23. package/dist/adapters/codemirror/completion.d.ts +15 -0
  24. package/dist/adapters/codemirror/completion.d.ts.map +1 -0
  25. package/dist/adapters/codemirror/completion.js +64 -0
  26. package/dist/adapters/codemirror/completion.js.map +1 -0
  27. package/dist/adapters/codemirror/contract.d.ts +156 -0
  28. package/dist/adapters/codemirror/contract.d.ts.map +1 -0
  29. package/dist/adapters/codemirror/contract.js +42 -0
  30. package/dist/adapters/codemirror/contract.js.map +1 -0
  31. package/dist/adapters/codemirror/index.d.ts +43 -0
  32. package/dist/adapters/codemirror/index.d.ts.map +1 -0
  33. package/dist/adapters/codemirror/index.js +8 -0
  34. package/dist/adapters/codemirror/index.js.map +1 -0
  35. package/dist/adapters/codemirror/lint.d.ts +17 -0
  36. package/dist/adapters/codemirror/lint.d.ts.map +1 -0
  37. package/dist/adapters/codemirror/lint.js +62 -0
  38. package/dist/adapters/codemirror/lint.js.map +1 -0
  39. package/dist/adapters/codemirror/positions.d.ts +16 -0
  40. package/dist/adapters/codemirror/positions.d.ts.map +1 -0
  41. package/dist/adapters/codemirror/positions.js +65 -0
  42. package/dist/adapters/codemirror/positions.js.map +1 -0
  43. package/dist/adapters/codemirror/stream.d.ts +23 -0
  44. package/dist/adapters/codemirror/stream.d.ts.map +1 -0
  45. package/dist/adapters/codemirror/stream.js +70 -0
  46. package/dist/adapters/codemirror/stream.js.map +1 -0
  47. package/dist/adapters/codemirror/tokens.d.ts +44 -0
  48. package/dist/adapters/codemirror/tokens.d.ts.map +1 -0
  49. package/dist/adapters/codemirror/tokens.js +34 -0
  50. package/dist/adapters/codemirror/tokens.js.map +1 -0
  51. package/dist/adapters/codemirror/tooltips.d.ts +35 -0
  52. package/dist/adapters/codemirror/tooltips.d.ts.map +1 -0
  53. package/dist/adapters/codemirror/tooltips.js +108 -0
  54. package/dist/adapters/codemirror/tooltips.js.map +1 -0
  55. package/dist/core/accounting/analysis.d.ts +111 -0
  56. package/dist/core/accounting/analysis.d.ts.map +1 -0
  57. package/dist/core/accounting/analysis.js +123 -0
  58. package/dist/core/accounting/analysis.js.map +1 -0
  59. package/dist/core/accounting/charges.d.ts +136 -0
  60. package/dist/core/accounting/charges.d.ts.map +1 -0
  61. package/dist/core/accounting/charges.js +362 -0
  62. package/dist/core/accounting/charges.js.map +1 -0
  63. package/dist/core/accounting/equity.d.ts +191 -0
  64. package/dist/core/accounting/equity.d.ts.map +1 -0
  65. package/dist/core/accounting/equity.js +167 -0
  66. package/dist/core/accounting/equity.js.map +1 -0
  67. package/dist/core/accounting/index.d.ts +46 -0
  68. package/dist/core/accounting/index.d.ts.map +1 -0
  69. package/dist/core/accounting/index.js +37 -0
  70. package/dist/core/accounting/index.js.map +1 -0
  71. package/dist/core/accounting/markers.d.ts +43 -0
  72. package/dist/core/accounting/markers.d.ts.map +1 -0
  73. package/dist/core/accounting/markers.js +64 -0
  74. package/dist/core/accounting/markers.js.map +1 -0
  75. package/dist/core/accounting/monthly.d.ts +52 -0
  76. package/dist/core/accounting/monthly.d.ts.map +1 -0
  77. package/dist/core/accounting/monthly.js +99 -0
  78. package/dist/core/accounting/monthly.js.map +1 -0
  79. package/dist/core/accounting/report.d.ts +41 -0
  80. package/dist/core/accounting/report.d.ts.map +1 -0
  81. package/dist/core/accounting/report.js +65 -0
  82. package/dist/core/accounting/report.js.map +1 -0
  83. package/dist/core/accounting/shapes.d.ts +70 -0
  84. package/dist/core/accounting/shapes.d.ts.map +1 -0
  85. package/dist/core/accounting/shapes.js +21 -0
  86. package/dist/core/accounting/shapes.js.map +1 -0
  87. package/dist/core/accounting/statistics.d.ts +87 -0
  88. package/dist/core/accounting/statistics.d.ts.map +1 -0
  89. package/dist/core/accounting/statistics.js +268 -0
  90. package/dist/core/accounting/statistics.js.map +1 -0
  91. package/dist/core/accounting/trades.d.ts +118 -0
  92. package/dist/core/accounting/trades.d.ts.map +1 -0
  93. package/dist/core/accounting/trades.js +186 -0
  94. package/dist/core/accounting/trades.js.map +1 -0
  95. package/dist/core/backtest/case.d.ts +60 -0
  96. package/dist/core/backtest/case.d.ts.map +1 -0
  97. package/dist/core/backtest/case.js +319 -0
  98. package/dist/core/backtest/case.js.map +1 -0
  99. package/dist/core/backtest/compare.d.ts +38 -0
  100. package/dist/core/backtest/compare.d.ts.map +1 -0
  101. package/dist/core/backtest/compare.js +191 -0
  102. package/dist/core/backtest/compare.js.map +1 -0
  103. package/dist/core/backtest/declaration.d.ts +52 -0
  104. package/dist/core/backtest/declaration.d.ts.map +1 -0
  105. package/dist/core/backtest/declaration.js +48 -0
  106. package/dist/core/backtest/declaration.js.map +1 -0
  107. package/dist/core/backtest/deliver.d.ts +93 -0
  108. package/dist/core/backtest/deliver.d.ts.map +1 -0
  109. package/dist/core/backtest/deliver.js +94 -0
  110. package/dist/core/backtest/deliver.js.map +1 -0
  111. package/dist/core/backtest/drive.d.ts +87 -0
  112. package/dist/core/backtest/drive.d.ts.map +1 -0
  113. package/dist/core/backtest/drive.js +312 -0
  114. package/dist/core/backtest/drive.js.map +1 -0
  115. package/dist/core/backtest/index.d.ts +58 -0
  116. package/dist/core/backtest/index.d.ts.map +1 -0
  117. package/dist/core/backtest/index.js +47 -0
  118. package/dist/core/backtest/index.js.map +1 -0
  119. package/dist/core/backtest/range.d.ts +84 -0
  120. package/dist/core/backtest/range.d.ts.map +1 -0
  121. package/dist/core/backtest/range.js +90 -0
  122. package/dist/core/backtest/range.js.map +1 -0
  123. package/dist/core/backtest/record.d.ts +299 -0
  124. package/dist/core/backtest/record.d.ts.map +1 -0
  125. package/dist/core/backtest/record.js +243 -0
  126. package/dist/core/backtest/record.js.map +1 -0
  127. package/dist/core/backtest/replay.d.ts +48 -0
  128. package/dist/core/backtest/replay.d.ts.map +1 -0
  129. package/dist/core/backtest/replay.js +137 -0
  130. package/dist/core/backtest/replay.js.map +1 -0
  131. package/dist/core/backtest/resting.d.ts +62 -0
  132. package/dist/core/backtest/resting.d.ts.map +1 -0
  133. package/dist/core/backtest/resting.js +59 -0
  134. package/dist/core/backtest/resting.js.map +1 -0
  135. package/dist/core/backtest/settings.d.ts +117 -0
  136. package/dist/core/backtest/settings.d.ts.map +1 -0
  137. package/dist/core/backtest/settings.js +207 -0
  138. package/dist/core/backtest/settings.js.map +1 -0
  139. package/dist/core/backtest/simulate.d.ts +258 -0
  140. package/dist/core/backtest/simulate.d.ts.map +1 -0
  141. package/dist/core/backtest/simulate.js +335 -0
  142. package/dist/core/backtest/simulate.js.map +1 -0
  143. package/dist/core/catalogue/catalogue.generated.d.ts +66 -0
  144. package/dist/core/catalogue/catalogue.generated.d.ts.map +1 -1
  145. package/dist/core/catalogue/catalogue.generated.js +6 -0
  146. package/dist/core/catalogue/catalogue.generated.js.map +1 -1
  147. package/dist/core/catalogue/values.generated.d.ts +24 -0
  148. package/dist/core/catalogue/values.generated.d.ts.map +1 -1
  149. package/dist/core/check/index.d.ts +2 -1
  150. package/dist/core/check/index.d.ts.map +1 -1
  151. package/dist/core/check/index.js +1 -1
  152. package/dist/core/check/index.js.map +1 -1
  153. package/dist/core/check/library-orders.js +2 -2
  154. package/dist/core/check/library-orders.js.map +1 -1
  155. package/dist/core/check/library-prose.generated.d.ts +16 -0
  156. package/dist/core/check/library-prose.generated.d.ts.map +1 -0
  157. package/dist/core/check/library-prose.generated.js +353 -0
  158. package/dist/core/check/library-prose.generated.js.map +1 -0
  159. package/dist/core/check/surface.d.ts +24 -0
  160. package/dist/core/check/surface.d.ts.map +1 -1
  161. package/dist/core/check/surface.js +29 -0
  162. package/dist/core/check/surface.js.map +1 -1
  163. package/dist/core/emit/canonical.d.ts +22 -8
  164. package/dist/core/emit/canonical.d.ts.map +1 -1
  165. package/dist/core/emit/canonical.js +67 -6
  166. package/dist/core/emit/canonical.js.map +1 -1
  167. package/dist/core/emit/defaults.d.ts +35 -16
  168. package/dist/core/emit/defaults.d.ts.map +1 -1
  169. package/dist/core/emit/defaults.js +66 -0
  170. package/dist/core/emit/defaults.js.map +1 -1
  171. package/dist/core/emit/index.d.ts +2 -0
  172. package/dist/core/emit/index.d.ts.map +1 -1
  173. package/dist/core/emit/index.js +2 -0
  174. package/dist/core/emit/index.js.map +1 -1
  175. package/dist/core/engine/arithmetic.d.ts +6 -25
  176. package/dist/core/engine/arithmetic.d.ts.map +1 -1
  177. package/dist/core/engine/arithmetic.js +48 -3
  178. package/dist/core/engine/arithmetic.js.map +1 -1
  179. package/dist/core/engine/index.d.ts +2 -2
  180. package/dist/core/engine/index.d.ts.map +1 -1
  181. package/dist/core/engine/index.js +2 -2
  182. package/dist/core/engine/index.js.map +1 -1
  183. package/dist/core/engine/library/arrays.d.ts.map +1 -1
  184. package/dist/core/engine/library/arrays.js +8 -2
  185. package/dist/core/engine/library/arrays.js.map +1 -1
  186. package/dist/core/engine/library/code-points.d.ts +40 -0
  187. package/dist/core/engine/library/code-points.d.ts.map +1 -0
  188. package/dist/core/engine/library/code-points.js +74 -0
  189. package/dist/core/engine/library/code-points.js.map +1 -0
  190. package/dist/core/engine/library/index.d.ts +5 -0
  191. package/dist/core/engine/library/index.d.ts.map +1 -1
  192. package/dist/core/engine/library/index.js +5 -0
  193. package/dist/core/engine/library/index.js.map +1 -1
  194. package/dist/core/engine/library/text.d.ts.map +1 -1
  195. package/dist/core/engine/library/text.js +51 -34
  196. package/dist/core/engine/library/text.js.map +1 -1
  197. package/dist/core/engine/load.d.ts +35 -1
  198. package/dist/core/engine/load.d.ts.map +1 -1
  199. package/dist/core/engine/load.js +63 -0
  200. package/dist/core/engine/load.js.map +1 -1
  201. package/dist/core/engine/verify-tables.d.ts.map +1 -1
  202. package/dist/core/engine/verify-tables.js +41 -0
  203. package/dist/core/engine/verify-tables.js.map +1 -1
  204. package/dist/core/index.d.ts +43 -4
  205. package/dist/core/index.d.ts.map +1 -1
  206. package/dist/core/index.js +23 -2
  207. package/dist/core/index.js.map +1 -1
  208. package/dist/core/stdlib/index.d.ts +1 -1
  209. package/dist/core/stdlib/index.d.ts.map +1 -1
  210. package/dist/core/stdlib/index.js +1 -1
  211. package/dist/core/stdlib/index.js.map +1 -1
  212. package/dist/core/stdlib/maths/index.d.ts +1 -1
  213. package/dist/core/stdlib/maths/index.d.ts.map +1 -1
  214. package/dist/core/stdlib/maths/index.js +1 -1
  215. package/dist/core/stdlib/maths/index.js.map +1 -1
  216. package/dist/core/stdlib/maths/rounding.d.ts +5 -0
  217. package/dist/core/stdlib/maths/rounding.d.ts.map +1 -1
  218. package/dist/core/stdlib/maths/rounding.js +19 -1
  219. package/dist/core/stdlib/maths/rounding.js.map +1 -1
  220. package/dist/core/version/version.generated.d.ts +1 -1
  221. package/dist/core/version/version.generated.js +1 -1
  222. package/dist/editor/complete.d.ts +40 -0
  223. package/dist/editor/complete.d.ts.map +1 -0
  224. package/dist/editor/complete.js +206 -0
  225. package/dist/editor/complete.js.map +1 -0
  226. package/dist/editor/diagnose.d.ts +18 -0
  227. package/dist/editor/diagnose.d.ts.map +1 -0
  228. package/dist/editor/diagnose.js +70 -0
  229. package/dist/editor/diagnose.js.map +1 -0
  230. package/dist/editor/format.d.ts +11 -0
  231. package/dist/editor/format.d.ts.map +1 -0
  232. package/dist/editor/format.js +50 -0
  233. package/dist/editor/format.js.map +1 -0
  234. package/dist/editor/highlight.d.ts +28 -0
  235. package/dist/editor/highlight.d.ts.map +1 -0
  236. package/dist/editor/highlight.js +65 -0
  237. package/dist/editor/highlight.js.map +1 -0
  238. package/dist/editor/hover.d.ts +40 -0
  239. package/dist/editor/hover.d.ts.map +1 -0
  240. package/dist/editor/hover.js +147 -0
  241. package/dist/editor/hover.js.map +1 -0
  242. package/dist/editor/index.d.ts +60 -0
  243. package/dist/editor/index.d.ts.map +1 -0
  244. package/dist/editor/index.js +7 -0
  245. package/dist/editor/index.js.map +1 -0
  246. package/dist/editor/kinds.d.ts +27 -0
  247. package/dist/editor/kinds.d.ts.map +1 -0
  248. package/dist/editor/kinds.js +118 -0
  249. package/dist/editor/kinds.js.map +1 -0
  250. package/dist/editor/layout.d.ts +47 -0
  251. package/dist/editor/layout.d.ts.map +1 -0
  252. package/dist/editor/layout.js +135 -0
  253. package/dist/editor/layout.js.map +1 -0
  254. package/dist/editor/manifest.d.ts +47 -0
  255. package/dist/editor/manifest.d.ts.map +1 -0
  256. package/dist/editor/manifest.js +93 -0
  257. package/dist/editor/manifest.js.map +1 -0
  258. package/dist/editor/reading.d.ts +41 -0
  259. package/dist/editor/reading.d.ts.map +1 -0
  260. package/dist/editor/reading.js +51 -0
  261. package/dist/editor/reading.js.map +1 -0
  262. package/dist/editor/scan.d.ts +26 -0
  263. package/dist/editor/scan.d.ts.map +1 -0
  264. package/dist/editor/scan.js +139 -0
  265. package/dist/editor/scan.js.map +1 -0
  266. package/dist/editor/scope.d.ts +19 -0
  267. package/dist/editor/scope.d.ts.map +1 -0
  268. package/dist/editor/scope.js +99 -0
  269. package/dist/editor/scope.js.map +1 -0
  270. package/dist/editor/signature.d.ts +38 -0
  271. package/dist/editor/signature.d.ts.map +1 -0
  272. package/dist/editor/signature.js +112 -0
  273. package/dist/editor/signature.js.map +1 -0
  274. package/dist/editor/site.d.ts +46 -0
  275. package/dist/editor/site.d.ts.map +1 -0
  276. package/dist/editor/site.js +184 -0
  277. package/dist/editor/site.js.map +1 -0
  278. package/dist/editor/spacing.d.ts +29 -0
  279. package/dist/editor/spacing.d.ts.map +1 -0
  280. package/dist/editor/spacing.js +116 -0
  281. package/dist/editor/spacing.js.map +1 -0
  282. package/package.json +42 -3
  283. package/spec/README.md +2 -1
  284. package/spec/errors.json +141 -1
  285. package/src/adapters/charts/driving.ts +109 -0
  286. package/src/adapters/charts/run.ts +120 -28
  287. package/src/adapters/charts/surfaces.ts +17 -0
  288. package/src/adapters/charts/tables.ts +88 -0
  289. package/src/adapters/charts/venue.ts +132 -0
  290. package/src/adapters/codemirror/commands.ts +53 -0
  291. package/src/adapters/codemirror/completion.ts +74 -0
  292. package/src/adapters/codemirror/contract.ts +156 -0
  293. package/src/adapters/codemirror/index.ts +66 -0
  294. package/src/adapters/codemirror/lint.ts +66 -0
  295. package/src/adapters/codemirror/positions.ts +79 -0
  296. package/src/adapters/codemirror/stream.ts +87 -0
  297. package/src/adapters/codemirror/tokens.ts +64 -0
  298. package/src/adapters/codemirror/tooltips.ts +113 -0
  299. package/src/core/accounting/analysis.ts +188 -0
  300. package/src/core/accounting/charges.ts +452 -0
  301. package/src/core/accounting/equity.ts +314 -0
  302. package/src/core/accounting/index.ts +51 -0
  303. package/src/core/accounting/markers.ts +95 -0
  304. package/src/core/accounting/monthly.ts +137 -0
  305. package/src/core/accounting/report.ts +94 -0
  306. package/src/core/accounting/shapes.ts +73 -0
  307. package/src/core/accounting/statistics.ts +387 -0
  308. package/src/core/accounting/trades.ts +313 -0
  309. package/src/core/backtest/case.ts +395 -0
  310. package/src/core/backtest/compare.ts +246 -0
  311. package/src/core/backtest/declaration.ts +97 -0
  312. package/src/core/backtest/deliver.ts +161 -0
  313. package/src/core/backtest/drive.ts +468 -0
  314. package/src/core/backtest/index.ts +64 -0
  315. package/src/core/backtest/range.ts +137 -0
  316. package/src/core/backtest/record.ts +470 -0
  317. package/src/core/backtest/replay.ts +168 -0
  318. package/src/core/backtest/resting.ts +125 -0
  319. package/src/core/backtest/settings.ts +280 -0
  320. package/src/core/backtest/simulate.ts +499 -0
  321. package/src/core/catalogue/catalogue.generated.ts +6 -0
  322. package/src/core/catalogue/values.generated.ts +6 -0
  323. package/src/core/check/index.ts +3 -0
  324. package/src/core/check/library-orders.ts +2 -2
  325. package/src/core/check/library-prose.generated.ts +367 -0
  326. package/src/core/check/surface.ts +34 -0
  327. package/src/core/emit/canonical.ts +67 -9
  328. package/src/core/emit/defaults.ts +70 -0
  329. package/src/core/emit/index.ts +2 -0
  330. package/src/core/engine/arithmetic.ts +23 -3
  331. package/src/core/engine/index.ts +2 -2
  332. package/src/core/engine/library/arrays.ts +8 -2
  333. package/src/core/engine/library/code-points.ts +73 -0
  334. package/src/core/engine/library/index.ts +6 -0
  335. package/src/core/engine/library/text.ts +53 -35
  336. package/src/core/engine/load.ts +84 -2
  337. package/src/core/engine/verify-tables.ts +43 -0
  338. package/src/core/index.ts +100 -2
  339. package/src/core/stdlib/index.ts +1 -0
  340. package/src/core/stdlib/maths/index.ts +1 -0
  341. package/src/core/stdlib/maths/rounding.ts +23 -1
  342. package/src/core/version/version.generated.ts +1 -1
  343. package/src/editor/complete.ts +266 -0
  344. package/src/editor/diagnose.ts +71 -0
  345. package/src/editor/format.ts +85 -0
  346. package/src/editor/highlight.ts +110 -0
  347. package/src/editor/hover.ts +199 -0
  348. package/src/editor/index.ts +65 -0
  349. package/src/editor/kinds.ts +157 -0
  350. package/src/editor/layout.ts +189 -0
  351. package/src/editor/manifest.ts +119 -0
  352. package/src/editor/reading.ts +69 -0
  353. package/src/editor/scan.ts +162 -0
  354. package/src/editor/scope.ts +122 -0
  355. package/src/editor/signature.ts +150 -0
  356. package/src/editor/site.ts +233 -0
  357. package/src/editor/spacing.ts +132 -0
@@ -0,0 +1,97 @@
1
+ /**
2
+ * The declaration's own half of a run, read once and read here.
3
+ *
4
+ * **What the program states is stored once, as the program**, so none of these
5
+ * figures is a setting a host chooses and none of them travels in the record
6
+ * beside the settings. They are read back out of the compiled program every
7
+ * time a run is driven or replayed, which is what makes a replay of a stored
8
+ * record the same run rather than a run under today's defaults.
9
+ *
10
+ * Every field of `meta.strategy` is written into the program with the value it
11
+ * resolved to, defaults included (`compiled-program.md` 2.3), so nothing here
12
+ * carries a table of defaults and a default that changes in a later language
13
+ * version cannot silently change an old program. A field a script wrote with an
14
+ * `input()` is resolved against the run's own settings, by the engine, at load,
15
+ * and `fieldValue` reads what that resolution produced: the rule lives in the
16
+ * engine and is applied here rather than repeated.
17
+ *
18
+ * A study has no strategy declaration at all. It places no order and has no
19
+ * money, and it reads here as the absence it is rather than as a zero capital
20
+ * somebody would divide by.
21
+ */
22
+ import type { CompiledProgram } from '../emit/index.js';
23
+ import { fieldValue } from '../engine/index.js';
24
+ import type { ResolvedInput, Value } from '../engine/index.js';
25
+
26
+ /** The money and the fill the declaration fixed before bar 0. */
27
+ export interface RunDeclaration {
28
+ /** False for a study, which declares none of this. */
29
+ readonly isStrategy: boolean;
30
+ readonly capital: number;
31
+ readonly currency: string;
32
+ /** Where a market order is priced, `language.md` 13.3. */
33
+ readonly fillOn: string;
34
+ readonly slippage: number;
35
+ readonly commission: number;
36
+ readonly commissionType: string;
37
+ /**
38
+ * The unit the declaration's quantity is stated in, `language.md` 13.3.
39
+ *
40
+ * Read here because the destination is the party that has to convert it, and
41
+ * a destination that cannot convert the unit a strategy sizes in has to
42
+ * refuse the run rather than fill a number in the wrong unit.
43
+ */
44
+ readonly qtyType: string;
45
+ }
46
+
47
+ /**
48
+ * What one program's declaration says about money, after its inputs.
49
+ *
50
+ * The inputs are the ones the engine resolved at load, handed back by `load`
51
+ * for this reader. A caller with none reads the literals, which is every
52
+ * program that did not write a declaration field with an `input()`.
53
+ */
54
+ export function declarationOf(
55
+ program: CompiledProgram,
56
+ inputs: readonly ResolvedInput[] = [],
57
+ ): RunDeclaration {
58
+ const strategy = program.meta.strategy;
59
+ if (strategy === undefined) {
60
+ return {
61
+ isStrategy: false,
62
+ capital: 0,
63
+ currency: '',
64
+ fillOn: '',
65
+ slippage: 0,
66
+ commission: 0,
67
+ commissionType: '',
68
+ qtyType: '',
69
+ };
70
+ }
71
+ return {
72
+ isStrategy: true,
73
+ capital: numberOf(fieldValue(strategy.capital, inputs)),
74
+ currency: stringOf(fieldValue(strategy.currency, inputs)),
75
+ fillOn: stringOf(fieldValue(strategy.fillOn, inputs)),
76
+ slippage: numberOf(fieldValue(strategy.slippage, inputs)),
77
+ commission: numberOf(fieldValue(strategy.commission, inputs)),
78
+ commissionType: stringOf(fieldValue(strategy.commissionType, inputs)),
79
+ qtyType: stringOf(fieldValue(strategy.qtyType, inputs)),
80
+ };
81
+ }
82
+
83
+ /**
84
+ * A number the declaration states, or zero where it states something else.
85
+ *
86
+ * Zero rather than absence, and only here: every one of these fields is written
87
+ * into the program with a number, so anything else is a program this engine
88
+ * would already have refused at load. The fallback is what keeps this reader
89
+ * total rather than a second place a malformed program is diagnosed.
90
+ */
91
+ function numberOf(value: Value): number {
92
+ return typeof value === 'number' && Number.isFinite(value) ? value : 0;
93
+ }
94
+
95
+ function stringOf(value: Value): string {
96
+ return typeof value === 'string' ? value : '';
97
+ }
@@ -0,0 +1,161 @@
1
+ /**
2
+ * A case's rows and this engine's frames, and the destination between them.
3
+ *
4
+ * Both directions are here because they are one correspondence: a case names an
5
+ * order by an ordinal and an engine knows it by an id, so `Delivery` reads an
6
+ * ordinal into the id of the intent the run placed, and `framedAs` writes an id
7
+ * back out as the ordinal a case file prints. Split between two files, the two
8
+ * halves of it drift, and a suite whose rows say one thing and whose records
9
+ * say another is one nobody can read.
10
+ *
11
+ * `conformance.md` section 3: `frames.csv` supplies order frames the way
12
+ * `bars.csv` supplies bars, so a strategy case asserts the fold against input
13
+ * the engine did not choose. `simulate.ts` is the other destination this module
14
+ * has, the one that reads a bar and works out what a venue would have said.
15
+ * This one works nothing out. It holds the rows a case supplied, hands over the
16
+ * ones each boundary names, and the whole of its behaviour is the mapping
17
+ * between a row and a frame.
18
+ *
19
+ * **An ordinal is what a case can name, and an id is not.** A row names the nth
20
+ * intent the run placed, because no case can know the id an engine minted, so
21
+ * the intents are counted here in the order the run handed them over and the
22
+ * ordinal is read against that count. A row naming an ordinal the run never
23
+ * placed is delivered all the same, carrying an id no run mints: step 1 of
24
+ * `stdlib.md` 17.8 refuses a frame naming no row of the ledger, and that
25
+ * refusal is the ledger's to make. A destination that dropped the row instead
26
+ * would answer nothing at all where section 3 hands an engine a frame about an
27
+ * order its ledger does not hold, and the case would pass by the frame never
28
+ * having arrived.
29
+ *
30
+ * **What a row does not carry, this does not invent.** `host-interface.md` 7.2
31
+ * lets a frame say which instrument and product the destination booked the
32
+ * order under, and the file has no column for either, so neither is stated and
33
+ * the row keeps what its placement put there. The instant is the one the file
34
+ * does carry: a row states one or states `none`, and one that states none
35
+ * leaves `updatedAt` where the placement put it, which is what the fold does
36
+ * with a frame whose destination stated no instant.
37
+ */
38
+ import type { OrderFrame, OrderIntent, RoutedEffect } from '../engine/index.js';
39
+ import type { RecordedFrame } from './record.js';
40
+
41
+ /** One frame, the boundary it was handed over at, and the row it came from. */
42
+ export interface Delivered {
43
+ readonly frame: OrderFrame;
44
+ readonly afterBar: number;
45
+ /**
46
+ * The row a case supplied, or null where the run's own destination answered
47
+ * the frame and there is no row until the record is written.
48
+ */
49
+ readonly row: RecordedFrame | null;
50
+ }
51
+
52
+ /** Where a run's orders go, and what it is told between two of its bars. */
53
+ export interface Destination {
54
+ /** Step 9: what the strategy decided, on the bar it decided it. */
55
+ route(effect: RoutedEffect, barIndex: number): void;
56
+ /** What this destination hands over at the boundary after `barIndex`. */
57
+ answers(barIndex: number): readonly Delivered[];
58
+ /** Every intent it was handed, in the order it was handed them. */
59
+ readonly intents: readonly OrderIntent[];
60
+ }
61
+
62
+ /**
63
+ * An id no run mints, which a row naming no intent of this run is delivered
64
+ * under.
65
+ *
66
+ * Ids are counted from one by the ledger that mints them, so nothing below one
67
+ * can name a row and the fold refuses the frame by the rule it refuses every
68
+ * other unknown one by. The alternative was an id of a real row chosen by some
69
+ * rule of this file's own, which would fold a case's frame into whichever order
70
+ * happened to be near it.
71
+ */
72
+ const NO_INTENT = -1;
73
+
74
+ /**
75
+ * A destination holding one case's frames, ready at the boundaries they name.
76
+ *
77
+ * Built before the run rather than during it, because the rows are input: what
78
+ * a boundary hands over was decided by whoever wrote the case and not by
79
+ * anything this run does. The one thing it learns as the run goes is which
80
+ * intent an ordinal names, which only the run can say.
81
+ */
82
+ export class Delivery implements Destination {
83
+ readonly intents: OrderIntent[] = [];
84
+ /** The rows of each boundary, in file order, which section 3 fixes as the delivery order. */
85
+ private readonly rows = new Map<number, RecordedFrame[]>();
86
+
87
+ constructor(frames: readonly RecordedFrame[]) {
88
+ for (const row of frames) {
89
+ const at = this.rows.get(row.afterBar);
90
+ if (at === undefined) this.rows.set(row.afterBar, [row]);
91
+ else at.push(row);
92
+ }
93
+ }
94
+
95
+ /** Nothing is decided by an order arriving here: it is counted, and that is all. */
96
+ route(effect: RoutedEffect): void {
97
+ for (const intent of effect.intents) this.intents.push(intent);
98
+ }
99
+
100
+ answers(barIndex: number): readonly Delivered[] {
101
+ const due = this.rows.get(barIndex) ?? [];
102
+ return due.map((row) => ({
103
+ frame: frameOf(row, this.intents[row.intent - 1]),
104
+ afterBar: barIndex,
105
+ row,
106
+ }));
107
+ }
108
+ }
109
+
110
+ /** One row of a case, as the frame `host-interface.md` 7.2 describes. */
111
+ function frameOf(row: RecordedFrame, intent: OrderIntent | undefined): OrderFrame {
112
+ return {
113
+ intentId: intent?.intentId ?? NO_INTENT,
114
+ status: row.status,
115
+ filledQty: row.filledQty,
116
+ avgFillPrice: row.avgFillPrice,
117
+ orderRef: row.orderRef,
118
+ text: row.text,
119
+ time: row.time,
120
+ };
121
+ }
122
+
123
+ /**
124
+ * The ordinal of every intent, which is how a case names one.
125
+ *
126
+ * One, two, three in the order the run placed them, because no engine can know
127
+ * the id another minted and a case that named one would only ever be readable
128
+ * by the engine that wrote it.
129
+ */
130
+ export function ordinalsOf(intents: readonly OrderIntent[]): ReadonlyMap<number, number> {
131
+ const out = new Map<number, number>();
132
+ for (const intent of intents) {
133
+ if (!out.has(intent.intentId)) out.set(intent.intentId, out.size + 1);
134
+ }
135
+ return out;
136
+ }
137
+
138
+ /**
139
+ * One delivered frame, in the columns a case file prints.
140
+ *
141
+ * The instant travels with it. `stdlib.md` 17.7 folds `updatedAt` from a
142
+ * frame's `time`, so a driver that dropped the field here wrote a record whose
143
+ * ledger no engine could fold from the record's own frames: it would have
144
+ * nothing to move that field to and would leave it at `placedAt`.
145
+ */
146
+ export function framedAs(
147
+ frame: OrderFrame,
148
+ afterBar: number,
149
+ ordinals: ReadonlyMap<number, number>,
150
+ ): RecordedFrame {
151
+ return {
152
+ afterBar,
153
+ intent: ordinals.get(frame.intentId) ?? 0,
154
+ status: frame.status,
155
+ filledQty: frame.filledQty,
156
+ avgFillPrice: frame.avgFillPrice ?? null,
157
+ orderRef: frame.orderRef ?? null,
158
+ text: frame.text ?? null,
159
+ time: frame.time ?? null,
160
+ };
161
+ }