@quantform/core 0.5.15 → 0.6.4

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 (562) hide show
  1. package/LICENSE.md +21 -0
  2. package/dist/adapter/adapter-aggregate.d.ts +41 -5
  3. package/dist/adapter/adapter-aggregate.d.ts.map +1 -0
  4. package/dist/adapter/adapter-aggregate.js +114 -54
  5. package/dist/adapter/adapter.d.ts +29 -15
  6. package/dist/adapter/adapter.d.ts.map +1 -0
  7. package/dist/adapter/adapter.js +4 -1
  8. package/dist/adapter/backtester/backtester-adapter.d.ts +4 -3
  9. package/dist/adapter/backtester/backtester-adapter.d.ts.map +1 -0
  10. package/dist/adapter/backtester/backtester-adapter.js +28 -15
  11. package/dist/adapter/backtester/backtester-cursor.d.ts +5 -4
  12. package/dist/adapter/backtester/backtester-cursor.d.ts.map +1 -0
  13. package/dist/adapter/backtester/backtester-cursor.js +24 -14
  14. package/dist/adapter/backtester/backtester-streamer.d.ts +20 -2
  15. package/dist/adapter/backtester/backtester-streamer.d.ts.map +1 -0
  16. package/dist/adapter/backtester/backtester-streamer.js +54 -40
  17. package/dist/adapter/backtester/error.d.ts +3 -0
  18. package/dist/adapter/backtester/error.d.ts.map +1 -0
  19. package/dist/adapter/backtester/error.js +11 -0
  20. package/dist/adapter/backtester/index.d.ts +1 -0
  21. package/dist/adapter/backtester/index.d.ts.map +1 -0
  22. package/dist/adapter/backtester/index.js +0 -1
  23. package/dist/adapter/error.d.ts +2 -0
  24. package/dist/adapter/error.d.ts.map +1 -0
  25. package/dist/adapter/error.js +5 -2
  26. package/dist/adapter/index.d.ts +1 -0
  27. package/dist/adapter/index.d.ts.map +1 -0
  28. package/dist/adapter/index.js +0 -1
  29. package/dist/adapter/paper/engine/paper-engine.d.ts +1 -0
  30. package/dist/adapter/paper/engine/paper-engine.d.ts.map +1 -0
  31. package/dist/adapter/paper/engine/paper-engine.js +38 -32
  32. package/dist/adapter/paper/index.d.ts +1 -0
  33. package/dist/adapter/paper/index.d.ts.map +1 -0
  34. package/dist/adapter/paper/index.js +0 -1
  35. package/dist/adapter/paper/paper-adapter.d.ts +7 -5
  36. package/dist/adapter/paper/paper-adapter.d.ts.map +1 -0
  37. package/dist/adapter/paper/paper-adapter.js +49 -25
  38. package/dist/cli/build.d.ts +1 -0
  39. package/dist/cli/build.d.ts.map +1 -0
  40. package/dist/cli/build.js +18 -8
  41. package/dist/cli/dev.d.ts +1 -0
  42. package/dist/cli/dev.d.ts.map +1 -0
  43. package/dist/cli/dev.js +52 -12
  44. package/dist/cli/error.d.ts +2 -0
  45. package/dist/cli/error.d.ts.map +1 -0
  46. package/dist/cli/error.js +7 -0
  47. package/dist/cli/index.d.ts +1 -0
  48. package/dist/cli/index.d.ts.map +1 -0
  49. package/dist/cli/index.js +21 -10
  50. package/dist/cli/internal/workspace.d.ts +1 -7
  51. package/dist/cli/internal/workspace.d.ts.map +1 -0
  52. package/dist/cli/internal/workspace.js +1 -6
  53. package/dist/cli/pull.d.ts +1 -0
  54. package/dist/cli/pull.d.ts.map +1 -0
  55. package/dist/cli/pull.js +65 -40
  56. package/dist/cli/run.d.ts +2 -1
  57. package/dist/cli/run.d.ts.map +1 -0
  58. package/dist/cli/run.js +52 -14
  59. package/dist/cli/test.d.ts +2 -1
  60. package/dist/cli/test.d.ts.map +1 -0
  61. package/dist/cli/test.js +59 -34
  62. package/dist/domain/asset.d.ts +24 -4
  63. package/dist/domain/asset.d.ts.map +1 -0
  64. package/dist/domain/asset.js +23 -8
  65. package/dist/domain/{balance.operator.d.ts → balance-operator.d.ts} +1 -0
  66. package/dist/domain/balance-operator.d.ts.map +1 -0
  67. package/dist/domain/{balance.operator.js → balance-operator.js} +0 -1
  68. package/dist/domain/balance.d.ts +35 -11
  69. package/dist/domain/balance.d.ts.map +1 -0
  70. package/dist/domain/balance.js +46 -17
  71. package/dist/domain/candle-operator.d.ts +11 -0
  72. package/dist/domain/candle-operator.d.ts.map +1 -0
  73. package/dist/domain/{candle.operator.js → candle-operator.js} +11 -5
  74. package/dist/domain/candle.d.ts +9 -8
  75. package/dist/domain/candle.d.ts.map +1 -0
  76. package/dist/domain/candle.js +3 -3
  77. package/dist/domain/commission.d.ts +12 -9
  78. package/dist/domain/commission.d.ts.map +1 -0
  79. package/dist/domain/commission.js +7 -6
  80. package/dist/domain/component.d.ts +1 -0
  81. package/dist/domain/component.d.ts.map +1 -0
  82. package/dist/domain/component.js +0 -1
  83. package/dist/domain/error.d.ts +6 -4
  84. package/dist/domain/error.d.ts.map +1 -0
  85. package/dist/domain/error.js +4 -5
  86. package/dist/domain/index.d.ts +9 -7
  87. package/dist/domain/index.d.ts.map +1 -0
  88. package/dist/domain/index.js +8 -8
  89. package/dist/domain/{instrument.operator.d.ts → instrument-operator.d.ts} +1 -0
  90. package/dist/domain/instrument-operator.d.ts.map +1 -0
  91. package/dist/domain/{instrument.operator.js → instrument-operator.js} +0 -1
  92. package/dist/domain/instrument.d.ts +9 -6
  93. package/dist/domain/instrument.d.ts.map +1 -0
  94. package/dist/domain/instrument.js +7 -3
  95. package/dist/domain/{order.operator.d.ts → order-operator.d.ts} +1 -0
  96. package/dist/domain/order-operator.d.ts.map +1 -0
  97. package/dist/domain/order-operator.js +16 -0
  98. package/dist/domain/order.d.ts +17 -22
  99. package/dist/domain/order.d.ts.map +1 -0
  100. package/dist/domain/order.js +23 -34
  101. package/dist/domain/{orderbook.operator.d.ts → orderbook-operator.d.ts} +1 -0
  102. package/dist/domain/orderbook-operator.d.ts.map +1 -0
  103. package/dist/domain/{orderbook.operator.js → orderbook-operator.js} +0 -1
  104. package/dist/domain/orderbook.d.ts +26 -10
  105. package/dist/domain/orderbook.d.ts.map +1 -0
  106. package/dist/domain/orderbook.js +12 -6
  107. package/dist/domain/{position.operator.d.ts → position-operator.d.ts} +7 -4
  108. package/dist/domain/position-operator.d.ts.map +1 -0
  109. package/dist/domain/{position.operator.js → position-operator.js} +13 -6
  110. package/dist/domain/position.d.ts +10 -9
  111. package/dist/domain/position.d.ts.map +1 -0
  112. package/dist/domain/position.js +4 -4
  113. package/dist/domain/session-builder.d.ts +54 -0
  114. package/dist/domain/session-builder.d.ts.map +1 -0
  115. package/dist/domain/session-builder.js +105 -0
  116. package/dist/domain/session.d.ts +54 -13
  117. package/dist/domain/session.d.ts.map +1 -0
  118. package/dist/domain/session.js +104 -40
  119. package/dist/domain/timeframe.d.ts +1 -0
  120. package/dist/domain/timeframe.d.ts.map +1 -0
  121. package/dist/domain/timeframe.js +0 -1
  122. package/dist/domain/{trade.operator.d.ts → trade-operator.d.ts} +1 -0
  123. package/dist/domain/trade-operator.d.ts.map +1 -0
  124. package/dist/domain/{trade.operator.js → trade-operator.js} +0 -1
  125. package/dist/domain/trade.d.ts +12 -7
  126. package/dist/domain/trade.d.ts.map +1 -0
  127. package/dist/domain/trade.js +8 -2
  128. package/dist/index.d.ts +2 -2
  129. package/dist/index.d.ts.map +1 -0
  130. package/dist/index.js +1 -3
  131. package/dist/shared/collections.d.ts +20 -1
  132. package/dist/shared/collections.d.ts.map +1 -0
  133. package/dist/shared/collections.js +98 -8
  134. package/dist/shared/datetime.d.ts +1 -0
  135. package/dist/shared/datetime.d.ts.map +1 -0
  136. package/dist/shared/datetime.js +0 -1
  137. package/dist/shared/decimals.d.ts +28 -6
  138. package/dist/shared/decimals.d.ts.map +1 -0
  139. package/dist/shared/decimals.js +33 -35
  140. package/dist/shared/environment.d.ts +3 -0
  141. package/dist/shared/environment.d.ts.map +1 -0
  142. package/dist/shared/environment.js +15 -0
  143. package/dist/shared/index.d.ts +3 -1
  144. package/dist/shared/index.d.ts.map +1 -0
  145. package/dist/shared/index.js +2 -2
  146. package/dist/shared/logger.d.ts +5 -7
  147. package/dist/shared/logger.d.ts.map +1 -0
  148. package/dist/shared/logger.js +24 -8
  149. package/dist/shared/pipe.d.ts +5 -0
  150. package/dist/shared/pipe.d.ts.map +1 -0
  151. package/dist/shared/pipe.js +8 -0
  152. package/dist/shared/policy.d.ts +1 -0
  153. package/dist/shared/policy.d.ts.map +1 -0
  154. package/dist/shared/policy.js +0 -1
  155. package/dist/storage/cache.d.ts +1 -0
  156. package/dist/storage/cache.d.ts.map +1 -0
  157. package/dist/storage/cache.js +30 -19
  158. package/dist/storage/feed.d.ts +33 -4
  159. package/dist/storage/feed.d.ts.map +1 -0
  160. package/dist/storage/feed.js +93 -19
  161. package/dist/storage/index.d.ts +1 -0
  162. package/dist/storage/index.d.ts.map +1 -0
  163. package/dist/storage/index.js +0 -1
  164. package/dist/storage/measurement.d.ts +20 -0
  165. package/dist/storage/measurement.d.ts.map +1 -0
  166. package/dist/storage/measurement.js +41 -10
  167. package/dist/storage/storage.d.ts +41 -0
  168. package/dist/storage/storage.d.ts.map +1 -0
  169. package/dist/storage/storage.js +69 -33
  170. package/dist/store/error.d.ts +9 -0
  171. package/dist/store/error.d.ts.map +1 -0
  172. package/dist/store/error.js +31 -0
  173. package/dist/store/index.d.ts +8 -7
  174. package/dist/store/index.d.ts.map +1 -0
  175. package/dist/store/index.js +7 -8
  176. package/dist/store/{store-balance.event.d.ts → store-balance-event.d.ts} +20 -7
  177. package/dist/store/store-balance-event.d.ts.map +1 -0
  178. package/dist/store/{store-balance.event.js → store-balance-event.js} +54 -10
  179. package/dist/store/{store.event.d.ts → store-event.d.ts} +1 -0
  180. package/dist/store/store-event.d.ts.map +1 -0
  181. package/dist/store/{store.event.js → store-event.js} +0 -1
  182. package/dist/store/{store-instrument.event.d.ts → store-instrument-event.d.ts} +5 -4
  183. package/dist/store/store-instrument-event.d.ts.map +1 -0
  184. package/dist/store/{store-instrument.event.js → store-instrument-event.js} +13 -5
  185. package/dist/store/{store-order.event.d.ts → store-order-event.d.ts} +10 -5
  186. package/dist/store/store-order-event.d.ts.map +1 -0
  187. package/dist/store/{store-order.event.js → store-order-event.js} +24 -20
  188. package/dist/store/store-orderbook-event.d.ts +13 -0
  189. package/dist/store/store-orderbook-event.d.ts.map +1 -0
  190. package/dist/store/store-orderbook-event.js +43 -0
  191. package/dist/store/{store-position.event.d.ts → store-position-event.d.ts} +7 -6
  192. package/dist/store/store-position-event.d.ts.map +1 -0
  193. package/dist/store/{store-position.event.js → store-position-event.js} +36 -17
  194. package/dist/store/store-state.d.ts +3 -2
  195. package/dist/store/store-state.d.ts.map +1 -0
  196. package/dist/store/store-state.js +1 -1
  197. package/dist/store/store-trade-event.d.ts +17 -0
  198. package/dist/store/store-trade-event.d.ts.map +1 -0
  199. package/dist/store/{store-trade.event.js → store-trade-event.js} +14 -5
  200. package/dist/store/store.d.ts +2 -1
  201. package/dist/store/store.d.ts.map +1 -0
  202. package/dist/store/store.js +0 -1
  203. package/dist/strategy.d.ts +8 -0
  204. package/dist/strategy.d.ts.map +1 -0
  205. package/dist/strategy.js +44 -0
  206. package/jest.config.ts +13 -0
  207. package/package.json +19 -30
  208. package/src/adapter/adapter-aggregate.ts +57 -25
  209. package/src/adapter/adapter.ts +15 -18
  210. package/src/adapter/backtester/backtester-adapter.ts +14 -7
  211. package/src/adapter/backtester/backtester-cursor.spec.ts +20 -18
  212. package/src/adapter/backtester/backtester-cursor.ts +6 -6
  213. package/src/adapter/backtester/backtester-streamer.spec.ts +18 -15
  214. package/src/adapter/backtester/backtester-streamer.ts +21 -30
  215. package/src/adapter/backtester/error.ts +7 -0
  216. package/src/adapter/error.ts +4 -0
  217. package/src/adapter/paper/engine/paper-engine.spec.ts +54 -30
  218. package/src/adapter/paper/engine/paper-engine.ts +62 -46
  219. package/src/adapter/paper/paper-adapter.ts +30 -9
  220. package/src/cli/build.ts +1 -1
  221. package/src/cli/dev.ts +15 -7
  222. package/src/cli/error.ts +5 -0
  223. package/src/cli/internal/workspace.ts +0 -11
  224. package/src/cli/pull.ts +28 -36
  225. package/src/cli/run.ts +14 -11
  226. package/src/cli/test.ts +24 -37
  227. package/src/domain/asset.spec.ts +4 -4
  228. package/src/domain/asset.ts +8 -15
  229. package/src/domain/{balance.operator.spec.ts → balance-operator.spec.ts} +4 -3
  230. package/src/domain/{balance.operator.ts → balance-operator.ts} +0 -0
  231. package/src/domain/balance.spec.ts +51 -47
  232. package/src/domain/balance.ts +32 -31
  233. package/src/domain/candle-operator.spec.ts +126 -0
  234. package/src/domain/{candle.operator.ts → candle-operator.ts} +24 -7
  235. package/src/domain/candle.spec.ts +13 -12
  236. package/src/domain/candle.ts +9 -9
  237. package/src/domain/commission.spec.ts +13 -12
  238. package/src/domain/commission.ts +15 -11
  239. package/src/domain/error.ts +8 -6
  240. package/src/domain/index.ts +8 -7
  241. package/src/domain/{instrument.operator.spec.ts → instrument-operator.spec.ts} +9 -2
  242. package/src/domain/{instrument.operator.ts → instrument-operator.ts} +0 -0
  243. package/src/domain/instrument.spec.ts +8 -1
  244. package/src/domain/instrument.ts +11 -8
  245. package/src/domain/{order.operator.spec.ts → order-operator.spec.ts} +11 -7
  246. package/src/domain/{order.operator.ts → order-operator.ts} +2 -2
  247. package/src/domain/order.spec.ts +15 -15
  248. package/src/domain/order.ts +34 -61
  249. package/src/domain/{orderbook.operator.spec.ts → orderbook-operator.spec.ts} +15 -3
  250. package/src/domain/{orderbook.operator.ts → orderbook-operator.ts} +0 -0
  251. package/src/domain/orderbook.spec.ts +11 -2
  252. package/src/domain/orderbook.ts +20 -13
  253. package/src/domain/{position.operator.spec.ts → position-operator.spec.ts} +13 -7
  254. package/src/domain/{position.operator.ts → position-operator.ts} +21 -11
  255. package/src/domain/position.spec.ts +14 -10
  256. package/src/domain/position.ts +10 -10
  257. package/src/domain/session-builder.ts +158 -0
  258. package/src/domain/session.spec.ts +5 -12
  259. package/src/domain/session.ts +85 -72
  260. package/src/domain/{trade.operator.spec.ts → trade-operator.spec.ts} +7 -3
  261. package/src/domain/{trade.operator.ts → trade-operator.ts} +0 -0
  262. package/src/domain/trade.spec.ts +6 -2
  263. package/src/domain/trade.ts +9 -7
  264. package/src/index.ts +1 -2
  265. package/src/shared/collections.spec.ts +34 -0
  266. package/src/shared/collections.ts +125 -6
  267. package/src/shared/decimals.spec.ts +18 -24
  268. package/src/shared/decimals.ts +22 -55
  269. package/src/shared/environment.ts +13 -0
  270. package/src/shared/index.ts +2 -1
  271. package/src/shared/logger.ts +35 -7
  272. package/src/shared/pipe.ts +12 -0
  273. package/src/storage/cache.ts +3 -1
  274. package/src/storage/feed.ts +91 -34
  275. package/src/storage/storage.ts +10 -8
  276. package/src/store/error.ts +36 -0
  277. package/src/store/index.ts +7 -7
  278. package/src/store/{store-balance.event.spec.ts → store-balance-event.spec.ts} +8 -8
  279. package/src/store/{store-balance.event.ts → store-balance-event.ts} +58 -15
  280. package/src/store/{store.event.ts → store-event.ts} +0 -0
  281. package/src/store/{store-instrument.event.spec.ts → store-instrument-event.spec.ts} +8 -7
  282. package/src/store/{store-instrument.event.ts → store-instrument-event.ts} +18 -7
  283. package/src/store/store-order-event.spec.ts +32 -0
  284. package/src/store/{store-order.event.ts → store-order-event.ts} +27 -22
  285. package/src/store/store-orderbook-event.spec.ts +39 -0
  286. package/src/store/store-orderbook-event.ts +56 -0
  287. package/src/store/{store-position.event.ts → store-position-event.ts} +41 -22
  288. package/src/store/store-state.ts +3 -3
  289. package/src/store/{store-trade.event.spec.ts → store-trade-event.spec.ts} +16 -14
  290. package/src/store/{store-trade.event.ts → store-trade-event.ts} +14 -8
  291. package/src/store/store.spec.ts +22 -20
  292. package/src/store/store.ts +1 -1
  293. package/src/strategy.ts +47 -0
  294. package/tsconfig.json +12 -5
  295. package/dist/adapter/adapter-aggregate.js.map +0 -1
  296. package/dist/adapter/adapter.js.map +0 -1
  297. package/dist/adapter/backtester/backtester-adapter.js.map +0 -1
  298. package/dist/adapter/backtester/backtester-adapter.spec.d.ts +0 -1
  299. package/dist/adapter/backtester/backtester-adapter.spec.js +0 -82
  300. package/dist/adapter/backtester/backtester-adapter.spec.js.map +0 -1
  301. package/dist/adapter/backtester/backtester-cursor.js.map +0 -1
  302. package/dist/adapter/backtester/backtester-cursor.spec.d.ts +0 -1
  303. package/dist/adapter/backtester/backtester-cursor.spec.js +0 -37
  304. package/dist/adapter/backtester/backtester-cursor.spec.js.map +0 -1
  305. package/dist/adapter/backtester/backtester-streamer.js.map +0 -1
  306. package/dist/adapter/backtester/backtester-streamer.spec.d.ts +0 -1
  307. package/dist/adapter/backtester/backtester-streamer.spec.js +0 -44
  308. package/dist/adapter/backtester/backtester-streamer.spec.js.map +0 -1
  309. package/dist/adapter/backtester/index.js.map +0 -1
  310. package/dist/adapter/error.js.map +0 -1
  311. package/dist/adapter/index.js.map +0 -1
  312. package/dist/adapter/paper/engine/paper-engine.js.map +0 -1
  313. package/dist/adapter/paper/engine/paper-engine.spec.d.ts +0 -1
  314. package/dist/adapter/paper/engine/paper-engine.spec.js +0 -54
  315. package/dist/adapter/paper/engine/paper-engine.spec.js.map +0 -1
  316. package/dist/adapter/paper/index.js.map +0 -1
  317. package/dist/adapter/paper/paper-adapter.js.map +0 -1
  318. package/dist/adapter/paper/paper-adapter.spec.d.ts +0 -1
  319. package/dist/adapter/paper/paper-adapter.spec.js +0 -69
  320. package/dist/adapter/paper/paper-adapter.spec.js.map +0 -1
  321. package/dist/bootstrap.d.ts +0 -11
  322. package/dist/bootstrap.js +0 -73
  323. package/dist/bootstrap.js.map +0 -1
  324. package/dist/cli/build.js.map +0 -1
  325. package/dist/cli/dev.js.map +0 -1
  326. package/dist/cli/index.js.map +0 -1
  327. package/dist/cli/internal/workspace.js.map +0 -1
  328. package/dist/cli/pull.js.map +0 -1
  329. package/dist/cli/run.js.map +0 -1
  330. package/dist/cli/test.js.map +0 -1
  331. package/dist/domain/asset.js.map +0 -1
  332. package/dist/domain/asset.spec.d.ts +0 -1
  333. package/dist/domain/asset.spec.js +0 -55
  334. package/dist/domain/asset.spec.js.map +0 -1
  335. package/dist/domain/balance.js.map +0 -1
  336. package/dist/domain/balance.operator.js.map +0 -1
  337. package/dist/domain/balance.operator.spec.d.ts +0 -1
  338. package/dist/domain/balance.operator.spec.js +0 -23
  339. package/dist/domain/balance.operator.spec.js.map +0 -1
  340. package/dist/domain/balance.spec.d.ts +0 -1
  341. package/dist/domain/balance.spec.js +0 -82
  342. package/dist/domain/balance.spec.js.map +0 -1
  343. package/dist/domain/candle.js.map +0 -1
  344. package/dist/domain/candle.operator.d.ts +0 -9
  345. package/dist/domain/candle.operator.js.map +0 -1
  346. package/dist/domain/candle.operator.spec.d.ts +0 -1
  347. package/dist/domain/candle.operator.spec.js +0 -111
  348. package/dist/domain/candle.operator.spec.js.map +0 -1
  349. package/dist/domain/candle.spec.d.ts +0 -1
  350. package/dist/domain/candle.spec.js +0 -26
  351. package/dist/domain/candle.spec.js.map +0 -1
  352. package/dist/domain/commission.js.map +0 -1
  353. package/dist/domain/commission.spec.d.ts +0 -1
  354. package/dist/domain/commission.spec.js +0 -30
  355. package/dist/domain/commission.spec.js.map +0 -1
  356. package/dist/domain/component.js.map +0 -1
  357. package/dist/domain/error.js.map +0 -1
  358. package/dist/domain/index.js.map +0 -1
  359. package/dist/domain/instrument.js.map +0 -1
  360. package/dist/domain/instrument.operator.js.map +0 -1
  361. package/dist/domain/instrument.operator.spec.d.ts +0 -1
  362. package/dist/domain/instrument.operator.spec.js +0 -24
  363. package/dist/domain/instrument.operator.spec.js.map +0 -1
  364. package/dist/domain/instrument.spec.d.ts +0 -1
  365. package/dist/domain/instrument.spec.js +0 -49
  366. package/dist/domain/instrument.spec.js.map +0 -1
  367. package/dist/domain/order.js.map +0 -1
  368. package/dist/domain/order.operator.js +0 -14
  369. package/dist/domain/order.operator.js.map +0 -1
  370. package/dist/domain/order.operator.spec.d.ts +0 -1
  371. package/dist/domain/order.operator.spec.js +0 -64
  372. package/dist/domain/order.operator.spec.js.map +0 -1
  373. package/dist/domain/order.spec.d.ts +0 -1
  374. package/dist/domain/order.spec.js +0 -33
  375. package/dist/domain/order.spec.js.map +0 -1
  376. package/dist/domain/orderbook.js.map +0 -1
  377. package/dist/domain/orderbook.operator.js.map +0 -1
  378. package/dist/domain/orderbook.operator.spec.d.ts +0 -1
  379. package/dist/domain/orderbook.operator.spec.js +0 -22
  380. package/dist/domain/orderbook.operator.spec.js.map +0 -1
  381. package/dist/domain/orderbook.spec.d.ts +0 -1
  382. package/dist/domain/orderbook.spec.js +0 -13
  383. package/dist/domain/orderbook.spec.js.map +0 -1
  384. package/dist/domain/position.js.map +0 -1
  385. package/dist/domain/position.operator.js.map +0 -1
  386. package/dist/domain/position.operator.spec.d.ts +0 -1
  387. package/dist/domain/position.operator.spec.js +0 -48
  388. package/dist/domain/position.operator.spec.js.map +0 -1
  389. package/dist/domain/position.spec.d.ts +0 -1
  390. package/dist/domain/position.spec.js +0 -30
  391. package/dist/domain/position.spec.js.map +0 -1
  392. package/dist/domain/session.js.map +0 -1
  393. package/dist/domain/session.spec.d.ts +0 -1
  394. package/dist/domain/session.spec.js +0 -23
  395. package/dist/domain/session.spec.js.map +0 -1
  396. package/dist/domain/timeframe.js.map +0 -1
  397. package/dist/domain/trade.js.map +0 -1
  398. package/dist/domain/trade.operator.js.map +0 -1
  399. package/dist/domain/trade.operator.spec.d.ts +0 -1
  400. package/dist/domain/trade.operator.spec.js +0 -24
  401. package/dist/domain/trade.operator.spec.js.map +0 -1
  402. package/dist/domain/trade.spec.d.ts +0 -1
  403. package/dist/domain/trade.spec.js +0 -13
  404. package/dist/domain/trade.spec.js.map +0 -1
  405. package/dist/index.js.map +0 -1
  406. package/dist/indicator/atr.d.ts +0 -3
  407. package/dist/indicator/atr.js +0 -16
  408. package/dist/indicator/atr.js.map +0 -1
  409. package/dist/indicator/cross.d.ts +0 -3
  410. package/dist/indicator/cross.js +0 -41
  411. package/dist/indicator/cross.js.map +0 -1
  412. package/dist/indicator/cross.spec.d.ts +0 -1
  413. package/dist/indicator/cross.spec.js +0 -101
  414. package/dist/indicator/cross.spec.js.map +0 -1
  415. package/dist/indicator/donchian.d.ts +0 -9
  416. package/dist/indicator/donchian.js +0 -16
  417. package/dist/indicator/donchian.js.map +0 -1
  418. package/dist/indicator/drawdown.d.ts +0 -2
  419. package/dist/indicator/drawdown.js +0 -27
  420. package/dist/indicator/drawdown.js.map +0 -1
  421. package/dist/indicator/ema.d.ts +0 -2
  422. package/dist/indicator/ema.js +0 -23
  423. package/dist/indicator/ema.js.map +0 -1
  424. package/dist/indicator/ema.spec.d.ts +0 -1
  425. package/dist/indicator/ema.spec.js +0 -23
  426. package/dist/indicator/ema.spec.js.map +0 -1
  427. package/dist/indicator/envelope.d.ts +0 -5
  428. package/dist/indicator/envelope.js +0 -18
  429. package/dist/indicator/envelope.js.map +0 -1
  430. package/dist/indicator/index.d.ts +0 -17
  431. package/dist/indicator/index.js +0 -34
  432. package/dist/indicator/index.js.map +0 -1
  433. package/dist/indicator/macd.d.ts +0 -2
  434. package/dist/indicator/macd.js +0 -13
  435. package/dist/indicator/macd.js.map +0 -1
  436. package/dist/indicator/min-max.d.ts +0 -5
  437. package/dist/indicator/min-max.js +0 -21
  438. package/dist/indicator/min-max.js.map +0 -1
  439. package/dist/indicator/ring-buffer.d.ts +0 -16
  440. package/dist/indicator/ring-buffer.js +0 -56
  441. package/dist/indicator/ring-buffer.js.map +0 -1
  442. package/dist/indicator/rma.d.ts +0 -2
  443. package/dist/indicator/rma.js +0 -23
  444. package/dist/indicator/rma.js.map +0 -1
  445. package/dist/indicator/sma.d.ts +0 -2
  446. package/dist/indicator/sma.js +0 -19
  447. package/dist/indicator/sma.js.map +0 -1
  448. package/dist/indicator/sma.spec.d.ts +0 -1
  449. package/dist/indicator/sma.spec.js +0 -19
  450. package/dist/indicator/sma.spec.js.map +0 -1
  451. package/dist/indicator/swma.d.ts +0 -2
  452. package/dist/indicator/swma.js +0 -20
  453. package/dist/indicator/swma.js.map +0 -1
  454. package/dist/indicator/tma.d.ts +0 -2
  455. package/dist/indicator/tma.js +0 -16
  456. package/dist/indicator/tma.js.map +0 -1
  457. package/dist/indicator/tma.spec.d.ts +0 -1
  458. package/dist/indicator/tma.spec.js +0 -19
  459. package/dist/indicator/tma.spec.js.map +0 -1
  460. package/dist/indicator/trailing.d.ts +0 -13
  461. package/dist/indicator/trailing.js +0 -67
  462. package/dist/indicator/trailing.js.map +0 -1
  463. package/dist/indicator/trailing.spec.d.ts +0 -1
  464. package/dist/indicator/trailing.spec.js +0 -69
  465. package/dist/indicator/trailing.spec.js.map +0 -1
  466. package/dist/indicator/truerange.d.ts +0 -3
  467. package/dist/indicator/truerange.js +0 -19
  468. package/dist/indicator/truerange.js.map +0 -1
  469. package/dist/indicator/truerange.spec.d.ts +0 -1
  470. package/dist/indicator/truerange.spec.js +0 -28
  471. package/dist/indicator/truerange.spec.js.map +0 -1
  472. package/dist/indicator/window.d.ts +0 -3
  473. package/dist/indicator/window.js +0 -22
  474. package/dist/indicator/window.js.map +0 -1
  475. package/dist/indicator/wma.d.ts +0 -2
  476. package/dist/indicator/wma.js +0 -22
  477. package/dist/indicator/wma.js.map +0 -1
  478. package/dist/indicator/wma.spec.d.ts +0 -1
  479. package/dist/indicator/wma.spec.js +0 -19
  480. package/dist/indicator/wma.spec.js.map +0 -1
  481. package/dist/shared/collections.js.map +0 -1
  482. package/dist/shared/datetime.js.map +0 -1
  483. package/dist/shared/decimals.js.map +0 -1
  484. package/dist/shared/decimals.spec.d.ts +0 -1
  485. package/dist/shared/decimals.spec.js +0 -34
  486. package/dist/shared/decimals.spec.js.map +0 -1
  487. package/dist/shared/index.js.map +0 -1
  488. package/dist/shared/io.d.ts +0 -1
  489. package/dist/shared/io.js +0 -8
  490. package/dist/shared/io.js.map +0 -1
  491. package/dist/shared/logger.js.map +0 -1
  492. package/dist/shared/policy.js.map +0 -1
  493. package/dist/storage/cache.js.map +0 -1
  494. package/dist/storage/cache.spec.d.ts +0 -1
  495. package/dist/storage/cache.spec.js +0 -18
  496. package/dist/storage/cache.spec.js.map +0 -1
  497. package/dist/storage/feed.js.map +0 -1
  498. package/dist/storage/index.js.map +0 -1
  499. package/dist/storage/measurement.js.map +0 -1
  500. package/dist/storage/storage.js.map +0 -1
  501. package/dist/store/index.js.map +0 -1
  502. package/dist/store/store-balance.event.js.map +0 -1
  503. package/dist/store/store-balance.event.spec.d.ts +0 -1
  504. package/dist/store/store-balance.event.spec.js +0 -26
  505. package/dist/store/store-balance.event.spec.js.map +0 -1
  506. package/dist/store/store-instrument.event.js.map +0 -1
  507. package/dist/store/store-instrument.event.spec.d.ts +0 -1
  508. package/dist/store/store-instrument.event.spec.js +0 -22
  509. package/dist/store/store-instrument.event.spec.js.map +0 -1
  510. package/dist/store/store-order.event.js.map +0 -1
  511. package/dist/store/store-order.event.spec.d.ts +0 -1
  512. package/dist/store/store-order.event.spec.js +0 -21
  513. package/dist/store/store-order.event.spec.js.map +0 -1
  514. package/dist/store/store-orderbook.event.d.ts +0 -14
  515. package/dist/store/store-orderbook.event.js +0 -42
  516. package/dist/store/store-orderbook.event.js.map +0 -1
  517. package/dist/store/store-position.event.js.map +0 -1
  518. package/dist/store/store-state.js.map +0 -1
  519. package/dist/store/store-trade.event.d.ts +0 -12
  520. package/dist/store/store-trade.event.js.map +0 -1
  521. package/dist/store/store-trade.event.spec.d.ts +0 -1
  522. package/dist/store/store-trade.event.spec.js +0 -44
  523. package/dist/store/store-trade.event.spec.js.map +0 -1
  524. package/dist/store/store.event.js.map +0 -1
  525. package/dist/store/store.js.map +0 -1
  526. package/dist/store/store.spec.d.ts +0 -1
  527. package/dist/store/store.spec.js +0 -119
  528. package/dist/store/store.spec.js.map +0 -1
  529. package/dist/tsconfig.tsbuildinfo +0 -1
  530. package/jestconfig.json +0 -12
  531. package/src/adapter/backtester/backtester-adapter.spec.ts +0 -124
  532. package/src/adapter/paper/paper-adapter.spec.ts +0 -105
  533. package/src/bootstrap.ts +0 -139
  534. package/src/domain/candle.operator.spec.ts +0 -125
  535. package/src/indicator/atr.ts +0 -20
  536. package/src/indicator/cross.spec.ts +0 -151
  537. package/src/indicator/cross.ts +0 -51
  538. package/src/indicator/donchian.ts +0 -37
  539. package/src/indicator/drawdown.ts +0 -27
  540. package/src/indicator/ema.spec.ts +0 -38
  541. package/src/indicator/ema.ts +0 -26
  542. package/src/indicator/envelope.ts +0 -20
  543. package/src/indicator/index.ts +0 -17
  544. package/src/indicator/macd.ts +0 -21
  545. package/src/indicator/min-max.ts +0 -25
  546. package/src/indicator/ring-buffer.ts +0 -63
  547. package/src/indicator/rma.ts +0 -25
  548. package/src/indicator/sma.spec.ts +0 -20
  549. package/src/indicator/sma.ts +0 -24
  550. package/src/indicator/swma.ts +0 -24
  551. package/src/indicator/tma.spec.ts +0 -20
  552. package/src/indicator/tma.ts +0 -19
  553. package/src/indicator/trailing.spec.ts +0 -75
  554. package/src/indicator/trailing.ts +0 -75
  555. package/src/indicator/truerange.spec.ts +0 -32
  556. package/src/indicator/truerange.ts +0 -31
  557. package/src/indicator/window.ts +0 -28
  558. package/src/indicator/wma.spec.ts +0 -19
  559. package/src/indicator/wma.ts +0 -28
  560. package/src/shared/io.ts +0 -3
  561. package/src/store/store-order.event.spec.ts +0 -28
  562. package/src/store/store-orderbook.event.ts +0 -54
