@quantform/core 0.5.14 → 0.5.15

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 (408) hide show
  1. package/dist/adapter/adapter-aggregate.d.ts +4 -2
  2. package/dist/adapter/adapter-aggregate.js +16 -18
  3. package/dist/adapter/adapter-aggregate.js.map +1 -1
  4. package/dist/adapter/adapter.d.ts +20 -21
  5. package/dist/adapter/adapter.js +8 -43
  6. package/dist/adapter/adapter.js.map +1 -1
  7. package/dist/adapter/backtester/backtester-adapter.d.ts +9 -7
  8. package/dist/adapter/backtester/backtester-adapter.js +13 -12
  9. package/dist/adapter/backtester/backtester-adapter.js.map +1 -1
  10. package/dist/{tests → adapter/backtester}/backtester-adapter.spec.d.ts +0 -0
  11. package/dist/adapter/backtester/backtester-adapter.spec.js +82 -0
  12. package/dist/adapter/backtester/backtester-adapter.spec.js.map +1 -0
  13. package/dist/adapter/backtester/backtester-cursor.d.ts +3 -4
  14. package/dist/adapter/backtester/backtester-cursor.js +2 -1
  15. package/dist/adapter/backtester/backtester-cursor.js.map +1 -1
  16. package/dist/adapter/backtester/backtester-cursor.spec.js +17 -18
  17. package/dist/adapter/backtester/backtester-cursor.spec.js.map +1 -1
  18. package/dist/adapter/backtester/backtester-streamer.d.ts +4 -1
  19. package/dist/adapter/backtester/backtester-streamer.js +39 -18
  20. package/dist/adapter/backtester/backtester-streamer.js.map +1 -1
  21. package/dist/adapter/backtester/backtester-streamer.spec.js +13 -13
  22. package/dist/adapter/backtester/backtester-streamer.spec.js.map +1 -1
  23. package/dist/adapter/error.d.ts +2 -0
  24. package/dist/adapter/error.js +12 -0
  25. package/dist/adapter/error.js.map +1 -0
  26. package/dist/adapter/paper/engine/paper-engine.d.ts +11 -0
  27. package/dist/adapter/paper/engine/paper-engine.js +103 -0
  28. package/dist/adapter/paper/engine/paper-engine.js.map +1 -0
  29. package/dist/adapter/paper/{simulator/paper-spot-simulator.spec.d.ts → engine/paper-engine.spec.d.ts} +0 -0
  30. package/dist/adapter/paper/engine/paper-engine.spec.js +54 -0
  31. package/dist/adapter/paper/engine/paper-engine.spec.js.map +1 -0
  32. package/dist/adapter/paper/index.d.ts +1 -2
  33. package/dist/adapter/paper/index.js +1 -2
  34. package/dist/adapter/paper/index.js.map +1 -1
  35. package/dist/adapter/paper/paper-adapter.d.ts +7 -7
  36. package/dist/adapter/paper/paper-adapter.js +20 -18
  37. package/dist/adapter/paper/paper-adapter.js.map +1 -1
  38. package/dist/adapter/paper/paper-adapter.spec.js +35 -17
  39. package/dist/adapter/paper/paper-adapter.spec.js.map +1 -1
  40. package/dist/bootstrap.js +11 -10
  41. package/dist/bootstrap.js.map +1 -1
  42. package/dist/cli/pull.js +3 -1
  43. package/dist/cli/pull.js.map +1 -1
  44. package/dist/cli/test.js +5 -1
  45. package/dist/cli/test.js.map +1 -1
  46. package/dist/domain/asset.d.ts +6 -5
  47. package/dist/domain/asset.js +22 -16
  48. package/dist/domain/asset.js.map +1 -1
  49. package/dist/domain/asset.spec.js +32 -32
  50. package/dist/domain/asset.spec.js.map +1 -1
  51. package/dist/domain/balance.d.ts +7 -7
  52. package/dist/domain/balance.js +26 -21
  53. package/dist/domain/balance.js.map +1 -1
  54. package/dist/domain/balance.operator.d.ts +6 -0
  55. package/dist/domain/balance.operator.js +10 -0
  56. package/dist/domain/balance.operator.js.map +1 -0
  57. package/dist/{shared/policy.spec.d.ts → domain/balance.operator.spec.d.ts} +0 -0
  58. package/dist/domain/balance.operator.spec.js +23 -0
  59. package/dist/domain/balance.operator.spec.js.map +1 -0
  60. package/dist/domain/balance.spec.js +67 -7
  61. package/dist/domain/balance.spec.js.map +1 -1
  62. package/dist/domain/candle.d.ts +2 -17
  63. package/dist/domain/candle.js +3 -70
  64. package/dist/domain/candle.js.map +1 -1
  65. package/dist/domain/candle.operator.d.ts +9 -0
  66. package/dist/domain/candle.operator.js +64 -0
  67. package/dist/domain/candle.operator.js.map +1 -0
  68. package/dist/{shared/topic.spec.d.ts → domain/candle.operator.spec.d.ts} +0 -0
  69. package/dist/domain/candle.operator.spec.js +111 -0
  70. package/dist/domain/candle.operator.spec.js.map +1 -0
  71. package/dist/domain/candle.spec.js +11 -53
  72. package/dist/domain/candle.spec.js.map +1 -1
  73. package/dist/domain/commission.d.ts +4 -1
  74. package/dist/domain/commission.js +2 -2
  75. package/dist/domain/commission.js.map +1 -1
  76. package/dist/{store/event/store-balance.event.spec.d.ts → domain/commission.spec.d.ts} +0 -0
  77. package/dist/domain/commission.spec.js +30 -0
  78. package/dist/domain/commission.spec.js.map +1 -0
  79. package/dist/domain/component.d.ts +1 -0
  80. package/dist/domain/error.d.ts +5 -0
  81. package/dist/domain/error.js +24 -0
  82. package/dist/domain/error.js.map +1 -0
  83. package/dist/domain/index.d.ts +8 -1
  84. package/dist/domain/index.js +8 -1
  85. package/dist/domain/index.js.map +1 -1
  86. package/dist/domain/instrument.d.ts +3 -2
  87. package/dist/domain/instrument.js +17 -9
  88. package/dist/domain/instrument.js.map +1 -1
  89. package/dist/domain/instrument.operator.d.ts +6 -0
  90. package/dist/domain/instrument.operator.js +14 -0
  91. package/dist/domain/instrument.operator.js.map +1 -0
  92. package/dist/{store/event/store-candle.event.spec.d.ts → domain/instrument.operator.spec.d.ts} +0 -0
  93. package/dist/domain/instrument.operator.spec.js +24 -0
  94. package/dist/domain/instrument.operator.spec.js.map +1 -0
  95. package/dist/domain/instrument.spec.js +22 -30
  96. package/dist/domain/instrument.spec.js.map +1 -1
  97. package/dist/domain/order.d.ts +12 -14
  98. package/dist/domain/order.js +37 -26
  99. package/dist/domain/order.js.map +1 -1
  100. package/dist/domain/order.operator.d.ts +7 -0
  101. package/dist/domain/order.operator.js +14 -0
  102. package/dist/domain/order.operator.js.map +1 -0
  103. package/dist/{store/event/store-instrument.event.spec.d.ts → domain/order.operator.spec.d.ts} +0 -0
  104. package/dist/domain/order.operator.spec.js +64 -0
  105. package/dist/domain/order.operator.spec.js.map +1 -0
  106. package/dist/{store/event/store-order.event.spec.d.ts → domain/order.spec.d.ts} +0 -0
  107. package/dist/domain/order.spec.js +33 -0
  108. package/dist/domain/order.spec.js.map +1 -0
  109. package/dist/domain/orderbook.d.ts +1 -0
  110. package/dist/domain/orderbook.js +1 -0
  111. package/dist/domain/orderbook.js.map +1 -1
  112. package/dist/domain/orderbook.operator.d.ts +6 -0
  113. package/dist/domain/orderbook.operator.js +10 -0
  114. package/dist/domain/orderbook.operator.js.map +1 -0
  115. package/dist/{store/event/store-trade.event.spec.d.ts → domain/orderbook.operator.spec.d.ts} +0 -0
  116. package/dist/domain/orderbook.operator.spec.js +22 -0
  117. package/dist/domain/orderbook.operator.spec.js.map +1 -0
  118. package/dist/domain/orderbook.spec.d.ts +1 -0
  119. package/dist/domain/orderbook.spec.js +13 -0
  120. package/dist/domain/orderbook.spec.js.map +1 -0
  121. package/dist/domain/position.d.ts +6 -11
  122. package/dist/domain/position.js +9 -31
  123. package/dist/domain/position.js.map +1 -1
  124. package/dist/domain/position.operator.d.ts +10 -0
  125. package/dist/domain/position.operator.js +38 -0
  126. package/dist/domain/position.operator.js.map +1 -0
  127. package/dist/domain/position.operator.spec.d.ts +1 -0
  128. package/dist/domain/position.operator.spec.js +48 -0
  129. package/dist/domain/position.operator.spec.js.map +1 -0
  130. package/dist/domain/position.spec.js +21 -17
  131. package/dist/domain/position.spec.js.map +1 -1
  132. package/dist/domain/session.d.ts +15 -18
  133. package/dist/domain/session.js +21 -31
  134. package/dist/domain/session.js.map +1 -1
  135. package/dist/domain/session.spec.js +1 -1
  136. package/dist/domain/session.spec.js.map +1 -1
  137. package/dist/domain/trade.d.ts +1 -0
  138. package/dist/domain/trade.js +1 -0
  139. package/dist/domain/trade.js.map +1 -1
  140. package/dist/domain/trade.operator.d.ts +6 -0
  141. package/dist/domain/trade.operator.js +10 -0
  142. package/dist/domain/trade.operator.js.map +1 -0
  143. package/dist/domain/trade.operator.spec.d.ts +1 -0
  144. package/dist/domain/trade.operator.spec.js +24 -0
  145. package/dist/domain/trade.operator.spec.js.map +1 -0
  146. package/dist/domain/trade.spec.d.ts +1 -0
  147. package/dist/domain/trade.spec.js +13 -0
  148. package/dist/domain/trade.spec.js.map +1 -0
  149. package/dist/indicator/cross.spec.js +2 -2
  150. package/dist/indicator/cross.spec.js.map +1 -1
  151. package/dist/indicator/ema.spec.js +1 -1
  152. package/dist/indicator/ema.spec.js.map +1 -1
  153. package/dist/indicator/sma.spec.js +1 -1
  154. package/dist/indicator/sma.spec.js.map +1 -1
  155. package/dist/indicator/tma.spec.js +1 -1
  156. package/dist/indicator/tma.spec.js.map +1 -1
  157. package/dist/indicator/trailing.spec.js +2 -2
  158. package/dist/indicator/trailing.spec.js.map +1 -1
  159. package/dist/indicator/truerange.spec.js +1 -1
  160. package/dist/indicator/truerange.spec.js.map +1 -1
  161. package/dist/indicator/wma.spec.js +1 -1
  162. package/dist/indicator/wma.spec.js.map +1 -1
  163. package/dist/shared/collections.d.ts +10 -0
  164. package/dist/shared/collections.js +33 -0
  165. package/dist/shared/collections.js.map +1 -0
  166. package/dist/shared/datetime.d.ts +0 -1
  167. package/dist/shared/datetime.js +1 -12
  168. package/dist/shared/datetime.js.map +1 -1
  169. package/dist/shared/decimals.d.ts +1 -1
  170. package/dist/shared/decimals.js +4 -5
  171. package/dist/shared/decimals.js.map +1 -1
  172. package/dist/shared/decimals.spec.js +2 -1
  173. package/dist/shared/decimals.spec.js.map +1 -1
  174. package/dist/shared/index.d.ts +1 -1
  175. package/dist/shared/index.js +1 -1
  176. package/dist/shared/index.js.map +1 -1
  177. package/dist/shared/io.js.map +1 -1
  178. package/dist/shared/policy.d.ts +0 -1
  179. package/dist/shared/policy.js +1 -11
  180. package/dist/shared/policy.js.map +1 -1
  181. package/dist/storage/cache.js +1 -1
  182. package/dist/storage/cache.js.map +1 -1
  183. package/dist/storage/cache.spec.d.ts +1 -0
  184. package/dist/storage/cache.spec.js +18 -0
  185. package/dist/storage/cache.spec.js.map +1 -0
  186. package/dist/storage/feed.d.ts +3 -4
  187. package/dist/storage/feed.js +16 -6
  188. package/dist/storage/feed.js.map +1 -1
  189. package/dist/storage/storage.d.ts +2 -7
  190. package/dist/storage/storage.js +6 -11
  191. package/dist/storage/storage.js.map +1 -1
  192. package/dist/store/index.d.ts +8 -2
  193. package/dist/store/index.js +8 -2
  194. package/dist/store/index.js.map +1 -1
  195. package/dist/store/store-balance.event.d.ts +33 -0
  196. package/dist/store/store-balance.event.js +90 -0
  197. package/dist/store/store-balance.event.js.map +1 -0
  198. package/dist/store/store-balance.event.spec.d.ts +1 -0
  199. package/dist/store/{event/store-balance.event.spec.js → store-balance.event.spec.js} +7 -7
  200. package/dist/store/store-balance.event.spec.js.map +1 -0
  201. package/dist/store/{event/store-instrument.event.d.ts → store-instrument.event.d.ts} +5 -8
  202. package/dist/store/store-instrument.event.js +52 -0
  203. package/dist/store/store-instrument.event.js.map +1 -0
  204. package/dist/store/store-instrument.event.spec.d.ts +1 -0
  205. package/dist/store/store-instrument.event.spec.js +22 -0
  206. package/dist/store/store-instrument.event.spec.js.map +1 -0
  207. package/dist/store/store-order.event.d.ts +59 -0
  208. package/dist/store/store-order.event.js +181 -0
  209. package/dist/store/store-order.event.js.map +1 -0
  210. package/dist/store/store-order.event.spec.d.ts +1 -0
  211. package/dist/store/{event/store-order.event.spec.js → store-order.event.spec.js} +8 -8
  212. package/dist/store/store-order.event.spec.js.map +1 -0
  213. package/dist/store/{event/store-orderbook.event.d.ts → store-orderbook.event.d.ts} +4 -5
  214. package/dist/store/store-orderbook.event.js +42 -0
  215. package/dist/store/store-orderbook.event.js.map +1 -0
  216. package/dist/store/{event/store-position.event.d.ts → store-position.event.d.ts} +5 -7
  217. package/dist/store/store-position.event.js +77 -0
  218. package/dist/store/store-position.event.js.map +1 -0
  219. package/dist/store/store-state.d.ts +27 -0
  220. package/dist/store/store-state.js +29 -0
  221. package/dist/store/store-state.js.map +1 -0
  222. package/dist/store/{event/store-trade.event.d.ts → store-trade.event.d.ts} +4 -5
  223. package/dist/store/store-trade.event.js +25 -0
  224. package/dist/store/store-trade.event.js.map +1 -0
  225. package/dist/store/store-trade.event.spec.d.ts +1 -0
  226. package/dist/store/{event/store-trade.event.spec.js → store-trade.event.spec.js} +13 -13
  227. package/dist/store/store-trade.event.spec.js.map +1 -0
  228. package/dist/store/store.d.ts +4 -25
  229. package/dist/store/store.event.d.ts +6 -0
  230. package/dist/store/{event/store.event.js → store.event.js} +0 -0
  231. package/dist/store/store.event.js.map +1 -0
  232. package/dist/store/store.js +7 -195
  233. package/dist/store/store.js.map +1 -1
  234. package/dist/store/store.spec.d.ts +1 -0
  235. package/dist/store/store.spec.js +119 -0
  236. package/dist/store/store.spec.js.map +1 -0
  237. package/dist/tsconfig.tsbuildinfo +1 -1
  238. package/{jestconfig.unit.json → jestconfig.json} +1 -2
  239. package/package.json +2 -6
  240. package/src/adapter/adapter-aggregate.ts +27 -35
  241. package/src/adapter/adapter.ts +25 -54
  242. package/src/adapter/backtester/backtester-adapter.spec.ts +124 -0
  243. package/src/adapter/backtester/backtester-adapter.ts +28 -17
  244. package/src/adapter/backtester/backtester-cursor.spec.ts +18 -19
  245. package/src/adapter/backtester/backtester-cursor.ts +7 -7
  246. package/src/adapter/backtester/backtester-streamer.spec.ts +19 -19
  247. package/src/adapter/backtester/backtester-streamer.ts +50 -20
  248. package/src/adapter/error.ts +9 -0
  249. package/src/adapter/paper/engine/paper-engine.spec.ts +92 -0
  250. package/src/adapter/paper/engine/paper-engine.ts +135 -0
  251. package/src/adapter/paper/index.ts +1 -2
  252. package/src/adapter/paper/paper-adapter.spec.ts +55 -19
  253. package/src/adapter/paper/paper-adapter.ts +27 -24
  254. package/src/bootstrap.ts +26 -19
  255. package/src/cli/pull.ts +5 -1
  256. package/src/cli/test.ts +5 -2
  257. package/src/domain/asset.spec.ts +33 -29
  258. package/src/domain/asset.ts +27 -21
  259. package/src/domain/balance.operator.spec.ts +25 -0
  260. package/src/domain/balance.operator.ts +15 -0
  261. package/src/domain/balance.spec.ts +95 -7
  262. package/src/domain/balance.ts +35 -29
  263. package/src/domain/candle.operator.spec.ts +125 -0
  264. package/src/domain/candle.operator.ts +106 -0
  265. package/src/domain/candle.spec.ts +12 -68
  266. package/src/domain/candle.ts +2 -114
  267. package/src/domain/commission.spec.ts +33 -0
  268. package/src/domain/commission.ts +2 -2
  269. package/src/domain/component.ts +1 -0
  270. package/src/domain/error.ts +25 -0
  271. package/src/domain/index.ts +8 -1
  272. package/src/domain/instrument.operator.spec.ts +28 -0
  273. package/src/domain/instrument.operator.ts +25 -0
  274. package/src/domain/instrument.spec.ts +22 -30
  275. package/src/domain/instrument.ts +20 -11
  276. package/src/domain/order.operator.spec.ts +81 -0
  277. package/src/domain/order.operator.ts +23 -0
  278. package/src/domain/order.spec.ts +43 -0
  279. package/src/domain/order.ts +43 -46
  280. package/src/domain/orderbook.operator.spec.ts +28 -0
  281. package/src/domain/orderbook.operator.ts +15 -0
  282. package/src/domain/orderbook.spec.ts +17 -0
  283. package/src/domain/orderbook.ts +4 -1
  284. package/src/domain/position.operator.spec.ts +58 -0
  285. package/src/domain/position.operator.ts +61 -0
  286. package/src/domain/position.spec.ts +28 -24
  287. package/src/domain/position.ts +16 -48
  288. package/src/domain/session.spec.ts +1 -1
  289. package/src/domain/session.ts +41 -131
  290. package/src/domain/trade.operator.spec.ts +31 -0
  291. package/src/domain/trade.operator.ts +15 -0
  292. package/src/domain/trade.spec.ts +17 -0
  293. package/src/domain/trade.ts +4 -1
  294. package/src/indicator/cross.spec.ts +2 -2
  295. package/src/indicator/ema.spec.ts +1 -1
  296. package/src/indicator/sma.spec.ts +1 -1
  297. package/src/indicator/tma.spec.ts +1 -1
  298. package/src/indicator/trailing.spec.ts +2 -2
  299. package/src/indicator/truerange.spec.ts +1 -1
  300. package/src/indicator/wma.spec.ts +1 -1
  301. package/src/shared/collections.ts +35 -0
  302. package/src/shared/datetime.ts +0 -12
  303. package/src/shared/decimals.spec.ts +2 -1
  304. package/src/shared/decimals.ts +6 -6
  305. package/src/shared/index.ts +1 -1
  306. package/src/shared/io.ts +0 -2
  307. package/src/shared/policy.ts +0 -13
  308. package/src/storage/cache.spec.ts +18 -0
  309. package/src/storage/cache.ts +1 -1
  310. package/src/storage/feed.ts +26 -16
  311. package/src/storage/storage.ts +9 -13
  312. package/src/store/index.ts +8 -2
  313. package/src/store/{event/store-balance.event.spec.ts → store-balance.event.spec.ts} +6 -6
  314. package/src/store/store-balance.event.ts +124 -0
  315. package/src/store/store-instrument.event.spec.ts +25 -0
  316. package/src/store/store-instrument.event.ts +72 -0
  317. package/src/store/store-order.event.spec.ts +28 -0
  318. package/src/store/store-order.event.ts +214 -0
  319. package/src/store/store-orderbook.event.ts +54 -0
  320. package/src/store/store-position.event.ts +102 -0
  321. package/src/store/store-state.ts +48 -0
  322. package/src/store/{event/store-trade.event.spec.ts → store-trade.event.spec.ts} +14 -14
  323. package/src/store/store-trade.event.ts +36 -0
  324. package/src/store/store.event.ts +8 -0
  325. package/src/store/store.spec.ts +180 -0
  326. package/src/store/store.ts +10 -208
  327. package/dist/adapter/paper/simulator/paper-margin-simulator.d.ts +0 -10
  328. package/dist/adapter/paper/simulator/paper-margin-simulator.js +0 -69
  329. package/dist/adapter/paper/simulator/paper-margin-simulator.js.map +0 -1
  330. package/dist/adapter/paper/simulator/paper-simulator.d.ts +0 -16
  331. package/dist/adapter/paper/simulator/paper-simulator.js +0 -93
  332. package/dist/adapter/paper/simulator/paper-simulator.js.map +0 -1
  333. package/dist/adapter/paper/simulator/paper-spot-simulator.d.ts +0 -13
  334. package/dist/adapter/paper/simulator/paper-spot-simulator.js +0 -81
  335. package/dist/adapter/paper/simulator/paper-spot-simulator.js.map +0 -1
  336. package/dist/adapter/paper/simulator/paper-spot-simulator.spec.js +0 -49
  337. package/dist/adapter/paper/simulator/paper-spot-simulator.spec.js.map +0 -1
  338. package/dist/domain/statement.d.ts +0 -4
  339. package/dist/domain/statement.js +0 -87
  340. package/dist/domain/statement.js.map +0 -1
  341. package/dist/shared/policy.spec.js +0 -22
  342. package/dist/shared/policy.spec.js.map +0 -1
  343. package/dist/shared/topic.d.ts +0 -14
  344. package/dist/shared/topic.js +0 -40
  345. package/dist/shared/topic.js.map +0 -1
  346. package/dist/shared/topic.spec.js +0 -43
  347. package/dist/shared/topic.spec.js.map +0 -1
  348. package/dist/store/event/index.d.ts +0 -8
  349. package/dist/store/event/index.js +0 -25
  350. package/dist/store/event/index.js.map +0 -1
  351. package/dist/store/event/store-balance.event.d.ts +0 -37
  352. package/dist/store/event/store-balance.event.js +0 -119
  353. package/dist/store/event/store-balance.event.js.map +0 -1
  354. package/dist/store/event/store-balance.event.spec.js.map +0 -1
  355. package/dist/store/event/store-candle.event.d.ts +0 -18
  356. package/dist/store/event/store-candle.event.js +0 -63
  357. package/dist/store/event/store-candle.event.js.map +0 -1
  358. package/dist/store/event/store-candle.event.spec.js +0 -23
  359. package/dist/store/event/store-candle.event.spec.js.map +0 -1
  360. package/dist/store/event/store-instrument.event.js +0 -78
  361. package/dist/store/event/store-instrument.event.js.map +0 -1
  362. package/dist/store/event/store-instrument.event.spec.js +0 -21
  363. package/dist/store/event/store-instrument.event.spec.js.map +0 -1
  364. package/dist/store/event/store-order.event.d.ts +0 -61
  365. package/dist/store/event/store-order.event.js +0 -205
  366. package/dist/store/event/store-order.event.js.map +0 -1
  367. package/dist/store/event/store-order.event.spec.js.map +0 -1
  368. package/dist/store/event/store-orderbook.event.js +0 -65
  369. package/dist/store/event/store-orderbook.event.js.map +0 -1
  370. package/dist/store/event/store-position.event.js +0 -97
  371. package/dist/store/event/store-position.event.js.map +0 -1
  372. package/dist/store/event/store-trade.event.js +0 -47
  373. package/dist/store/event/store-trade.event.js.map +0 -1
  374. package/dist/store/event/store-trade.event.spec.js.map +0 -1
  375. package/dist/store/event/store.event.d.ts +0 -5
  376. package/dist/store/event/store.event.js.map +0 -1
  377. package/dist/store/store.state.d.ts +0 -21
  378. package/dist/store/store.state.js +0 -21
  379. package/dist/store/store.state.js.map +0 -1
  380. package/dist/tests/backtester-adapter.spec.js +0 -61
  381. package/dist/tests/backtester-adapter.spec.js.map +0 -1
  382. package/dist/tests/session.spec.d.ts +0 -0
  383. package/dist/tests/session.spec.js +0 -1
  384. package/dist/tests/session.spec.js.map +0 -1
  385. package/jestconfig.integration.json +0 -12
  386. package/src/adapter/paper/simulator/paper-margin-simulator.ts +0 -108
  387. package/src/adapter/paper/simulator/paper-simulator.ts +0 -121
  388. package/src/adapter/paper/simulator/paper-spot-simulator.spec.ts +0 -87
  389. package/src/adapter/paper/simulator/paper-spot-simulator.ts +0 -134
  390. package/src/domain/statement.ts +0 -119
  391. package/src/shared/policy.spec.ts +0 -25
  392. package/src/shared/topic.spec.ts +0 -34
  393. package/src/shared/topic.ts +0 -43
  394. package/src/store/event/index.ts +0 -8
  395. package/src/store/event/store-balance.event.ts +0 -161
  396. package/src/store/event/store-candle.event.spec.ts +0 -30
  397. package/src/store/event/store-candle.event.ts +0 -71
  398. package/src/store/event/store-instrument.event.spec.ts +0 -25
  399. package/src/store/event/store-instrument.event.ts +0 -84
  400. package/src/store/event/store-order.event.spec.ts +0 -28
  401. package/src/store/event/store-order.event.ts +0 -218
  402. package/src/store/event/store-orderbook.event.ts +0 -70
  403. package/src/store/event/store-position.event.ts +0 -109
  404. package/src/store/event/store-trade.event.ts +0 -52
  405. package/src/store/event/store.event.ts +0 -6
  406. package/src/store/store.state.ts +0 -43
  407. package/src/tests/backtester-adapter.spec.ts +0 -88
  408. package/src/tests/session.spec.ts +0 -121
