openalgo-script 0.4.0 → 0.6.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 (359) hide show
  1. package/CHANGELOG.md +1050 -0
  2. package/README.md +111 -27
  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 +89 -16
  10. package/dist/adapters/charts/run.js.map +1 -1
  11. package/dist/adapters/charts/tables.d.ts +6 -19
  12. package/dist/adapters/charts/tables.d.ts.map +1 -1
  13. package/dist/adapters/charts/tables.js.map +1 -1
  14. package/dist/adapters/charts/undrawable.d.ts +4 -0
  15. package/dist/adapters/charts/undrawable.d.ts.map +1 -0
  16. package/dist/adapters/charts/undrawable.js +47 -0
  17. package/dist/adapters/charts/undrawable.js.map +1 -0
  18. package/dist/adapters/charts/venue.d.ts +73 -0
  19. package/dist/adapters/charts/venue.d.ts.map +1 -0
  20. package/dist/adapters/charts/venue.js +104 -0
  21. package/dist/adapters/charts/venue.js.map +1 -0
  22. package/dist/core/accounting/analysis.d.ts +111 -0
  23. package/dist/core/accounting/analysis.d.ts.map +1 -0
  24. package/dist/core/accounting/analysis.js +123 -0
  25. package/dist/core/accounting/analysis.js.map +1 -0
  26. package/dist/core/accounting/equity.d.ts +33 -0
  27. package/dist/core/accounting/equity.d.ts.map +1 -1
  28. package/dist/core/accounting/equity.js +12 -0
  29. package/dist/core/accounting/equity.js.map +1 -1
  30. package/dist/core/accounting/index.d.ts +2 -0
  31. package/dist/core/accounting/index.d.ts.map +1 -1
  32. package/dist/core/accounting/index.js +1 -0
  33. package/dist/core/accounting/index.js.map +1 -1
  34. package/dist/core/accounting/report.d.ts +3 -0
  35. package/dist/core/accounting/report.d.ts.map +1 -1
  36. package/dist/core/accounting/report.js +2 -0
  37. package/dist/core/accounting/report.js.map +1 -1
  38. package/dist/core/accounting/statistics.d.ts +12 -0
  39. package/dist/core/accounting/statistics.d.ts.map +1 -1
  40. package/dist/core/accounting/statistics.js +23 -1
  41. package/dist/core/accounting/statistics.js.map +1 -1
  42. package/dist/core/backtest/case.d.ts +60 -0
  43. package/dist/core/backtest/case.d.ts.map +1 -0
  44. package/dist/core/backtest/case.js +319 -0
  45. package/dist/core/backtest/case.js.map +1 -0
  46. package/dist/core/backtest/compare.d.ts.map +1 -1
  47. package/dist/core/backtest/compare.js +2 -0
  48. package/dist/core/backtest/compare.js.map +1 -1
  49. package/dist/core/backtest/deliver.d.ts +93 -0
  50. package/dist/core/backtest/deliver.d.ts.map +1 -0
  51. package/dist/core/backtest/deliver.js +94 -0
  52. package/dist/core/backtest/deliver.js.map +1 -0
  53. package/dist/core/backtest/drive.d.ts +101 -8
  54. package/dist/core/backtest/drive.d.ts.map +1 -1
  55. package/dist/core/backtest/drive.js +114 -158
  56. package/dist/core/backtest/drive.js.map +1 -1
  57. package/dist/core/backtest/index.d.ts +26 -12
  58. package/dist/core/backtest/index.d.ts.map +1 -1
  59. package/dist/core/backtest/index.js +21 -10
  60. package/dist/core/backtest/index.js.map +1 -1
  61. package/dist/core/backtest/record.d.ts +63 -2
  62. package/dist/core/backtest/record.d.ts.map +1 -1
  63. package/dist/core/backtest/record.js +71 -4
  64. package/dist/core/backtest/record.js.map +1 -1
  65. package/dist/core/backtest/replay.d.ts.map +1 -1
  66. package/dist/core/backtest/replay.js +11 -1
  67. package/dist/core/backtest/replay.js.map +1 -1
  68. package/dist/core/backtest/simulate.d.ts +113 -1
  69. package/dist/core/backtest/simulate.d.ts.map +1 -1
  70. package/dist/core/backtest/simulate.js +123 -5
  71. package/dist/core/backtest/simulate.js.map +1 -1
  72. package/dist/core/backtest/walk.d.ts +39 -0
  73. package/dist/core/backtest/walk.d.ts.map +1 -0
  74. package/dist/core/backtest/walk.js +125 -0
  75. package/dist/core/backtest/walk.js.map +1 -0
  76. package/dist/core/catalogue/catalogue.generated.d.ts +179 -2
  77. package/dist/core/catalogue/catalogue.generated.d.ts.map +1 -1
  78. package/dist/core/catalogue/catalogue.generated.js +19 -2
  79. package/dist/core/catalogue/catalogue.generated.js.map +1 -1
  80. package/dist/core/catalogue/types.d.ts +8 -2
  81. package/dist/core/catalogue/types.d.ts.map +1 -1
  82. package/dist/core/catalogue/values.generated.d.ts +51 -0
  83. package/dist/core/catalogue/values.generated.d.ts.map +1 -1
  84. package/dist/core/check/assigned.d.ts +19 -0
  85. package/dist/core/check/assigned.d.ts.map +1 -0
  86. package/dist/core/check/assigned.js +14 -0
  87. package/dist/core/check/assigned.js.map +1 -0
  88. package/dist/core/check/call-sites.d.ts.map +1 -1
  89. package/dist/core/check/call-sites.js +9 -4
  90. package/dist/core/check/call-sites.js.map +1 -1
  91. package/dist/core/check/calls.d.ts.map +1 -1
  92. package/dist/core/check/calls.js +12 -4
  93. package/dist/core/check/calls.js.map +1 -1
  94. package/dist/core/check/check.d.ts.map +1 -1
  95. package/dist/core/check/check.js +15 -2
  96. package/dist/core/check/check.js.map +1 -1
  97. package/dist/core/check/checker.d.ts +26 -0
  98. package/dist/core/check/checker.d.ts.map +1 -1
  99. package/dist/core/check/checker.js +38 -2
  100. package/dist/core/check/checker.js.map +1 -1
  101. package/dist/core/check/constant.d.ts +16 -0
  102. package/dist/core/check/constant.d.ts.map +1 -1
  103. package/dist/core/check/constant.js +52 -0
  104. package/dist/core/check/constant.js.map +1 -1
  105. package/dist/core/check/deleted.d.ts +3 -0
  106. package/dist/core/check/deleted.d.ts.map +1 -0
  107. package/dist/core/check/deleted.js +109 -0
  108. package/dist/core/check/deleted.js.map +1 -0
  109. package/dist/core/check/expressions.js +1 -1
  110. package/dist/core/check/expressions.js.map +1 -1
  111. package/dist/core/check/library-orders.js +2 -2
  112. package/dist/core/check/library-orders.js.map +1 -1
  113. package/dist/core/check/library-output.d.ts.map +1 -1
  114. package/dist/core/check/library-output.js +1 -0
  115. package/dist/core/check/library-output.js.map +1 -1
  116. package/dist/core/check/library-prose.generated.js +12 -12
  117. package/dist/core/check/library-prose.generated.js.map +1 -1
  118. package/dist/core/check/library.d.ts +7 -0
  119. package/dist/core/check/library.d.ts.map +1 -1
  120. package/dist/core/check/library.js +1 -0
  121. package/dist/core/check/library.js.map +1 -1
  122. package/dist/core/check/surface.d.ts +9 -0
  123. package/dist/core/check/surface.d.ts.map +1 -1
  124. package/dist/core/check/surface.js +13 -0
  125. package/dist/core/check/surface.js.map +1 -1
  126. package/dist/core/emit/canonical.d.ts +22 -8
  127. package/dist/core/emit/canonical.d.ts.map +1 -1
  128. package/dist/core/emit/canonical.js +67 -6
  129. package/dist/core/emit/canonical.js.map +1 -1
  130. package/dist/core/engine/arithmetic.d.ts +6 -25
  131. package/dist/core/engine/arithmetic.d.ts.map +1 -1
  132. package/dist/core/engine/arithmetic.js +48 -3
  133. package/dist/core/engine/arithmetic.js.map +1 -1
  134. package/dist/core/engine/bar-source.d.ts +65 -0
  135. package/dist/core/engine/bar-source.d.ts.map +1 -0
  136. package/dist/core/engine/bar-source.js +58 -0
  137. package/dist/core/engine/bar-source.js.map +1 -0
  138. package/dist/core/engine/engine.d.ts +9 -11
  139. package/dist/core/engine/engine.d.ts.map +1 -1
  140. package/dist/core/engine/engine.js +24 -24
  141. package/dist/core/engine/engine.js.map +1 -1
  142. package/dist/core/engine/guard.d.ts.map +1 -1
  143. package/dist/core/engine/guard.js +10 -0
  144. package/dist/core/engine/guard.js.map +1 -1
  145. package/dist/core/engine/host.d.ts +4 -2
  146. package/dist/core/engine/host.d.ts.map +1 -1
  147. package/dist/core/engine/host.js.map +1 -1
  148. package/dist/core/engine/index.d.ts +2 -1
  149. package/dist/core/engine/index.d.ts.map +1 -1
  150. package/dist/core/engine/index.js +1 -1
  151. package/dist/core/engine/index.js.map +1 -1
  152. package/dist/core/engine/library/arrays.d.ts.map +1 -1
  153. package/dist/core/engine/library/arrays.js +8 -2
  154. package/dist/core/engine/library/arrays.js.map +1 -1
  155. package/dist/core/engine/library/binding.d.ts +2 -0
  156. package/dist/core/engine/library/binding.d.ts.map +1 -1
  157. package/dist/core/engine/library/binding.js.map +1 -1
  158. package/dist/core/engine/library/code-points.d.ts +40 -0
  159. package/dist/core/engine/library/code-points.d.ts.map +1 -0
  160. package/dist/core/engine/library/code-points.js +74 -0
  161. package/dist/core/engine/library/code-points.js.map +1 -0
  162. package/dist/core/engine/library/index.d.ts +13 -0
  163. package/dist/core/engine/library/index.d.ts.map +1 -1
  164. package/dist/core/engine/library/index.js +15 -0
  165. package/dist/core/engine/library/index.js.map +1 -1
  166. package/dist/core/engine/library/objects.d.ts.map +1 -1
  167. package/dist/core/engine/library/objects.js +1 -1
  168. package/dist/core/engine/library/objects.js.map +1 -1
  169. package/dist/core/engine/library/text.d.ts.map +1 -1
  170. package/dist/core/engine/library/text.js +51 -34
  171. package/dist/core/engine/library/text.js.map +1 -1
  172. package/dist/core/engine/load.d.ts +20 -0
  173. package/dist/core/engine/load.d.ts.map +1 -1
  174. package/dist/core/engine/load.js +62 -0
  175. package/dist/core/engine/load.js.map +1 -1
  176. package/dist/core/engine/request-body.d.ts +3 -1
  177. package/dist/core/engine/request-body.d.ts.map +1 -1
  178. package/dist/core/engine/request-body.js +3 -1
  179. package/dist/core/engine/request-body.js.map +1 -1
  180. package/dist/core/engine/request-plan.d.ts +3 -3
  181. package/dist/core/engine/request-plan.js +3 -3
  182. package/dist/core/engine/requests.d.ts +2 -2
  183. package/dist/core/engine/requests.d.ts.map +1 -1
  184. package/dist/core/engine/requests.js +5 -4
  185. package/dist/core/engine/requests.js.map +1 -1
  186. package/dist/core/engine/series.d.ts +18 -6
  187. package/dist/core/engine/series.d.ts.map +1 -1
  188. package/dist/core/engine/series.js +24 -5
  189. package/dist/core/engine/series.js.map +1 -1
  190. package/dist/core/engine/session/record.d.ts +4 -4
  191. package/dist/core/engine/session/record.js +4 -4
  192. package/dist/core/engine/verify-tables.d.ts.map +1 -1
  193. package/dist/core/engine/verify-tables.js +41 -0
  194. package/dist/core/engine/verify-tables.js.map +1 -1
  195. package/dist/core/importer/calls.d.ts +29 -0
  196. package/dist/core/importer/calls.d.ts.map +1 -0
  197. package/dist/core/importer/calls.js +267 -0
  198. package/dist/core/importer/calls.js.map +1 -0
  199. package/dist/core/importer/context.d.ts +118 -0
  200. package/dist/core/importer/context.d.ts.map +1 -0
  201. package/dist/core/importer/context.js +120 -0
  202. package/dist/core/importer/context.js.map +1 -0
  203. package/dist/core/importer/expressions.d.ts +44 -0
  204. package/dist/core/importer/expressions.d.ts.map +1 -0
  205. package/dist/core/importer/expressions.js +223 -0
  206. package/dist/core/importer/expressions.js.map +1 -0
  207. package/dist/core/importer/importer.d.ts +13 -0
  208. package/dist/core/importer/importer.d.ts.map +1 -0
  209. package/dist/core/importer/importer.js +220 -0
  210. package/dist/core/importer/importer.js.map +1 -0
  211. package/dist/core/importer/index.d.ts +20 -0
  212. package/dist/core/importer/index.d.ts.map +1 -0
  213. package/dist/core/importer/index.js +18 -0
  214. package/dist/core/importer/index.js.map +1 -0
  215. package/dist/core/importer/lexer.d.ts +68 -0
  216. package/dist/core/importer/lexer.d.ts.map +1 -0
  217. package/dist/core/importer/lexer.js +207 -0
  218. package/dist/core/importer/lexer.js.map +1 -0
  219. package/dist/core/importer/names.d.ts +41 -0
  220. package/dist/core/importer/names.d.ts.map +1 -0
  221. package/dist/core/importer/names.js +78 -0
  222. package/dist/core/importer/names.js.map +1 -0
  223. package/dist/core/importer/orders.d.ts +8 -0
  224. package/dist/core/importer/orders.d.ts.map +1 -0
  225. package/dist/core/importer/orders.js +332 -0
  226. package/dist/core/importer/orders.js.map +1 -0
  227. package/dist/core/importer/outputs.d.ts +19 -0
  228. package/dist/core/importer/outputs.d.ts.map +1 -0
  229. package/dist/core/importer/outputs.js +266 -0
  230. package/dist/core/importer/outputs.js.map +1 -0
  231. package/dist/core/importer/parser.d.ts +5 -0
  232. package/dist/core/importer/parser.d.ts.map +1 -0
  233. package/dist/core/importer/parser.js +439 -0
  234. package/dist/core/importer/parser.js.map +1 -0
  235. package/dist/core/importer/presence.d.ts +32 -0
  236. package/dist/core/importer/presence.d.ts.map +1 -0
  237. package/dist/core/importer/presence.js +146 -0
  238. package/dist/core/importer/presence.js.map +1 -0
  239. package/dist/core/importer/settle.d.ts +23 -0
  240. package/dist/core/importer/settle.d.ts.map +1 -0
  241. package/dist/core/importer/settle.js +135 -0
  242. package/dist/core/importer/settle.js.map +1 -0
  243. package/dist/core/importer/statements.d.ts +4 -0
  244. package/dist/core/importer/statements.d.ts.map +1 -0
  245. package/dist/core/importer/statements.js +339 -0
  246. package/dist/core/importer/statements.js.map +1 -0
  247. package/dist/core/importer/syntax.d.ts +182 -0
  248. package/dist/core/importer/syntax.d.ts.map +1 -0
  249. package/dist/core/importer/syntax.js +14 -0
  250. package/dist/core/importer/syntax.js.map +1 -0
  251. package/dist/core/importer/table.d.ts +52 -0
  252. package/dist/core/importer/table.d.ts.map +1 -0
  253. package/dist/core/importer/table.js +156 -0
  254. package/dist/core/importer/table.js.map +1 -0
  255. package/dist/core/importer/values.d.ts +27 -0
  256. package/dist/core/importer/values.d.ts.map +1 -0
  257. package/dist/core/importer/values.js +236 -0
  258. package/dist/core/importer/values.js.map +1 -0
  259. package/dist/core/index.d.ts +22 -5
  260. package/dist/core/index.d.ts.map +1 -1
  261. package/dist/core/index.js +19 -3
  262. package/dist/core/index.js.map +1 -1
  263. package/dist/core/stdlib/calendar/civil.d.ts.map +1 -1
  264. package/dist/core/stdlib/calendar/civil.js +5 -2
  265. package/dist/core/stdlib/calendar/civil.js.map +1 -1
  266. package/dist/core/stdlib/index.d.ts +1 -1
  267. package/dist/core/stdlib/index.d.ts.map +1 -1
  268. package/dist/core/stdlib/index.js +1 -1
  269. package/dist/core/stdlib/index.js.map +1 -1
  270. package/dist/core/stdlib/maths/index.d.ts +1 -1
  271. package/dist/core/stdlib/maths/index.d.ts.map +1 -1
  272. package/dist/core/stdlib/maths/index.js +1 -1
  273. package/dist/core/stdlib/maths/index.js.map +1 -1
  274. package/dist/core/stdlib/maths/rounding.d.ts +5 -0
  275. package/dist/core/stdlib/maths/rounding.d.ts.map +1 -1
  276. package/dist/core/stdlib/maths/rounding.js +19 -1
  277. package/dist/core/stdlib/maths/rounding.js.map +1 -1
  278. package/dist/core/version/version.generated.d.ts +1 -1
  279. package/dist/core/version/version.generated.js +1 -1
  280. package/package.json +17 -2
  281. package/spec/README.md +2 -1
  282. package/spec/errors.json +383 -23
  283. package/src/adapters/charts/driving.ts +109 -0
  284. package/src/adapters/charts/run.ts +126 -28
  285. package/src/adapters/charts/tables.ts +6 -19
  286. package/src/adapters/charts/undrawable.ts +51 -0
  287. package/src/adapters/charts/venue.ts +132 -0
  288. package/src/core/accounting/analysis.ts +188 -0
  289. package/src/core/accounting/equity.ts +38 -0
  290. package/src/core/accounting/index.ts +2 -0
  291. package/src/core/accounting/report.ts +5 -0
  292. package/src/core/accounting/statistics.ts +38 -1
  293. package/src/core/backtest/case.ts +395 -0
  294. package/src/core/backtest/compare.ts +2 -0
  295. package/src/core/backtest/deliver.ts +161 -0
  296. package/src/core/backtest/drive.ts +233 -217
  297. package/src/core/backtest/index.ts +26 -12
  298. package/src/core/backtest/record.ts +134 -5
  299. package/src/core/backtest/replay.ts +11 -1
  300. package/src/core/backtest/simulate.ts +201 -6
  301. package/src/core/backtest/walk.ts +182 -0
  302. package/src/core/catalogue/catalogue.generated.ts +19 -2
  303. package/src/core/catalogue/types.ts +8 -2
  304. package/src/core/catalogue/values.generated.ts +16 -0
  305. package/src/core/check/assigned.ts +31 -0
  306. package/src/core/check/call-sites.ts +11 -4
  307. package/src/core/check/calls.ts +13 -4
  308. package/src/core/check/check.ts +14 -2
  309. package/src/core/check/checker.ts +39 -2
  310. package/src/core/check/constant.ts +57 -0
  311. package/src/core/check/deleted.ts +135 -0
  312. package/src/core/check/expressions.ts +1 -1
  313. package/src/core/check/library-orders.ts +2 -2
  314. package/src/core/check/library-output.ts +1 -0
  315. package/src/core/check/library-prose.generated.ts +12 -12
  316. package/src/core/check/library.ts +8 -0
  317. package/src/core/check/surface.ts +16 -0
  318. package/src/core/emit/canonical.ts +67 -9
  319. package/src/core/engine/arithmetic.ts +23 -3
  320. package/src/core/engine/bar-source.ts +113 -0
  321. package/src/core/engine/engine.ts +26 -25
  322. package/src/core/engine/guard.ts +12 -1
  323. package/src/core/engine/host.ts +4 -2
  324. package/src/core/engine/index.ts +2 -1
  325. package/src/core/engine/library/arrays.ts +8 -2
  326. package/src/core/engine/library/binding.ts +2 -0
  327. package/src/core/engine/library/code-points.ts +73 -0
  328. package/src/core/engine/library/index.ts +17 -0
  329. package/src/core/engine/library/objects.ts +1 -6
  330. package/src/core/engine/library/text.ts +53 -35
  331. package/src/core/engine/load.ts +68 -0
  332. package/src/core/engine/request-body.ts +5 -7
  333. package/src/core/engine/request-plan.ts +3 -3
  334. package/src/core/engine/requests.ts +11 -8
  335. package/src/core/engine/series.ts +30 -6
  336. package/src/core/engine/session/record.ts +4 -4
  337. package/src/core/engine/verify-tables.ts +43 -0
  338. package/src/core/importer/calls.ts +274 -0
  339. package/src/core/importer/context.ts +197 -0
  340. package/src/core/importer/expressions.ts +247 -0
  341. package/src/core/importer/importer.ts +226 -0
  342. package/src/core/importer/index.ts +19 -0
  343. package/src/core/importer/lexer.ts +285 -0
  344. package/src/core/importer/names.ts +104 -0
  345. package/src/core/importer/orders.ts +307 -0
  346. package/src/core/importer/outputs.ts +245 -0
  347. package/src/core/importer/parser.ts +436 -0
  348. package/src/core/importer/presence.ts +164 -0
  349. package/src/core/importer/settle.ts +141 -0
  350. package/src/core/importer/statements.ts +331 -0
  351. package/src/core/importer/syntax.ts +144 -0
  352. package/src/core/importer/table.ts +191 -0
  353. package/src/core/importer/values.ts +241 -0
  354. package/src/core/index.ts +29 -2
  355. package/src/core/stdlib/calendar/civil.ts +5 -2
  356. package/src/core/stdlib/index.ts +1 -0
  357. package/src/core/stdlib/maths/index.ts +1 -0
  358. package/src/core/stdlib/maths/rounding.ts +23 -1
  359. package/src/core/version/version.generated.ts +1 -1