@@ -1,8 +1,8 @@
1
1
  import { Asset, Commission } from '../domain';
2
- import { now } from '../shared';
2
+ import { d, now } from '../shared';
3
3
  import { Store } from '.';
4
- import { BalancePatchEvent } from './store-balance.event';
5
- import { InstrumentPatchEvent } from './store-instrument.event';
4
+ import { BalancePatchEvent } from './store-balance-event';
5
+ import { InstrumentPatchEvent } from './store-instrument-event';
6
6
 
7
7
  describe('BalancePatchEvent', () => {
8
8
  test('should patch a store', () => {
@@ -15,15 +15,15 @@ describe('BalancePatchEvent', () => {
15
15
  store.changes$.subscribe(it => (component = it));
16
16
 
17
17
  store.dispatch(
18
- new InstrumentPatchEvent(timestamp, base, quote, new Commission(0, 0), '')
18
+ new InstrumentPatchEvent(timestamp, base, quote, new Commission(d.Zero, d.Zero), '')
19
19
  );
20
- store.dispatch(new BalancePatchEvent(base, 100, 0, timestamp));
20
+ store.dispatch(new BalancePatchEvent(base, d(100), d.Zero, timestamp));
21
21
 
22
- const balance = store.snapshot.balance.get(base.id);
22
+ const balance = store.snapshot.balance.get(base.id) ?? fail();
23
23
 
24
24
  expect(balance).toEqual(component);
25
- expect(balance.free).toEqual(100);
26
- expect(balance.locked).toEqual(0);
25
+ expect(balance.free).toEqual(d(100));
26
+ expect(balance.locked).toEqual(d.Zero);
27
27
  expect(balance.timestamp).toEqual(timestamp);
28
28
  expect(store.snapshot.timestamp).toEqual(timestamp);
29
29
  });
@@ -1,6 +1,12 @@
1
1
  import { AssetSelector, Balance, InstrumentSelector } from '../domain';
2
- import { timestamp } from '../shared';
3
- import { StoreEvent } from './store.event';
2
+ import { decimal, timestamp } from '../shared';
3
+ import {
4
+ assetNotSupportedError,
5
+ balanceNotFoundError,
6
+ instrumentNotSubscribedError,
7
+ orderNotFoundError
8
+ } from './error';
9
+ import { StoreEvent } from './store-event';
4
10
  import { State, StateChangeTracker } from './store-state';
5
11
 
6
12
  /**
@@ -9,19 +15,22 @@ import { State, StateChangeTracker } from './store-state';
9
15
  export class BalancePatchEvent implements StoreEvent {
10
16
  constructor(
11
17
  readonly asset: AssetSelector,
12
- readonly free: number,
13
- readonly freezed: number,
18
+ readonly free: decimal,
19
+ readonly freezed: decimal,
14
20
  readonly timestamp: timestamp
15
21
  ) {}
16
22
 
17
23
  handle(state: State, changes: StateChangeTracker) {
18
- // you can have not tradeable assets in wallet, skip them.
24
+ /*
25
+ * skip not tradeable assets (for example, you can have an unlisted
26
+ * asset in your wallet).
27
+ */
19
28
  const asset = state.universe.asset.get(this.asset.id);
20
29
  if (!asset) {
21
30
  return;
22
31
  }
23
32
 
24
- const balance = state.balance.tryGetOrSet(this.asset.id, () => new Balance(asset));
33
+ const balance = state.balance.tryGetOrSet(this.asset.id, () => new Balance(0, asset));
25
34
 
26
35
  balance.timestamp = this.timestamp;
27
36
  balance.set(this.free, this.freezed);
@@ -31,22 +40,24 @@ export class BalancePatchEvent implements StoreEvent {
31
40
  changes.commit(balance);
32
41
  }
33
42
  }
43
+
34
44
  /**
35
45
  *
36
46
  */
37
47
  export class BalanceTransactEvent implements StoreEvent {
38
48
  constructor(
39
49
  readonly asset: AssetSelector,
40
- readonly amount: number,
50
+ readonly amount: decimal,
41
51
  readonly timestamp: timestamp
42
52
  ) {}
43
53
 
44
54
  handle(state: State, changes: StateChangeTracker) {
45
- const balance = state.balance.tryGetOrSet(this.asset.id, () => {
46
- const asset = state.universe.asset.get(this.asset.id);
55
+ const asset = state.universe.asset.get(this.asset.id);
56
+ if (!asset) {
57
+ throw assetNotSupportedError(this.asset);
58
+ }
47
59
 
48
- return new Balance(asset);
49
- });
60
+ const balance = state.balance.tryGetOrSet(this.asset.id, () => new Balance(0, asset));
50
61
 
51
62
  balance.timestamp = this.timestamp;
52
63
  balance.account(this.amount);
@@ -68,22 +79,38 @@ export class BalanceLockOrderEvent implements StoreEvent {
68
79
  ) {}
69
80
 
70
81
  handle(state: State, changes: StateChangeTracker) {
71
- const order = state.order.get(this.instrument.id).get(this.orderId);
82
+ const orders = state.order.get(this.instrument.id);
83
+ if (!orders) {
84
+ throw instrumentNotSubscribedError(this.instrument);
85
+ }
86
+
87
+ const order = orders.get(this.orderId);
88
+ if (!order) {
89
+ throw orderNotFoundError(this.orderId);
90
+ }
91
+
72
92
  const base = state.balance.get(order.instrument.base.id);
93
+ if (!base) {
94
+ throw balanceNotFoundError(order.instrument.base);
95
+ }
96
+
73
97
  const quote = state.balance.get(order.instrument.quote.id);
98
+ if (!quote) {
99
+ throw balanceNotFoundError(order.instrument.quote);
100
+ }
74
101
 
75
102
  const balanceToLock = order.calculateBalanceToLock(base, quote);
76
103
 
77
104
  state.timestamp = this.timestamp;
78
105
 
79
- if (balanceToLock.base > 0) {
106
+ if (balanceToLock.base?.greaterThan(0)) {
80
107
  base.timestamp = this.timestamp;
81
108
  base.lock(this.orderId, balanceToLock.base);
82
109
 
83
110
  changes.commit(base);
84
111
  }
85
112
 
86
- if (balanceToLock.quote > 0) {
113
+ if (balanceToLock.quote?.greaterThan(0)) {
87
114
  quote.timestamp = this.timestamp;
88
115
  quote.lock(this.orderId, balanceToLock.quote);
89
116
 
@@ -103,9 +130,25 @@ export class BalanceUnlockOrderEvent implements StoreEvent {
103
130
  ) {}
104
131
 
105
132
  handle(state: State, changes: StateChangeTracker) {
106
- const order = state.order.get(this.instrument.id).get(this.orderId);
133
+ const orders = state.order.get(this.instrument.id);
134
+ if (!orders) {
135
+ throw instrumentNotSubscribedError(this.instrument);
136
+ }
137
+
138
+ const order = orders.get(this.orderId);
139
+ if (!order) {
140
+ throw orderNotFoundError(this.orderId);
141
+ }
142
+
107
143
  const base = state.balance.get(order.instrument.base.id);
144
+ if (!base) {
145
+ throw balanceNotFoundError(order.instrument.base);
146
+ }
147
+
108
148
  const quote = state.balance.get(order.instrument.quote.id);
149
+ if (!quote) {
150
+ throw balanceNotFoundError(order.instrument.quote);
151
+ }
109
152
 
110
153
  state.timestamp = this.timestamp;
111
154
 
File without changes
@@ -1,7 +1,7 @@
1
- import { Store } from '..';
2
1
  import { Asset, Commission } from '../domain';
3
- import { now } from '../shared';
4
- import { InstrumentPatchEvent } from './store-instrument.event';
2
+ import { d, now } from '../shared';
3
+ import { Store } from './store';
4
+ import { InstrumentPatchEvent } from './store-instrument-event';
5
5
 
6
6
  describe('InstrumentPatchEvent', () => {
7
7
  test('should patch a store', () => {
@@ -11,14 +11,15 @@ describe('InstrumentPatchEvent', () => {
11
11
  const quote = new Asset('usd', 'cex', 2);
12
12
 
13
13
  store.dispatch(
14
- new InstrumentPatchEvent(timestamp, base, quote, new Commission(0, 0), '')
14
+ new InstrumentPatchEvent(timestamp, base, quote, new Commission(d.Zero, d.Zero), '')
15
15
  );
16
16
 
17
17
  const { universe } = store.snapshot;
18
+ const instrument = universe.instrument.get('cex:de30-usd') ?? fail();
18
19
 
19
- expect(universe.instrument.get('cex:de30-usd').base).toEqual(base);
20
- expect(universe.instrument.get('cex:de30-usd').quote).toEqual(quote);
21
- expect(universe.instrument.get('cex:de30-usd').timestamp).toEqual(timestamp);
20
+ expect(instrument.base).toEqual(base);
21
+ expect(instrument.quote).toEqual(quote);
22
+ expect(instrument.timestamp).toEqual(timestamp);
22
23
  expect(universe.instrument.asReadonlyArray().length).toEqual(1);
23
24
  expect(universe.asset.asReadonlyArray().length).toEqual(2);
24
25
  });
@@ -1,8 +1,9 @@
1
- import { Asset, Commission, InstrumentSelector, Instrument } from '../domain';
1
+ import { Asset, Commission, Instrument, InstrumentSelector } from '../domain';
2
2
  import { timestamp } from '../shared';
3
- import { State, StateChangeTracker } from '../store';
3
+ import { State, StateChangeTracker } from '.';
4
+ import { assetNotSupportedError, instrumentNotSupportedError } from './error';
5
+ import { StoreEvent } from './store-event';
4
6
  import { InnerSet } from './store-state';
5
- import { StoreEvent } from './store.event';
6
7
 
7
8
  export class InstrumentPatchEvent implements StoreEvent {
8
9
  constructor(
@@ -34,7 +35,7 @@ export class InstrumentPatchEvent implements StoreEvent {
34
35
 
35
36
  state.order.tryGetOrSet(selector.id, () => new InnerSet(selector.id));
36
37
 
37
- return new Instrument(this.base, this.quote, this.raw);
38
+ return new Instrument(0, this.base, this.quote, this.raw, Commission.Zero);
38
39
  });
39
40
 
40
41
  instrument.timestamp = this.timestamp;
@@ -58,13 +59,23 @@ export class InstrumentSubscriptionEvent implements StoreEvent {
58
59
  handle(state: State, changes: StateChangeTracker): void {
59
60
  const instrument = state.universe.instrument.get(this.instrument.id);
60
61
  if (!instrument) {
61
- throw new Error('invalid instrument');
62
+ throw instrumentNotSupportedError(this.instrument);
62
63
  }
63
64
 
64
65
  if (this.subscribed) {
66
+ const base = state.universe.asset.get(instrument.base.id);
67
+ if (!base) {
68
+ throw assetNotSupportedError(instrument.base);
69
+ }
70
+
71
+ const quote = state.universe.asset.get(instrument.quote.id);
72
+ if (!quote) {
73
+ throw assetNotSupportedError(instrument.quote);
74
+ }
75
+
65
76
  state.subscription.instrument.upsert(instrument);
66
- state.subscription.asset.upsert(state.universe.asset.get(instrument.base.id));
67
- state.subscription.asset.upsert(state.universe.asset.get(instrument.quote.id));
77
+ state.subscription.asset.upsert(base);
78
+ state.subscription.asset.upsert(quote);
68
79
  }
69
80
 
70
81
  changes.commit(instrument);
@@ -0,0 +1,32 @@
1
+ import { Asset, Commission, Instrument, Order } from '../domain';
2
+ import { d, now } from '../shared';
3
+ import { Store } from '.';
4
+ import { OrderLoadEvent } from './store-order-event';
5
+
6
+ describe('OrderLoadEvent', () => {
7
+ const instrument = new Instrument(
8
+ 0,
9
+ new Asset('btc', 'binance', 8),
10
+ new Asset('usdt', 'binance', 2),
11
+ 'binance:btc-usdt',
12
+ Commission.Zero
13
+ );
14
+
15
+ test('should load order to store', () => {
16
+ const timestamp = now();
17
+ const store = new Store();
18
+ const order = new Order(0, '1', instrument, d(1.0), 0);
19
+
20
+ order.state = 'PENDING';
21
+
22
+ store.snapshot.universe.instrument.upsert(instrument);
23
+ store.snapshot.subscription.instrument.upsert(instrument);
24
+
25
+ store.dispatch(new OrderLoadEvent(order, timestamp));
26
+
27
+ const pendingOrder = store.snapshot.order.get(instrument.id)?.get('1') ?? fail();
28
+
29
+ expect(store.snapshot.order.asReadonlyArray().length).toEqual(1);
30
+ expect(pendingOrder).toEqual(order);
31
+ });
32
+ });
@@ -1,12 +1,17 @@
1
1
  import { InstrumentSelector, Order } from '../domain';
2
- import { timestamp } from '../shared';
3
- import { StoreEvent } from './store.event';
2
+ import { decimal, timestamp } from '../shared';
3
+ import { orderInvalidStateError, orderNotFoundError } from './error';
4
+ import { StoreEvent } from './store-event';
4
5
  import { InnerSet, State, StateChangeTracker } from './store-state';
5
6
 
7
+ /**
8
+ * Patches a store with an existing pending order.
9
+ * No store changing events are propagated.
10
+ */
6
11
  export class OrderLoadEvent implements StoreEvent {
7
12
  constructor(readonly order: Order, readonly timestamp: timestamp) {}
8
13
 
9
- handle(state: State, changes: StateChangeTracker): void {
14
+ handle(state: State): void {
10
15
  this.order.timestamp = this.timestamp;
11
16
 
12
17
  const orderByInstrument = state.order.tryGetOrSet(
@@ -23,7 +28,7 @@ export class OrderNewEvent implements StoreEvent {
23
28
 
24
29
  handle(state: State, changes: StateChangeTracker): void {
25
30
  if (this.order.state != 'NEW') {
26
- throw new Error(`Order is not new`);
31
+ throw orderInvalidStateError(this.order.state, ['NEW']);
27
32
  }
28
33
 
29
34
  this.order.createdAt = this.timestamp;
@@ -50,14 +55,14 @@ export class OrderPendingEvent implements StoreEvent {
50
55
  handle(state: State, changes: StateChangeTracker): void {
51
56
  const order = state.order
52
57
  .tryGetOrSet(this.instrument.id, () => {
53
- throw new Error(`Trying to patch unknown order: ${this.id}`);
58
+ throw orderNotFoundError(this.id);
54
59
  })
55
60
  .tryGetOrSet(this.id, () => {
56
- throw new Error(`Trying to patch unknown order: ${this.id}`);
61
+ throw orderNotFoundError(this.id);
57
62
  });
58
63
 
59
64
  if (order.state != 'NEW') {
60
- throw new Error(`Order is not NEW: ${order.state}`);
65
+ throw orderInvalidStateError(order.state, ['NEW']);
61
66
  }
62
67
 
63
68
  order.state = 'PENDING';
@@ -71,21 +76,21 @@ export class OrderFilledEvent implements StoreEvent {
71
76
  constructor(
72
77
  readonly id: string,
73
78
  readonly instrument: InstrumentSelector,
74
- readonly averageExecutionRate: number,
79
+ readonly averageExecutionRate: decimal,
75
80
  readonly timestamp: timestamp
76
81
  ) {}
77
82
 
78
83
  handle(state: State, changes: StateChangeTracker): void {
79
84
  const order = state.order
80
85
  .tryGetOrSet(this.instrument.id, () => {
81
- throw new Error(`Trying to patch unknown order: ${this.id}`);
86
+ throw orderNotFoundError(this.id);
82
87
  })
83
88
  .tryGetOrSet(this.id, () => {
84
- throw new Error(`Trying to patch unknown order: ${this.id}`);
89
+ throw orderNotFoundError(this.id);
85
90
  });
86
91
 
87
92
  if (order.state != 'PENDING' && order.state != 'CANCELING') {
88
- throw new Error(`Order is not PENDING or CANCELING: ${order.state}`);
93
+ throw orderInvalidStateError(order.state, ['PENDING', 'CANCELING']);
89
94
  }
90
95
 
91
96
  order.state = 'FILLED';
@@ -107,10 +112,10 @@ export class OrderCancelingEvent implements StoreEvent {
107
112
  handle(state: State, changes: StateChangeTracker): void {
108
113
  const order = state.order
109
114
  .tryGetOrSet(this.instrument.id, () => {
110
- throw new Error(`Trying to patch unknown order: ${this.id}`);
115
+ throw orderNotFoundError(this.id);
111
116
  })
112
117
  .tryGetOrSet(this.id, () => {
113
- throw new Error(`Trying to patch unknown order: ${this.id}`);
118
+ throw orderNotFoundError(this.id);
114
119
  });
115
120
 
116
121
  if (order.state == 'CANCELING' || order.state == 'CANCELED') {
@@ -118,7 +123,7 @@ export class OrderCancelingEvent implements StoreEvent {
118
123
  }
119
124
 
120
125
  if (order.state != 'PENDING') {
121
- throw new Error(`Order is not PENDING: ${order.state}`);
126
+ throw orderInvalidStateError(order.state, ['PENDING']);
122
127
  }
123
128
 
124
129
  order.state = 'CANCELING';
@@ -138,10 +143,10 @@ export class OrderCanceledEvent implements StoreEvent {
138
143
  handle(state: State, changes: StateChangeTracker): void {
139
144
  const order = state.order
140
145
  .tryGetOrSet(this.instrument.id, () => {
141
- throw new Error(`Trying to patch unknown order: ${this.id}`);
146
+ throw orderNotFoundError(this.id);
142
147
  })
143
148
  .tryGetOrSet(this.id, () => {
144
- throw new Error(`Trying to patch unknown order: ${this.id}`);
149
+ throw orderNotFoundError(this.id);
145
150
  });
146
151
 
147
152
  if (order.state == 'CANCELED') {
@@ -149,7 +154,7 @@ export class OrderCanceledEvent implements StoreEvent {
149
154
  }
150
155
 
151
156
  if (order.state != 'CANCELING') {
152
- throw new Error(`Order is not CANCELING: ${order.state}`);
157
+ throw orderInvalidStateError(order.state, ['CANCELING']);
153
158
  }
154
159
 
155
160
  order.state = 'CANCELED';
@@ -169,10 +174,10 @@ export class OrderCancelFailedEvent implements StoreEvent {
169
174
  handle(state: State, changes: StateChangeTracker): void {
170
175
  const order = state.order
171
176
  .tryGetOrSet(this.instrument.id, () => {
172
- throw new Error(`Trying to patch unknown order: ${this.id}`);
177
+ throw orderNotFoundError(this.id);
173
178
  })
174
179
  .tryGetOrSet(this.id, () => {
175
- throw new Error(`Trying to patch unknown order: ${this.id}`);
180
+ throw orderNotFoundError(this.id);
176
181
  });
177
182
 
178
183
  if (order.state != 'CANCELING') {
@@ -196,14 +201,14 @@ export class OrderRejectedEvent implements StoreEvent {
196
201
  handle(state: State, changes: StateChangeTracker): void {
197
202
  const order = state.order
198
203
  .tryGetOrSet(this.instrument.id, () => {
199
- throw new Error(`Trying to patch unknown order: ${this.id}`);
204
+ throw orderNotFoundError(this.id);
200
205
  })
201
206
  .tryGetOrSet(this.id, () => {
202
- throw new Error(`Trying to patch unknown order: ${this.id}`);
207
+ throw orderNotFoundError(this.id);
203
208
  });
204
209
 
205
210
  if (order.state != 'NEW') {
206
- throw new Error(`Order is not NEW: ${order.state}`);
211
+ throw orderInvalidStateError(order.state, ['NEW']);
207
212
  }
208
213
 
209
214
  order.state = 'REJECTED';
@@ -0,0 +1,39 @@
1
+ import { Asset, Commission, Instrument, Liquidity } from '../domain';
2
+ import { d, now } from '../shared';
3
+ import { OrderbookPatchEvent } from '.';
4
+ import { Store } from './store';
5
+
6
+ describe('OrderbookPatchEvent', () => {
7
+ const instrument = new Instrument(
8
+ 0,
9
+ new Asset('btc', 'binance', 8),
10
+ new Asset('usdt', 'binance', 2),
11
+ 'binance:btc-usdt',
12
+ Commission.Zero
13
+ );
14
+
15
+ let store: Store;
16
+
17
+ beforeEach(() => {
18
+ store = new Store();
19
+ store.snapshot.universe.instrument.upsert(instrument);
20
+ store.snapshot.subscription.instrument.upsert(instrument);
21
+ });
22
+
23
+ test('should set a best bid and ask', () => {
24
+ const timestamp = now();
25
+
26
+ const ask: Liquidity = { rate: d(2), quantity: d(2), next: undefined };
27
+ const bid: Liquidity = { rate: d(1), quantity: d(1), next: undefined };
28
+
29
+ store.dispatch(new OrderbookPatchEvent(instrument, ask, bid, timestamp));
30
+
31
+ const orderbook = store.snapshot.orderbook.get(instrument.id) ?? fail();
32
+
33
+ expect(orderbook.timestamp).toEqual(timestamp);
34
+ expect(orderbook.instrument.id).toEqual(orderbook.instrument.id);
35
+ expect(orderbook.asks).toEqual(ask);
36
+ expect(orderbook.bids).toEqual(bid);
37
+ expect(store.snapshot.timestamp).toEqual(timestamp);
38
+ });
39
+ });
@@ -0,0 +1,56 @@
1
+ import { InstrumentSelector, Liquidity, Orderbook } from '../domain';
2
+ import { timestamp } from '../shared';
3
+ import { instrumentNotSupportedError, liquidationError } from './error';
4
+ import { StoreEvent } from './store-event';
5
+ import { State, StateChangeTracker } from './store-state';
6
+
7
+ export class OrderbookPatchEvent implements StoreEvent {
8
+ constructor(
9
+ readonly instrument: InstrumentSelector,
10
+ readonly ask: Liquidity,
11
+ readonly bid: Liquidity,
12
+ readonly timestamp: timestamp
13
+ ) {}
14
+
15
+ handle(state: State, changes: StateChangeTracker): void {
16
+ const instrument = state.universe.instrument.get(this.instrument.id);
17
+ if (!instrument) {
18
+ throw instrumentNotSupportedError(this.instrument);
19
+ }
20
+
21
+ const orderbook = state.orderbook.tryGetOrSet(
22
+ this.instrument.id,
23
+ () => new Orderbook(0, instrument, this.ask, this.bid)
24
+ );
25
+
26
+ state.timestamp = this.timestamp;
27
+
28
+ orderbook.timestamp = this.timestamp;
29
+ orderbook.asks = this.ask;
30
+ orderbook.bids = this.bid;
31
+
32
+ const quote = state.balance.get(orderbook.instrument.quote.id);
33
+
34
+ if (quote) {
35
+ for (const position of Object.values(quote.position)) {
36
+ if (position.instrument.id != orderbook.instrument.id) {
37
+ continue;
38
+ }
39
+
40
+ const rate = position.size.greaterThanOrEqualTo(0)
41
+ ? orderbook.bids.rate
42
+ : orderbook.asks.rate;
43
+
44
+ if (rate) {
45
+ position.calculateEstimatedUnrealizedPnL(rate);
46
+ }
47
+ }
48
+
49
+ if (quote.total.lessThan(0)) {
50
+ throw liquidationError();
51
+ }
52
+ }
53
+
54
+ changes.commit(orderbook);
55
+ }
56
+ }
@@ -1,30 +1,35 @@
1
1
  import { Instrument, Position, PositionMode } from '../domain';
2
- import { timestamp } from '../shared';
3
- import { StoreEvent } from './store.event';
2
+ import { decimal, timestamp } from '../shared';
3
+ import { balanceNotFoundError, instrumentNotSubscribedError } from './error';
4
+ import { StoreEvent } from './store-event';
4
5
  import { State, StateChangeTracker } from './store-state';
5
6
 
6
7
  export class PositionLoadEvent implements StoreEvent {
7
8
  constructor(readonly position: Position, readonly timestamp: timestamp) {}
8
9
 
9
- handle(state: State, changes: StateChangeTracker): void {
10
+ handle(state: State): void {
10
11
  if (!state.subscription.instrument.get(this.position.instrument.id)) {
11
- throw new Error(
12
- `Trying to patch unsubscribed instrument: ${this.position.instrument.id}`
13
- );
12
+ throw instrumentNotSubscribedError(this.position.instrument);
14
13
  }
15
14
 
16
15
  this.position.timestamp = this.timestamp;
17
16
 
18
17
  const balance = state.balance.get(this.position.instrument.quote.id);
19
- const orderbook = state.orderbook.get(this.position.instrument.id);
18
+ if (!balance) {
19
+ throw balanceNotFoundError(this.position.instrument.quote);
20
+ }
20
21
 
21
22
  balance.position[this.position.id] = this.position;
22
23
 
24
+ const orderbook = state.orderbook.get(this.position.instrument.id);
23
25
  if (orderbook) {
24
- const rate =
25
- this.position.size >= 0 ? orderbook.bestBidRate : orderbook.bestAskRate;
26
+ const rate = this.position.size.greaterThanOrEqualTo(0)
27
+ ? orderbook.bids.rate
28
+ : orderbook.asks.rate;
26
29
 
27
- this.position.calculateEstimatedUnrealizedPnL(rate);
30
+ if (rate) {
31
+ this.position.calculateEstimatedUnrealizedPnL(rate);
32
+ }
28
33
  }
29
34
  }
30
35
  }
@@ -33,35 +38,44 @@ export class PositionPatchEvent implements StoreEvent {
33
38
  constructor(
34
39
  readonly id: string,
35
40
  readonly instrument: Instrument,
36
- readonly rate: number,
37
- readonly size: number,
41
+ readonly rate: decimal,
42
+ readonly size: decimal,
38
43
  readonly leverage: number,
39
44
  readonly mode: PositionMode,
40
45
  readonly timestamp: timestamp
41
46
  ) {}
42
47
 
48
+ // eslint-disable-next-line complexity
43
49
  handle(state: State, changes: StateChangeTracker): void {
44
50
  if (!state.subscription.instrument.get(this.instrument.id)) {
45
- throw new Error(`Trying to patch unsubscribed instrument: ${this.instrument.id}`);
51
+ throw instrumentNotSubscribedError(this.instrument);
46
52
  }
47
53
 
48
54
  const balance = state.balance.get(this.instrument.quote.id);
55
+ if (!balance) {
56
+ throw balanceNotFoundError(this.instrument.quote);
57
+ }
58
+
49
59
  const orderbook = state.orderbook.get(this.instrument.id);
50
60
 
51
61
  let position = balance.position[this.id];
52
62
 
53
- if (this.size == 0) {
63
+ if (this.size.equals(0)) {
54
64
  if (position) {
55
- position.averageExecutionRate = this.instrument.quote.fixed(this.rate);
56
- position.size = this.instrument.base.fixed(this.size);
65
+ position.averageExecutionRate = this.instrument.quote.floor(this.rate);
66
+ position.size = this.instrument.base.floor(this.size);
57
67
  position.leverage = this.leverage;
58
68
 
59
69
  delete balance.position[this.id];
60
70
 
61
71
  if (orderbook) {
62
- const rate = position.size >= 0 ? orderbook.bestBidRate : orderbook.bestAskRate;
72
+ const rate = position.size.greaterThanOrEqualTo(0)
73
+ ? orderbook.bids.rate
74
+ : orderbook.asks.rate;
63
75
 
64
- position.calculateEstimatedUnrealizedPnL(rate);
76
+ if (rate) {
77
+ position.calculateEstimatedUnrealizedPnL(rate);
78
+ }
65
79
  }
66
80
 
67
81
  changes.commit(position);
@@ -69,12 +83,13 @@ export class PositionPatchEvent implements StoreEvent {
69
83
  }
70
84
  }
71
85
 
72
- const size = (position.size = this.instrument.base.fixed(this.size));
86
+ const size = (position.size = this.instrument.base.floor(this.size));
73
87
  const averageExecutionRate = (position.averageExecutionRate =
74
- this.instrument.quote.fixed(this.rate));
88
+ this.instrument.quote.floor(this.rate));
75
89
 
76
90
  if (!position) {
77
91
  position = new Position(
92
+ this.timestamp,
78
93
  this.id,
79
94
  this.instrument,
80
95
  this.mode,
@@ -91,9 +106,13 @@ export class PositionPatchEvent implements StoreEvent {
91
106
  }
92
107
 
93
108
  if (orderbook) {
94
- const rate = position.size >= 0 ? orderbook.bestBidRate : orderbook.bestAskRate;
109
+ const rate = position.size.greaterThanOrEqualTo(0)
110
+ ? orderbook.bids.rate
111
+ : orderbook.asks.rate;
95
112
 
96
- position.calculateEstimatedUnrealizedPnL(rate);
113
+ if (rate) {
114
+ position.calculateEstimatedUnrealizedPnL(rate);
115
+ }
97
116
  }
98
117
 
99
118
  changes.commit(position);