@@ -1,4 +1,4 @@
1
- import { InstrumentSelector } from '../domain';
1
+ import { Candle, InstrumentSelector } from '../domain';
2
2
  import { StoreEvent } from '../store';
3
3
  import { Storage, StorageQueryOptions } from './storage';
4
4
 
@@ -19,18 +19,22 @@ export class Feed {
19
19
  /**
20
20
  *
21
21
  * @param instrument
22
- * @param events
22
+ * @param candles
23
23
  * @returns
24
24
  */
25
- save(instrument: InstrumentSelector, events: StoreEvent[]): Promise<void> {
25
+ save(instrument: InstrumentSelector, candles: Candle[]): Promise<void> {
26
26
  return this.storage.save(
27
27
  instrument.toString(),
28
- events.map(it => ({
28
+ candles.map(it => ({
29
29
  timestamp: it.timestamp,
30
- kind: it.type,
31
- json: JSON.stringify(it, (key, value) =>
32
- key != 'timestamp' && key != 'type' && key != 'instrument' ? value : undefined
33
- )
30
+ kind: 'candle',
31
+ json: JSON.stringify({
32
+ o: it.open,
33
+ h: it.high,
34
+ l: it.low,
35
+ c: it.close,
36
+ v: it.volume
37
+ })
34
38
  }))
35
39
  );
36
40
  }
@@ -44,14 +48,20 @@ export class Feed {
44
48
  async query(
45
49
  instrument: InstrumentSelector,
46
50
  options: StorageQueryOptions
47
- ): Promise<StoreEvent[]> {
48
- const rows = await this.storage.query(instrument.toString(), options);
51
+ ): Promise<Candle[]> {
52
+ const rows = await this.storage.query(instrument.id, options);
49
53
 
50
- return rows.map(it => ({
51
- timestamp: it.timestamp,
52
- type: it.kind,
53
- instrument,
54
- ...JSON.parse(it.json)
55
- }));
54
+ return rows.map(it => {
55
+ const payload = JSON.parse(it.json);
56
+
57
+ return new Candle(
58
+ it.timestamp,
59
+ payload.o,
60
+ payload.h,
61
+ payload.l,
62
+ payload.c,
63
+ payload.v
64
+ );
65
+ });
56
66
  }
57
67
  }
@@ -11,6 +11,11 @@ export type StorageQueryOptions = {
11
11
  count: number;
12
12
  };
13
13
 
14
+ /**
15
+ *
16
+ */
17
+ export type StorageFactory = (type: string) => Storage;
18
+
14
19
  /**
15
20
  *
16
21
  */
@@ -35,11 +40,10 @@ export interface Storage {
35
40
  query(library: string, options: StorageQueryOptions): Promise<StorageDocument[]>;
36
41
  }
37
42
 
38
- /**
39
- *
40
- */
41
- export interface StorageFactory {
42
- create(type: string): Storage;
43
+ export function inMemoryStorageFactory(): StorageFactory {
44
+ const storage: Record<string, Storage> = {};
45
+
46
+ return (type: string) => storage[type] ?? (storage[type] = new InMemoryStorage());
43
47
  }
44
48
 
45
49
  /**
@@ -118,11 +122,3 @@ export class InMemoryStorage implements Storage {
118
122
  this.tables = {};
119
123
  }
120
124
  }
121
-
122
- export class InMemoryStorageFactory implements StorageFactory {
123
- private readonly storage: Record<string, Storage> = {};
124
-
125
- create(type: string): Storage {
126
- return this.storage[type] ?? (this.storage[type] = new InMemoryStorage());
127
- }
128
- }
@@ -1,3 +1,9 @@
1
- export * from './event';
2
1
  export * from './store';
3
- export * from './store.state';
2
+ export * from './store-state';
3
+ export * from './store-balance.event';
4
+ export * from './store-instrument.event';
5
+ export * from './store-order.event';
6
+ export * from './store-orderbook.event';
7
+ export * from './store-position.event';
8
+ export * from './store-trade.event';
9
+ export * from './store.event';
@@ -1,10 +1,10 @@
1
- import { Asset, Commission } from '../../domain';
2
- import { now } from '../../shared';
3
- import { Store } from '..';
4
- import { BalancePatchEvent } from '.';
1
+ import { Asset, Commission } from '../domain';
2
+ import { now } from '../shared';
3
+ import { Store } from '.';
4
+ import { BalancePatchEvent } from './store-balance.event';
5
5
  import { InstrumentPatchEvent } from './store-instrument.event';
6
6
 
7
- describe('balance event tests', () => {
7
+ describe('BalancePatchEvent', () => {
8
8
  test('should patch a store', () => {
9
9
  const base = new Asset('de30', 'cex', 2);
10
10
  const quote = new Asset('usd', 'cex', 2);
@@ -19,7 +19,7 @@ describe('balance event tests', () => {
19
19
  );
20
20
  store.dispatch(new BalancePatchEvent(base, 100, 0, timestamp));
21
21
 
22
- const balance = store.snapshot.balance[base.toString()];
22
+ const balance = store.snapshot.balance.get(base.id);
23
23
 
24
24
  expect(balance).toEqual(component);
25
25
  expect(balance.free).toEqual(100);
@@ -0,0 +1,124 @@
1
+ import { AssetSelector, Balance, InstrumentSelector } from '../domain';
2
+ import { timestamp } from '../shared';
3
+ import { StoreEvent } from './store.event';
4
+ import { State, StateChangeTracker } from './store-state';
5
+
6
+ /**
7
+ * Updates the free and freezed balance of the given asset.
8
+ */
9
+ export class BalancePatchEvent implements StoreEvent {
10
+ constructor(
11
+ readonly asset: AssetSelector,
12
+ readonly free: number,
13
+ readonly freezed: number,
14
+ readonly timestamp: timestamp
15
+ ) {}
16
+
17
+ handle(state: State, changes: StateChangeTracker) {
18
+ // you can have not tradeable assets in wallet, skip them.
19
+ const asset = state.universe.asset.get(this.asset.id);
20
+ if (!asset) {
21
+ return;
22
+ }
23
+
24
+ const balance = state.balance.tryGetOrSet(this.asset.id, () => new Balance(asset));
25
+
26
+ balance.timestamp = this.timestamp;
27
+ balance.set(this.free, this.freezed);
28
+
29
+ state.timestamp = this.timestamp;
30
+
31
+ changes.commit(balance);
32
+ }
33
+ }
34
+ /**
35
+ *
36
+ */
37
+ export class BalanceTransactEvent implements StoreEvent {
38
+ constructor(
39
+ readonly asset: AssetSelector,
40
+ readonly amount: number,
41
+ readonly timestamp: timestamp
42
+ ) {}
43
+
44
+ handle(state: State, changes: StateChangeTracker) {
45
+ const balance = state.balance.tryGetOrSet(this.asset.id, () => {
46
+ const asset = state.universe.asset.get(this.asset.id);
47
+
48
+ return new Balance(asset);
49
+ });
50
+
51
+ balance.timestamp = this.timestamp;
52
+ balance.account(this.amount);
53
+
54
+ state.timestamp = this.timestamp;
55
+
56
+ changes.commit(balance);
57
+ }
58
+ }
59
+
60
+ /**
61
+ *
62
+ */
63
+ export class BalanceLockOrderEvent implements StoreEvent {
64
+ constructor(
65
+ readonly orderId: string,
66
+ readonly instrument: InstrumentSelector,
67
+ readonly timestamp: timestamp
68
+ ) {}
69
+
70
+ handle(state: State, changes: StateChangeTracker) {
71
+ const order = state.order.get(this.instrument.id).get(this.orderId);
72
+ const base = state.balance.get(order.instrument.base.id);
73
+ const quote = state.balance.get(order.instrument.quote.id);
74
+
75
+ const balanceToLock = order.calculateBalanceToLock(base, quote);
76
+
77
+ state.timestamp = this.timestamp;
78
+
79
+ if (balanceToLock.base > 0) {
80
+ base.timestamp = this.timestamp;
81
+ base.lock(this.orderId, balanceToLock.base);
82
+
83
+ changes.commit(base);
84
+ }
85
+
86
+ if (balanceToLock.quote > 0) {
87
+ quote.timestamp = this.timestamp;
88
+ quote.lock(this.orderId, balanceToLock.quote);
89
+
90
+ changes.commit(quote);
91
+ }
92
+ }
93
+ }
94
+
95
+ /**
96
+ *
97
+ */
98
+ export class BalanceUnlockOrderEvent implements StoreEvent {
99
+ constructor(
100
+ readonly orderId: string,
101
+ readonly instrument: InstrumentSelector,
102
+ readonly timestamp: timestamp
103
+ ) {}
104
+
105
+ handle(state: State, changes: StateChangeTracker) {
106
+ const order = state.order.get(this.instrument.id).get(this.orderId);
107
+ const base = state.balance.get(order.instrument.base.id);
108
+ const quote = state.balance.get(order.instrument.quote.id);
109
+
110
+ state.timestamp = this.timestamp;
111
+
112
+ if (base.tryUnlock(this.orderId)) {
113
+ base.timestamp = this.timestamp;
114
+
115
+ changes.commit(base);
116
+ }
117
+
118
+ if (quote.tryUnlock(this.orderId)) {
119
+ quote.timestamp = this.timestamp;
120
+
121
+ changes.commit(quote);
122
+ }
123
+ }
124
+ }
@@ -0,0 +1,25 @@
1
+ import { Store } from '..';
2
+ import { Asset, Commission } from '../domain';
3
+ import { now } from '../shared';
4
+ import { InstrumentPatchEvent } from './store-instrument.event';
5
+
6
+ describe('InstrumentPatchEvent', () => {
7
+ test('should patch a store', () => {
8
+ const timestamp = now();
9
+ const store = new Store();
10
+ const base = new Asset('de30', 'cex', 2);
11
+ const quote = new Asset('usd', 'cex', 2);
12
+
13
+ store.dispatch(
14
+ new InstrumentPatchEvent(timestamp, base, quote, new Commission(0, 0), '')
15
+ );
16
+
17
+ const { universe } = store.snapshot;
18
+
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);
22
+ expect(universe.instrument.asReadonlyArray().length).toEqual(1);
23
+ expect(universe.asset.asReadonlyArray().length).toEqual(2);
24
+ });
25
+ });
@@ -0,0 +1,72 @@
1
+ import { Asset, Commission, InstrumentSelector, Instrument } from '../domain';
2
+ import { timestamp } from '../shared';
3
+ import { State, StateChangeTracker } from '../store';
4
+ import { InnerSet } from './store-state';
5
+ import { StoreEvent } from './store.event';
6
+
7
+ export class InstrumentPatchEvent implements StoreEvent {
8
+ constructor(
9
+ readonly timestamp: timestamp,
10
+ readonly base: Asset,
11
+ readonly quote: Asset,
12
+ readonly commission: Commission,
13
+ readonly raw: string,
14
+ readonly leverage?: number
15
+ ) {}
16
+
17
+ handle(state: State, changes: StateChangeTracker): void {
18
+ const selector = new InstrumentSelector(
19
+ this.base.name,
20
+ this.quote.name,
21
+ this.base.adapterName
22
+ );
23
+
24
+ const instrument = state.universe.instrument.tryGetOrSet(selector.id, () => {
25
+ state.universe.asset.tryGetOrSet(
26
+ this.base.id,
27
+ () => new Asset(this.base.name, this.base.adapterName, 8)
28
+ );
29
+
30
+ state.universe.asset.tryGetOrSet(
31
+ this.quote.id,
32
+ () => new Asset(this.quote.name, this.quote.adapterName, 8)
33
+ );
34
+
35
+ state.order.tryGetOrSet(selector.id, () => new InnerSet(selector.id));
36
+
37
+ return new Instrument(this.base, this.quote, this.raw);
38
+ });
39
+
40
+ instrument.timestamp = this.timestamp;
41
+ instrument.commission = this.commission;
42
+
43
+ if (this.leverage) {
44
+ instrument.leverage = this.leverage;
45
+ }
46
+
47
+ changes.commit(instrument);
48
+ }
49
+ }
50
+
51
+ export class InstrumentSubscriptionEvent implements StoreEvent {
52
+ constructor(
53
+ readonly timestamp: timestamp,
54
+ readonly instrument: InstrumentSelector,
55
+ readonly subscribed: boolean
56
+ ) {}
57
+
58
+ handle(state: State, changes: StateChangeTracker): void {
59
+ const instrument = state.universe.instrument.get(this.instrument.id);
60
+ if (!instrument) {
61
+ throw new Error('invalid instrument');
62
+ }
63
+
64
+ if (this.subscribed) {
65
+ 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));
68
+ }
69
+
70
+ changes.commit(instrument);
71
+ }
72
+ }
@@ -0,0 +1,28 @@
1
+ import { Asset, Instrument, Order } from '../domain';
2
+ import { now } from '../shared';
3
+ import { Store } from '../store';
4
+ import { OrderLoadEvent } from './store-order.event';
5
+
6
+ const instrument = new Instrument(
7
+ new Asset('btc', 'binance', 8),
8
+ new Asset('usdt', 'binance', 2),
9
+ 'binance:btc-usdt'
10
+ );
11
+
12
+ describe('OrderLoadEvent', () => {
13
+ test('should load order to store', () => {
14
+ const timestamp = now();
15
+ const store = new Store();
16
+ const order = Order.market(instrument, 1.0);
17
+
18
+ order.state = 'PENDING';
19
+
20
+ store.snapshot.universe.instrument.upsert(instrument);
21
+ store.snapshot.subscription.instrument.upsert(instrument);
22
+
23
+ store.dispatch(new OrderLoadEvent(order, timestamp));
24
+
25
+ expect(store.snapshot.order.asReadonlyArray().length).toEqual(1);
26
+ expect(store.snapshot.order.get(instrument.id).get(order.id)).toEqual(order);
27
+ });
28
+ });
@@ -0,0 +1,214 @@
1
+ import { InstrumentSelector, Order } from '../domain';
2
+ import { timestamp } from '../shared';
3
+ import { StoreEvent } from './store.event';
4
+ import { InnerSet, State, StateChangeTracker } from './store-state';
5
+
6
+ export class OrderLoadEvent implements StoreEvent {
7
+ constructor(readonly order: Order, readonly timestamp: timestamp) {}
8
+
9
+ handle(state: State, changes: StateChangeTracker): void {
10
+ this.order.timestamp = this.timestamp;
11
+
12
+ const orderByInstrument = state.order.tryGetOrSet(
13
+ this.order.instrument.id,
14
+ () => new InnerSet<Order>(this.order.instrument.id)
15
+ );
16
+
17
+ orderByInstrument.upsert(this.order);
18
+ }
19
+ }
20
+
21
+ export class OrderNewEvent implements StoreEvent {
22
+ constructor(readonly order: Order, readonly timestamp: timestamp) {}
23
+
24
+ handle(state: State, changes: StateChangeTracker): void {
25
+ if (this.order.state != 'NEW') {
26
+ throw new Error(`Order is not new`);
27
+ }
28
+
29
+ this.order.createdAt = this.timestamp;
30
+ this.order.timestamp = this.timestamp;
31
+
32
+ const orderByInstrument = state.order.tryGetOrSet(
33
+ this.order.instrument.id,
34
+ () => new InnerSet<Order>(this.order.instrument.id)
35
+ );
36
+
37
+ orderByInstrument.upsert(this.order);
38
+
39
+ changes.commit(this.order);
40
+ }
41
+ }
42
+
43
+ export class OrderPendingEvent implements StoreEvent {
44
+ constructor(
45
+ readonly id: string,
46
+ readonly instrument: InstrumentSelector,
47
+ readonly timestamp: timestamp
48
+ ) {}
49
+
50
+ handle(state: State, changes: StateChangeTracker): void {
51
+ const order = state.order
52
+ .tryGetOrSet(this.instrument.id, () => {
53
+ throw new Error(`Trying to patch unknown order: ${this.id}`);
54
+ })
55
+ .tryGetOrSet(this.id, () => {
56
+ throw new Error(`Trying to patch unknown order: ${this.id}`);
57
+ });
58
+
59
+ if (order.state != 'NEW') {
60
+ throw new Error(`Order is not NEW: ${order.state}`);
61
+ }
62
+
63
+ order.state = 'PENDING';
64
+ order.timestamp = this.timestamp;
65
+
66
+ changes.commit(order);
67
+ }
68
+ }
69
+
70
+ export class OrderFilledEvent implements StoreEvent {
71
+ constructor(
72
+ readonly id: string,
73
+ readonly instrument: InstrumentSelector,
74
+ readonly averageExecutionRate: number,
75
+ readonly timestamp: timestamp
76
+ ) {}
77
+
78
+ handle(state: State, changes: StateChangeTracker): void {
79
+ const order = state.order
80
+ .tryGetOrSet(this.instrument.id, () => {
81
+ throw new Error(`Trying to patch unknown order: ${this.id}`);
82
+ })
83
+ .tryGetOrSet(this.id, () => {
84
+ throw new Error(`Trying to patch unknown order: ${this.id}`);
85
+ });
86
+
87
+ if (order.state != 'PENDING' && order.state != 'CANCELING') {
88
+ throw new Error(`Order is not PENDING or CANCELING: ${order.state}`);
89
+ }
90
+
91
+ order.state = 'FILLED';
92
+ order.timestamp = this.timestamp;
93
+ order.quantityExecuted = order.quantity;
94
+ order.averageExecutionRate = this.averageExecutionRate;
95
+
96
+ changes.commit(order);
97
+ }
98
+ }
99
+
100
+ export class OrderCancelingEvent implements StoreEvent {
101
+ constructor(
102
+ readonly id: string,
103
+ readonly instrument: InstrumentSelector,
104
+ readonly timestamp: timestamp
105
+ ) {}
106
+
107
+ handle(state: State, changes: StateChangeTracker): void {
108
+ const order = state.order
109
+ .tryGetOrSet(this.instrument.id, () => {
110
+ throw new Error(`Trying to patch unknown order: ${this.id}`);
111
+ })
112
+ .tryGetOrSet(this.id, () => {
113
+ throw new Error(`Trying to patch unknown order: ${this.id}`);
114
+ });
115
+
116
+ if (order.state == 'CANCELING' || order.state == 'CANCELED') {
117
+ return;
118
+ }
119
+
120
+ if (order.state != 'PENDING') {
121
+ throw new Error(`Order is not PENDING: ${order.state}`);
122
+ }
123
+
124
+ order.state = 'CANCELING';
125
+ order.timestamp = this.timestamp;
126
+
127
+ changes.commit(order);
128
+ }
129
+ }
130
+
131
+ export class OrderCanceledEvent implements StoreEvent {
132
+ constructor(
133
+ readonly id: string,
134
+ readonly instrument: InstrumentSelector,
135
+ readonly timestamp: timestamp
136
+ ) {}
137
+
138
+ handle(state: State, changes: StateChangeTracker): void {
139
+ const order = state.order
140
+ .tryGetOrSet(this.instrument.id, () => {
141
+ throw new Error(`Trying to patch unknown order: ${this.id}`);
142
+ })
143
+ .tryGetOrSet(this.id, () => {
144
+ throw new Error(`Trying to patch unknown order: ${this.id}`);
145
+ });
146
+
147
+ if (order.state == 'CANCELED') {
148
+ return;
149
+ }
150
+
151
+ if (order.state != 'CANCELING') {
152
+ throw new Error(`Order is not CANCELING: ${order.state}`);
153
+ }
154
+
155
+ order.state = 'CANCELED';
156
+ order.timestamp = this.timestamp;
157
+
158
+ changes.commit(order);
159
+ }
160
+ }
161
+
162
+ export class OrderCancelFailedEvent implements StoreEvent {
163
+ constructor(
164
+ readonly id: string,
165
+ readonly instrument: InstrumentSelector,
166
+ readonly timestamp: timestamp
167
+ ) {}
168
+
169
+ handle(state: State, changes: StateChangeTracker): void {
170
+ const order = state.order
171
+ .tryGetOrSet(this.instrument.id, () => {
172
+ throw new Error(`Trying to patch unknown order: ${this.id}`);
173
+ })
174
+ .tryGetOrSet(this.id, () => {
175
+ throw new Error(`Trying to patch unknown order: ${this.id}`);
176
+ });
177
+
178
+ if (order.state != 'CANCELING') {
179
+ return;
180
+ }
181
+
182
+ order.state = 'PENDING';
183
+ order.timestamp = this.timestamp;
184
+
185
+ changes.commit(order);
186
+ }
187
+ }
188
+
189
+ export class OrderRejectedEvent implements StoreEvent {
190
+ constructor(
191
+ readonly id: string,
192
+ readonly instrument: InstrumentSelector,
193
+ readonly timestamp: timestamp
194
+ ) {}
195
+
196
+ handle(state: State, changes: StateChangeTracker): void {
197
+ const order = state.order
198
+ .tryGetOrSet(this.instrument.id, () => {
199
+ throw new Error(`Trying to patch unknown order: ${this.id}`);
200
+ })
201
+ .tryGetOrSet(this.id, () => {
202
+ throw new Error(`Trying to patch unknown order: ${this.id}`);
203
+ });
204
+
205
+ if (order.state != 'NEW') {
206
+ throw new Error(`Order is not NEW: ${order.state}`);
207
+ }
208
+
209
+ order.state = 'REJECTED';
210
+ order.timestamp = this.timestamp;
211
+
212
+ changes.commit(order);
213
+ }
214
+ }
@@ -0,0 +1,54 @@
1
+ import { InstrumentSelector, Orderbook } from '../domain';
2
+ import { timestamp } from '../shared';
3
+ import { StoreEvent } from './store.event';
4
+ import { State, StateChangeTracker } from './store-state';
5
+
6
+ export class OrderbookPatchEvent implements StoreEvent {
7
+ constructor(
8
+ readonly instrument: InstrumentSelector,
9
+ readonly bestAskRate: number,
10
+ readonly bestAskQuantity: number,
11
+ readonly bestBidRate: number,
12
+ readonly bestBidQuantity: number,
13
+ readonly timestamp: timestamp
14
+ ) {}
15
+
16
+ handle(state: State, changes: StateChangeTracker): void {
17
+ if (!state.subscription.instrument.get(this.instrument.id)) {
18
+ throw new Error(`Trying to patch unsubscribed instrument: ${this.instrument.id}`);
19
+ }
20
+
21
+ const orderbook = state.orderbook.tryGetOrSet(
22
+ this.instrument.id,
23
+ () => new Orderbook(state.universe.instrument.get(this.instrument.id))
24
+ );
25
+
26
+ state.timestamp = this.timestamp;
27
+
28
+ orderbook.timestamp = this.timestamp;
29
+ orderbook.bestAskRate = orderbook.instrument.quote.fixed(this.bestAskRate);
30
+ orderbook.bestAskQuantity = orderbook.instrument.base.fixed(this.bestAskQuantity);
31
+ orderbook.bestBidRate = orderbook.instrument.quote.fixed(this.bestBidRate);
32
+ orderbook.bestBidQuantity = orderbook.instrument.base.fixed(this.bestBidQuantity);
33
+
34
+ const quote = state.balance.get(orderbook.instrument.quote.id);
35
+
36
+ if (quote) {
37
+ for (const position of Object.values(quote.position)) {
38
+ if (position.instrument.id != orderbook.instrument.id) {
39
+ continue;
40
+ }
41
+
42
+ const rate = position.size >= 0 ? orderbook.bestBidRate : orderbook.bestAskRate;
43
+
44
+ position.calculateEstimatedUnrealizedPnL(rate);
45
+ }
46
+
47
+ if (quote.total < 0) {
48
+ throw new Error('liquidated');
49
+ }
50
+ }
51
+
52
+ changes.commit(orderbook);
53
+ }
54
+ }