@@ -0,0 +1,47 @@
1
+ /**
2
+ * What this chart cannot draw of what a program declares, refused before a bar.
3
+ *
4
+ * `compiled-program.md` section 11: a host draws what its surface has room for,
5
+ * and refuses what it does not with OS6024 rather than drawing part of a study
6
+ * and saying nothing. Two things a version 1 program can declare have no place
7
+ * on this chart's surface, and both used to be dropped in silence.
8
+ *
9
+ * - **A second grid.** The descriptor has one `table` hook, so one grid reaches
10
+ * a pane. Merging two into it would put cells somewhere the script never
11
+ * asked for, and drawing the first alone is a study whose second panel never
12
+ * appears and whose cells look broken.
13
+ * - **A band colour computed per bar.** The chart's band takes one colour for
14
+ * the whole run and has no channel to point at, so a band whose colour the
15
+ * script computes was drawn in the first plot's colour faded, which is a
16
+ * colour the script did not choose.
17
+ *
18
+ * The compiled program carries no source position for a declaration, so the
19
+ * refusal names the declaration by its title, which is what a reader sees in
20
+ * the legend and the settings dialog, and its span is the load's own.
21
+ */
22
+ import { diagnosticFor, makeSpan } from '../../core/index.js';
23
+ /** A load refusal has no line of its own: the program is what was refused. */
24
+ const AT_LOAD = makeSpan(0, 0, 0, 0);
25
+ export function undrawable(program) {
26
+ const second = program.outputs.tables[1];
27
+ if (second !== undefined) {
28
+ return diagnosticFor('OS6024', AT_LOAD, {
29
+ what: `the table ${titled(second.title, 'after the first')}, the second grid this study declares`,
30
+ limit: 'a chart pane draws one grid',
31
+ });
32
+ }
33
+ for (const band of program.outputs.fills) {
34
+ if (band.colorUpChannel !== null || band.colorDownChannel !== null) {
35
+ return diagnosticFor('OS6024', AT_LOAD, {
36
+ what: "a band's colour that is computed per bar",
37
+ limit: "a chart's band takes one colour for the whole run",
38
+ });
39
+ }
40
+ }
41
+ return undefined;
42
+ }
43
+ /** A title as a reader sees it, or a description where it is a setting's. */
44
+ function titled(title, otherwise) {
45
+ return typeof title === 'string' ? `"${title}"` : otherwise;
46
+ }
47
+ //# sourceMappingURL=undrawable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"undrawable.js","sourceRoot":"","sources":["../../../src/adapters/charts/undrawable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAI9D,8EAA8E;AAC9E,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAErC,MAAM,UAAU,UAAU,CAAC,OAAwB;IACjD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACzC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE;YACtC,IAAI,EAAE,aAAa,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,iBAAiB,CAAC,uCAAuC;YACjG,KAAK,EAAE,6BAA6B;SACrC,CAAC,CAAC;IACL,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACzC,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,IAAI,IAAI,CAAC,gBAAgB,KAAK,IAAI,EAAE,CAAC;YACnE,OAAO,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE;gBACtC,IAAI,EAAE,0CAA0C;gBAChD,KAAK,EAAE,mDAAmD;aAC3D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,6EAA6E;AAC7E,SAAS,MAAM,CAAC,KAAY,EAAE,SAAiB;IAC7C,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * The destination a strategy runs against when a chart draws one.
3
+ *
4
+ * **Why a chart needs one at all.** A strategy asks a destination to do things
5
+ * and folds its position from what comes back. Handed no destination it is
6
+ * refused at load with OS6006, and handed one that answers nothing it runs but
7
+ * never learns it is in a position: every `close()` closes nothing, every entry
8
+ * is allowed again on the next signal, and the study draws a strategy that is
9
+ * wrong about itself while looking entirely normal. Measured on a stop and
10
+ * reverse script, that shape produced five buys and no sells.
11
+ *
12
+ * **It is the backtest's own venue, not a second one.** `Simulator` is what
13
+ * `backtest()` runs against, so a chart running a strategy through it fills the
14
+ * same orders at the same prices as the report the trader ran a moment ago. A
15
+ * venue written here to be simpler would be a second answer to "what would this
16
+ * have filled at", and the two would disagree the first time either changed:
17
+ * the chart would draw one set of trades and the report would list another.
18
+ *
19
+ * **What a chart supplies and what it invents.** The bars, the instrument and
20
+ * the declaration are the chart's own and are passed through. Money is not: a
21
+ * chart draws a strategy, it does not report one, so the currency, the point
22
+ * value and the rounding are stated here as the neutral values that make the
23
+ * accounting a no-op. Nothing a chart draws reads them, and a chart that
24
+ * guessed a point value would put a wrong profit in front of somebody.
25
+ *
26
+ * **Nothing here decides when a fill happens.** The declaration does, through
27
+ * `fillOn`, and the venue reads it. A market order priced at the next bar's
28
+ * open is known at that open; one that rested and traded inside a bar is known
29
+ * once the bar is complete. Both are what a venue could have told anybody at
30
+ * the time, and that is the whole reason the frames arrive between bars rather
31
+ * than inside the execution that sent them.
32
+ */
33
+ import { Simulator } from '../../core/backtest/index.js';
34
+ import type { CompiledProgram } from '../../core/emit/index.js';
35
+ import type { Instrument, OrderFrame, ResolvedInput, RoutedEffect } from '../../core/engine/index.js';
36
+ import type { ChartBar } from './contract.js';
37
+ /**
38
+ * Whether this program needs a destination before it can run at all.
39
+ *
40
+ * Read from the program's own declared capabilities rather than from whether
41
+ * its source said `strategy()`, because `requires` is the same fact the engine
42
+ * tests at load. A strategy that places no orders needs none, and anything that
43
+ * does need one is refused without it.
44
+ */
45
+ export declare function needsVenue(program: CompiledProgram): boolean;
46
+ /**
47
+ * The venue for one chart run, or nothing where the program does not need one.
48
+ *
49
+ * `inputs` are the ones the engine resolved at load, because a declaration
50
+ * field may be written as an `input()`: a script whose `fillOn` comes from a
51
+ * setting would otherwise be filled the way its source happened to be written
52
+ * rather than the way the trader is running it.
53
+ */
54
+ export declare function venueFor(program: CompiledProgram, bars: readonly ChartBar[], inputs: readonly ResolvedInput[], instrument: Instrument | undefined): Simulator | null;
55
+ /**
56
+ * A venue that can be asked for frames, held across a chart's recomputes.
57
+ *
58
+ * The bars a `Simulator` prices against are the ones it was built with, so a
59
+ * chart that has grown a bar needs a venue that knows about it. `extend` is how
60
+ * the tail path says so without rebuilding the orders it is already holding.
61
+ */
62
+ export interface HeldVenue {
63
+ readonly venue: Simulator;
64
+ /** Frames the venue answered for a bar, waiting to be delivered before the next. */
65
+ pending: readonly OrderFrame[];
66
+ }
67
+ /** What a venue has to say after one bar, which the next bar's engine reads. */
68
+ export declare function answersFor(held: HeldVenue, barIndex: number): void;
69
+ /** The route an engine is loaded with, pointing at a venue built after it. */
70
+ export declare function routeInto(holder: {
71
+ current: Simulator | null;
72
+ }): (effect: RoutedEffect, bar: number) => void;
73
+ //# sourceMappingURL=venue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"venue.d.ts","sourceRoot":"","sources":["../../../src/adapters/charts/venue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAgB,SAAS,EAAiB,MAAM,8BAA8B,CAAC;AAEtF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AACtG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAE5D;AAeD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,SAAS,QAAQ,EAAE,EACzB,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,UAAU,EAAE,UAAU,GAAG,SAAS,GACjC,SAAS,GAAG,IAAI,CA0BlB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,oFAAoF;IACpF,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;CAChC;AAED,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAElE;AAED,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,SAAS,GAAG,IAAI,CAAA;CAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAO5G"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * The destination a strategy runs against when a chart draws one.
3
+ *
4
+ * **Why a chart needs one at all.** A strategy asks a destination to do things
5
+ * and folds its position from what comes back. Handed no destination it is
6
+ * refused at load with OS6006, and handed one that answers nothing it runs but
7
+ * never learns it is in a position: every `close()` closes nothing, every entry
8
+ * is allowed again on the next signal, and the study draws a strategy that is
9
+ * wrong about itself while looking entirely normal. Measured on a stop and
10
+ * reverse script, that shape produced five buys and no sells.
11
+ *
12
+ * **It is the backtest's own venue, not a second one.** `Simulator` is what
13
+ * `backtest()` runs against, so a chart running a strategy through it fills the
14
+ * same orders at the same prices as the report the trader ran a moment ago. A
15
+ * venue written here to be simpler would be a second answer to "what would this
16
+ * have filled at", and the two would disagree the first time either changed:
17
+ * the chart would draw one set of trades and the report would list another.
18
+ *
19
+ * **What a chart supplies and what it invents.** The bars, the instrument and
20
+ * the declaration are the chart's own and are passed through. Money is not: a
21
+ * chart draws a strategy, it does not report one, so the currency, the point
22
+ * value and the rounding are stated here as the neutral values that make the
23
+ * accounting a no-op. Nothing a chart draws reads them, and a chart that
24
+ * guessed a point value would put a wrong profit in front of somebody.
25
+ *
26
+ * **Nothing here decides when a fill happens.** The declaration does, through
27
+ * `fillOn`, and the venue reads it. A market order priced at the next bar's
28
+ * open is known at that open; one that rested and traded inside a bar is known
29
+ * once the bar is complete. Both are what a venue could have told anybody at
30
+ * the time, and that is the whole reason the frames arrive between bars rather
31
+ * than inside the execution that sent them.
32
+ */
33
+ import { DEFAULT_FILL, Simulator, declarationOf } from '../../core/backtest/index.js';
34
+ /**
35
+ * Whether this program needs a destination before it can run at all.
36
+ *
37
+ * Read from the program's own declared capabilities rather than from whether
38
+ * its source said `strategy()`, because `requires` is the same fact the engine
39
+ * tests at load. A strategy that places no orders needs none, and anything that
40
+ * does need one is refused without it.
41
+ */
42
+ export function needsVenue(program) {
43
+ return program.requires.includes('orders');
44
+ }
45
+ /** One chart bar as the venue reads it. */
46
+ function recorded(bar) {
47
+ return {
48
+ time: bar.time,
49
+ open: bar.open,
50
+ high: bar.high,
51
+ low: bar.low,
52
+ close: bar.close,
53
+ volume: bar.volume ?? null,
54
+ oi: bar.oi ?? null,
55
+ };
56
+ }
57
+ /**
58
+ * The venue for one chart run, or nothing where the program does not need one.
59
+ *
60
+ * `inputs` are the ones the engine resolved at load, because a declaration
61
+ * field may be written as an `input()`: a script whose `fillOn` comes from a
62
+ * setting would otherwise be filled the way its source happened to be written
63
+ * rather than the way the trader is running it.
64
+ */
65
+ export function venueFor(program, bars, inputs, instrument) {
66
+ if (!needsVenue(program))
67
+ return null;
68
+ const declared = declarationOf(program, inputs);
69
+ return new Simulator({
70
+ bars: bars.map(recorded),
71
+ contract: {
72
+ symbol: instrument?.symbol ?? null,
73
+ exchange: instrument?.exchange ?? null,
74
+ // Neutral money. A chart draws a strategy and does not report one, so
75
+ // nothing it puts on screen reads these; stating a point value a host
76
+ // never gave would be inventing the size of somebody's position.
77
+ currency: declared.currency,
78
+ tickSize: instrument?.tickSize ?? null,
79
+ lotSize: null,
80
+ pointValue: 1,
81
+ digits: 2,
82
+ },
83
+ fill: DEFAULT_FILL,
84
+ // The declaration's own, so slippage is applied the way the backtest
85
+ // applies it. Ticks, against the instrument's tick size.
86
+ slippageTicks: declared.slippage,
87
+ fillOn: declared.fillOn,
88
+ qtyType: declared.qtyType,
89
+ });
90
+ }
91
+ /** What a venue has to say after one bar, which the next bar's engine reads. */
92
+ export function answersFor(held, barIndex) {
93
+ held.pending = held.venue.framesFor(barIndex);
94
+ }
95
+ /** The route an engine is loaded with, pointing at a venue built after it. */
96
+ export function routeInto(holder) {
97
+ // Late bound on purpose. The route is handed to `load`, and the venue cannot
98
+ // be built until `load` has resolved the inputs the declaration reads. The
99
+ // route is only ever called from inside an execution, which is after both.
100
+ return (effect, bar) => {
101
+ holder.current?.route(effect, bar);
102
+ };
103
+ }
104
+ //# sourceMappingURL=venue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"venue.js","sourceRoot":"","sources":["../../../src/adapters/charts/venue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAMtF;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,OAAwB;IACjD,OAAO,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC7C,CAAC;AAED,2CAA2C;AAC3C,SAAS,QAAQ,CAAC,GAAa;IAC7B,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,IAAI;QAC1B,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,IAAI;KACnB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CACtB,OAAwB,EACxB,IAAyB,EACzB,MAAgC,EAChC,UAAkC;IAElC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtC,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAEhD,OAAO,IAAI,SAAS,CAAC;QACnB,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;QACxB,QAAQ,EAAE;YACR,MAAM,EAAE,UAAU,EAAE,MAAM,IAAI,IAAI;YAClC,QAAQ,EAAE,UAAU,EAAE,QAAQ,IAAI,IAAI;YACtC,sEAAsE;YACtE,sEAAsE;YACtE,iEAAiE;YACjE,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,QAAQ,EAAE,UAAU,EAAE,QAAQ,IAAI,IAAI;YACtC,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,CAAC;YACb,MAAM,EAAE,CAAC;SACV;QACD,IAAI,EAAE,YAAY;QAClB,qEAAqE;QACrE,yDAAyD;QACzD,aAAa,EAAE,QAAQ,CAAC,QAAQ;QAChC,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,OAAO,EAAE,QAAQ,CAAC,OAAO;KAC1B,CAAC,CAAC;AACL,CAAC;AAeD,gFAAgF;AAChF,MAAM,UAAU,UAAU,CAAC,IAAe,EAAE,QAAgB;IAC1D,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;AAChD,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,SAAS,CAAC,MAAqC;IAC7D,6EAA6E;IAC7E,2EAA2E;IAC3E,2EAA2E;IAC3E,OAAO,CAAC,MAAoB,EAAE,GAAW,EAAE,EAAE;QAC3C,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,111 @@
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
+ import type { Money } from './shapes.js';
42
+ import type { Trade } from './trades.js';
43
+ /** One direction's own figures, folded over that side's closed trades. */
44
+ export interface SideAnalysis {
45
+ readonly count: number;
46
+ readonly wins: number;
47
+ readonly losses: number;
48
+ /** Exactly zero net, counted in neither half, as in the summary. */
49
+ readonly scratches: number;
50
+ /** Net after charges, which is the figure the sides are compared on. */
51
+ readonly netProfit: Money;
52
+ /** `wins / (wins + losses)`, null where this side decided nothing. */
53
+ readonly winRate: number | null;
54
+ }
55
+ /**
56
+ * The trades by direction, by extreme and by run.
57
+ *
58
+ * `long` and `short` partition the closed trades, so their counts sum to the
59
+ * summary's `tradeCount` and their nets sum to its `netProfit`. That is
60
+ * asserted rather than assumed, because a partition that stops partitioning is
61
+ * the defect this shape exists to make visible and it would otherwise show up
62
+ * as two panels that quietly disagree.
63
+ */
64
+ export interface TradeAnalysis {
65
+ readonly long: SideAnalysis;
66
+ readonly short: SideAnalysis;
67
+ /**
68
+ * The best closed trade's net, zero where none closed and zero where every
69
+ * closed trade lost.
70
+ *
71
+ * Zero rather than null, and it is the one place here that is worth arguing
72
+ * about. A run whose every trade lost has no winning trade to name, and null
73
+ * would say so. It reports zero because the figure is read beside
74
+ * `largestLoss` and against `netProfit`, and a null in a column of money
75
+ * forces every reader of the report to handle a case that means "nothing
76
+ * won", which is what zero already means in this column.
77
+ */
78
+ readonly largestWin: Money;
79
+ /** The worst closed trade's net as a positive magnitude, zero where none lost. */
80
+ readonly largestLoss: Money;
81
+ /**
82
+ * The longest run of consecutive winning closed trades, in the order they
83
+ * closed.
84
+ *
85
+ * In the order they closed, and not the order they opened, because that is
86
+ * the order the account experienced them in and the streak is a fact about
87
+ * what the account experienced. The two orders differ whenever a trade is
88
+ * held across another one's whole life, which is every scaling strategy.
89
+ */
90
+ readonly maxConsecutiveWins: number;
91
+ /** The same, for losses. */
92
+ readonly maxConsecutiveLosses: number;
93
+ }
94
+ /**
95
+ * One pass over the closed trades, in closing order.
96
+ *
97
+ * The list arrives in opening order, which is what the equity fold needs and
98
+ * what `tradesOf` produces. The streaks need closing order, so the closed
99
+ * trades are ordered here rather than anywhere else: reordering the list the
100
+ * caller holds would change the equity curve, and taking a second list in
101
+ * opening order and calling its streaks correct would be the defect this
102
+ * function is supposed to have caught.
103
+ *
104
+ * A trade whose net is exactly zero is a scratch, which is the summary's rule
105
+ * and is applied here for the same reason. A scratch **breaks** a streak
106
+ * without extending either one: a strategy that went right, flat, right was not
107
+ * right twice running, and counting the flat trade as either would make the
108
+ * streak a figure that depends on a rounding at the last digit.
109
+ */
110
+ export declare function analysisOf(trades: readonly Trade[]): TradeAnalysis;
111
+ //# sourceMappingURL=analysis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../../../src/core/accounting/analysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;IAC3B,kFAAkF;IAClF,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC;IAC5B;;;;;;;;OAQG;IACH,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,4BAA4B;IAC5B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;CACvC;AA2BD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,aAAa,CAiDlE"}
@@ -0,0 +1,123 @@
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
+ function emptySide() {
42
+ return { count: 0, wins: 0, losses: 0, scratches: 0, netProfit: 0 };
43
+ }
44
+ function sideOf(tally) {
45
+ const decided = tally.wins + tally.losses;
46
+ return {
47
+ count: tally.count,
48
+ wins: tally.wins,
49
+ losses: tally.losses,
50
+ scratches: tally.scratches,
51
+ netProfit: tally.netProfit,
52
+ winRate: decided === 0 ? null : tally.wins / decided,
53
+ };
54
+ }
55
+ /**
56
+ * One pass over the closed trades, in closing order.
57
+ *
58
+ * The list arrives in opening order, which is what the equity fold needs and
59
+ * what `tradesOf` produces. The streaks need closing order, so the closed
60
+ * trades are ordered here rather than anywhere else: reordering the list the
61
+ * caller holds would change the equity curve, and taking a second list in
62
+ * opening order and calling its streaks correct would be the defect this
63
+ * function is supposed to have caught.
64
+ *
65
+ * A trade whose net is exactly zero is a scratch, which is the summary's rule
66
+ * and is applied here for the same reason. A scratch **breaks** a streak
67
+ * without extending either one: a strategy that went right, flat, right was not
68
+ * right twice running, and counting the flat trade as either would make the
69
+ * streak a figure that depends on a rounding at the last digit.
70
+ */
71
+ export function analysisOf(trades) {
72
+ const long = emptySide();
73
+ const short = emptySide();
74
+ let largestWin = 0;
75
+ let largestLoss = 0;
76
+ let maxConsecutiveWins = 0;
77
+ let maxConsecutiveLosses = 0;
78
+ let winStreak = 0;
79
+ let lossStreak = 0;
80
+ const closed = trades.filter((trade) => !trade.isOpen).slice();
81
+ // A trade closes on a bar, and two can close on the same one. The opening
82
+ // order breaks the tie, because it is the order the list arrived in and the
83
+ // only other fact available: a sort that is not total gives two engines two
84
+ // different streaks from one list of trades.
85
+ closed.sort((a, b) => (a.closedOnBar ?? 0) - (b.closedOnBar ?? 0) || a.index - b.index);
86
+ for (const trade of closed) {
87
+ const side = trade.side === 'long' ? long : short;
88
+ side.count += 1;
89
+ side.netProfit += trade.netProfit;
90
+ if (trade.netProfit > 0) {
91
+ side.wins += 1;
92
+ if (trade.netProfit > largestWin)
93
+ largestWin = trade.netProfit;
94
+ winStreak += 1;
95
+ lossStreak = 0;
96
+ if (winStreak > maxConsecutiveWins)
97
+ maxConsecutiveWins = winStreak;
98
+ }
99
+ else if (trade.netProfit < 0) {
100
+ side.losses += 1;
101
+ if (-trade.netProfit > largestLoss)
102
+ largestLoss = -trade.netProfit;
103
+ lossStreak += 1;
104
+ winStreak = 0;
105
+ if (lossStreak > maxConsecutiveLosses)
106
+ maxConsecutiveLosses = lossStreak;
107
+ }
108
+ else {
109
+ side.scratches += 1;
110
+ winStreak = 0;
111
+ lossStreak = 0;
112
+ }
113
+ }
114
+ return {
115
+ long: sideOf(long),
116
+ short: sideOf(short),
117
+ largestWin,
118
+ largestLoss,
119
+ maxConsecutiveWins,
120
+ maxConsecutiveLosses,
121
+ };
122
+ }
123
+ //# sourceMappingURL=analysis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analysis.js","sourceRoot":"","sources":["../../../src/core/accounting/analysis.ts"],"names":[],"mappings":"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"}
@@ -104,6 +104,33 @@ export interface EquityPoint {
104
104
  readonly drawdown: Money;
105
105
  /** `drawdown / runningPeak`, a fraction and not a figure times a hundred. */
106
106
  readonly drawdownPercent: number;
107
+ /**
108
+ * The distance above the running trough, zero or positive.
109
+ *
110
+ * Drawdown's mirror, and carried for the same reason drawdown is: it is the
111
+ * run's best stretch measured the same way its worst one is, so the two can
112
+ * be read against each other. A reader handed only the depth learns how bad
113
+ * it got and nothing about whether the run ever climbed far enough for that
114
+ * depth to be a giving back rather than a steady bleed.
115
+ */
116
+ readonly runUp: Money;
117
+ /**
118
+ * `runUp / runningTrough`, a fraction and not a figure times a hundred, and
119
+ * zero where the trough is not above zero.
120
+ *
121
+ * Not the same guard drawdown gets, because the two bases are not the same
122
+ * kind of number. The running peak starts at the capital and only ever rises,
123
+ * so a run with capital above zero has a peak above zero at every point. The
124
+ * running trough starts there and only ever falls, so an account that lost
125
+ * everything has a trough at or below zero, and from that bar on this figure
126
+ * is zero rather than a fraction. Zero is the wrong answer for a run that
127
+ * recovered, and it is reported anyway, because the alternative is a
128
+ * percentage against a negative basis: a positive climb reported as a
129
+ * negative fraction, which is the shape that once gave a profit factor of
130
+ * minus a half. `runUp` itself is unaffected and stays the figure to read on
131
+ * such a run.
132
+ */
133
+ readonly runUpPercent: number;
107
134
  }
108
135
  /**
109
136
  * Whether this trade was still held at the close of this bar.
@@ -141,6 +168,12 @@ export declare function ratioOf(value: number, basis: number): number;
141
168
  * The running peak starts at the capital rather than at the first point, so a
142
169
  * run that is down from its first bar is in drawdown at its first bar. Starting
143
170
  * it at the first point would report every run as having begun at its high.
171
+ *
172
+ * The running trough starts at the capital for the same reason and not for a
173
+ * symmetrical one: a run that is up from its first bar has run up from the
174
+ * money it was given, which is the figure a reader is measuring against. Anchor
175
+ * it at the first point instead and a run that gapped up on bar zero reports
176
+ * that gain as having come from nowhere.
144
177
  */
145
178
  export declare function equityOver(trades: readonly Trade[], marks: readonly BarMark[], contract: Contract, capital: Money): readonly EquityPoint[];
146
179
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"equity.d.ts","sourceRoot":"","sources":["../../../src/core/accounting/equity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,yEAAyE;AACzE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,yCAAyC;IACzC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IACzB,kBAAkB;IAClB,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IACxB,kCAAkC;IAClC,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,yBAAyB;IACzB,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IACvB,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IACzB,8CAA8C;IAC9C,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IACzB,6EAA6E;IAC7E,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,KAAK,EAAE,EACxB,KAAK,EAAE,SAAS,OAAO,EAAE,EACzB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,KAAK,GACb,SAAS,WAAW,EAAE,CAoExB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,KAAK,EAAE,EACxB,MAAM,EAAE,SAAS,WAAW,EAAE,GAC7B,MAAM,CAuBR"}
1
+ {"version":3,"file":"equity.d.ts","sourceRoot":"","sources":["../../../src/core/accounting/equity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,yEAAyE;AACzE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,yCAAyC;IACzC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IACzB,kBAAkB;IAClB,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IACxB,kCAAkC;IAClC,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,yBAAyB;IACzB,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IACvB,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IACzB,8CAA8C;IAC9C,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IACzB,6EAA6E;IAC7E,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,KAAK,EAAE,EACxB,KAAK,EAAE,SAAS,OAAO,EAAE,EACzB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,KAAK,GACb,SAAS,WAAW,EAAE,CAyExB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,KAAK,EAAE,EACxB,MAAM,EAAE,SAAS,WAAW,EAAE,GAC7B,MAAM,CAuBR"}
@@ -40,6 +40,12 @@ export function ratioOf(value, basis) {
40
40
  * The running peak starts at the capital rather than at the first point, so a
41
41
  * run that is down from its first bar is in drawdown at its first bar. Starting
42
42
  * it at the first point would report every run as having begun at its high.
43
+ *
44
+ * The running trough starts at the capital for the same reason and not for a
45
+ * symmetrical one: a run that is up from its first bar has run up from the
46
+ * money it was given, which is the figure a reader is measuring against. Anchor
47
+ * it at the first point instead and a run that gapped up on bar zero reports
48
+ * that gain as having come from nowhere.
43
49
  */
44
50
  export function equityOver(trades, marks, contract, capital) {
45
51
  const points = [];
@@ -48,6 +54,7 @@ export function equityOver(trades, marks, contract, capital) {
48
54
  let realised = 0;
49
55
  let charges = 0;
50
56
  let peak = capital;
57
+ let trough = capital;
51
58
  let mark = null;
52
59
  for (const bar of marks) {
53
60
  // Opened by this bar, charges and all. The pointer is why the trades have
@@ -93,7 +100,10 @@ export function equityOver(trades, marks, contract, capital) {
93
100
  const equity = cash + openProfit;
94
101
  if (equity > peak)
95
102
  peak = equity;
103
+ if (equity < trough)
104
+ trough = equity;
96
105
  const drawdown = equity - peak;
106
+ const runUp = equity - trough;
97
107
  points.push({
98
108
  barIndex: bar.barIndex,
99
109
  time: bar.time,
@@ -105,6 +115,8 @@ export function equityOver(trades, marks, contract, capital) {
105
115
  exposure,
106
116
  drawdown,
107
117
  drawdownPercent: ratioOf(drawdown, peak),
118
+ runUp,
119
+ runUpPercent: ratioOf(runUp, trough),
108
120
  });
109
121
  }
110
122
  return points;
@@ -1 +1 @@
1
- {"version":3,"file":"equity.js","sourceRoot":"","sources":["../../../src/core/accounting/equity.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"equity.js","sourceRoot":"","sources":["../../../src/core/accounting/equity.ts"],"names":[],"mappings":"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"}
@@ -37,6 +37,8 @@ export { monthlyOver } from './monthly.js';
37
37
  export type { MonthlyReturn } from './monthly.js';
38
38
  export { markersOf } from './markers.js';
39
39
  export type { TradeMarker } from './markers.js';
40
+ export { analysisOf } from './analysis.js';
41
+ export type { SideAnalysis, TradeAnalysis } from './analysis.js';
40
42
  export { summaryOf } from './statistics.js';
41
43
  export type { Summary } from './statistics.js';
42
44
  export { reportOf } from './report.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/accounting/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACnF,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1E,YAAY,EACV,UAAU,EACV,eAAe,EACf,UAAU,EACV,cAAc,EACd,UAAU,GACX,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,YAAY,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/accounting/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACnF,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1E,YAAY,EACV,UAAU,EACV,eAAe,EACf,UAAU,EACV,cAAc,EACd,UAAU,GACX,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,YAAY,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
@@ -31,6 +31,7 @@ export { tradesOf } from './trades.js';
31
31
  export { equityOver } from './equity.js';
32
32
  export { monthlyOver } from './monthly.js';
33
33
  export { markersOf } from './markers.js';
34
+ export { analysisOf } from './analysis.js';
34
35
  export { summaryOf } from './statistics.js';
35
36
  export { reportOf } from './report.js';
36
37
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/accounting/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AASnF,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/accounting/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AASnF,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}