@quantform/core 0.5.23 → 0.6.5

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 (557) hide show
  1. package/LICENSE.md +21 -0
  2. package/dist/adapter/adapter-aggregate.d.ts +38 -3
  3. package/dist/adapter/adapter-aggregate.d.ts.map +1 -0
  4. package/dist/adapter/adapter-aggregate.js +109 -50
  5. package/dist/adapter/adapter.d.ts +27 -2
  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 +3 -2
  9. package/dist/adapter/backtester/backtester-adapter.d.ts.map +1 -0
  10. package/dist/adapter/backtester/backtester-adapter.js +26 -13
  11. package/dist/adapter/backtester/backtester-cursor.d.ts +2 -1
  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 -1
  15. package/dist/adapter/backtester/backtester-streamer.d.ts.map +1 -0
  16. package/dist/adapter/backtester/backtester-streamer.js +54 -30
  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 +18 -13
  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 +6 -5
  36. package/dist/adapter/paper/paper-adapter.d.ts.map +1 -0
  37. package/dist/adapter/paper/paper-adapter.js +44 -21
  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 +68 -38
  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 +17 -1
  63. package/dist/domain/asset.d.ts.map +1 -0
  64. package/dist/domain/asset.js +16 -4
  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 +27 -5
  69. package/dist/domain/balance.d.ts.map +1 -0
  70. package/dist/domain/balance.js +31 -7
  71. package/dist/domain/commission.d.ts +2 -0
  72. package/dist/domain/commission.d.ts.map +1 -0
  73. package/dist/domain/commission.js +2 -1
  74. package/dist/domain/component.d.ts +1 -1
  75. package/dist/domain/component.d.ts.map +1 -0
  76. package/dist/domain/component.js +0 -1
  77. package/dist/domain/error.d.ts +4 -3
  78. package/dist/domain/error.d.ts.map +1 -0
  79. package/dist/domain/error.js +3 -4
  80. package/dist/domain/index.d.ts +10 -8
  81. package/dist/domain/index.d.ts.map +1 -0
  82. package/dist/domain/index.js +9 -9
  83. package/dist/domain/{instrument.operator.d.ts → instrument-operator.d.ts} +1 -0
  84. package/dist/domain/instrument-operator.d.ts.map +1 -0
  85. package/dist/domain/{instrument.operator.js → instrument-operator.js} +0 -1
  86. package/dist/domain/instrument.d.ts +8 -7
  87. package/dist/domain/instrument.d.ts.map +1 -0
  88. package/dist/domain/instrument.js +7 -7
  89. package/dist/domain/ohlc-operator.d.ts +11 -0
  90. package/dist/domain/ohlc-operator.d.ts.map +1 -0
  91. package/dist/domain/{candle.operator.js → ohlc-operator.js} +21 -15
  92. package/dist/domain/{candle.d.ts → ohlc.d.ts} +4 -3
  93. package/dist/domain/ohlc.d.ts.map +1 -0
  94. package/dist/domain/{candle.js → ohlc.js} +3 -4
  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 +14 -21
  99. package/dist/domain/order.d.ts.map +1 -0
  100. package/dist/domain/order.js +16 -32
  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 +9 -7
  105. package/dist/domain/orderbook.d.ts.map +1 -0
  106. package/dist/domain/orderbook.js +7 -6
  107. package/dist/domain/{position.operator.d.ts → position-operator.d.ts} +4 -2
  108. package/dist/domain/position-operator.d.ts.map +1 -0
  109. package/dist/domain/{position.operator.js → position-operator.js} +10 -3
  110. package/dist/domain/position.d.ts +4 -5
  111. package/dist/domain/position.d.ts.map +1 -0
  112. package/dist/domain/position.js +2 -6
  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 +106 -0
  116. package/dist/domain/session.d.ts +56 -15
  117. package/dist/domain/session.d.ts.map +1 -0
  118. package/dist/domain/session.js +103 -39
  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 +9 -6
  126. package/dist/domain/trade.d.ts.map +1 -0
  127. package/dist/domain/trade.js +8 -6
  128. package/dist/index.d.ts +25 -2
  129. package/dist/index.d.ts.map +1 -0
  130. package/dist/index.js +63 -3
  131. package/dist/shared/collections.d.ts +9 -6
  132. package/dist/shared/collections.d.ts.map +1 -0
  133. package/dist/shared/collections.js +21 -13
  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 +13 -0
  138. package/dist/shared/decimals.d.ts.map +1 -0
  139. package/dist/shared/decimals.js +12 -1
  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 +2 -1
  144. package/dist/shared/index.d.ts.map +1 -0
  145. package/dist/shared/index.js +1 -2
  146. package/dist/shared/logger.d.ts +6 -7
  147. package/dist/shared/logger.d.ts.map +1 -0
  148. package/dist/shared/logger.js +27 -8
  149. package/dist/shared/pipe.d.ts +1 -0
  150. package/dist/shared/pipe.d.ts.map +1 -0
  151. package/dist/shared/pipe.js +0 -1
  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 +25 -0
  159. package/dist/storage/feed.d.ts.map +1 -0
  160. package/dist/storage/feed.js +56 -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} +14 -1
  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} +7 -2
  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 → store-orderbook-event.d.ts} +2 -1
  189. package/dist/store/store-orderbook-event.d.ts.map +1 -0
  190. package/dist/store/{store-orderbook.event.js → store-orderbook-event.js} +6 -5
  191. package/dist/store/{store-position.event.d.ts → store-position-event.d.ts} +3 -2
  192. package/dist/store/store-position-event.d.ts.map +1 -0
  193. package/dist/store/{store-position.event.js → store-position-event.js} +13 -6
  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 → store-trade-event.d.ts} +6 -1
  198. package/dist/store/store-trade-event.d.ts.map +1 -0
  199. package/dist/store/{store-trade.event.js → store-trade-event.js} +12 -3
  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/jest.config.ts +13 -0
  204. package/package.json +19 -32
  205. package/src/adapter/adapter-aggregate.ts +42 -21
  206. package/src/adapter/adapter.ts +3 -3
  207. package/src/adapter/backtester/backtester-adapter.ts +2 -4
  208. package/src/adapter/backtester/backtester-cursor.ts +1 -1
  209. package/src/adapter/backtester/backtester-streamer.spec.ts +5 -3
  210. package/src/adapter/backtester/backtester-streamer.ts +16 -8
  211. package/src/adapter/backtester/error.ts +7 -0
  212. package/src/adapter/error.ts +4 -0
  213. package/src/adapter/paper/engine/paper-engine.spec.ts +38 -21
  214. package/src/adapter/paper/engine/paper-engine.ts +44 -35
  215. package/src/adapter/paper/paper-adapter.ts +15 -6
  216. package/src/cli/build.ts +1 -1
  217. package/src/cli/dev.ts +15 -7
  218. package/src/cli/error.ts +5 -0
  219. package/src/cli/internal/workspace.ts +0 -11
  220. package/src/cli/pull.ts +22 -31
  221. package/src/cli/run.ts +14 -11
  222. package/src/cli/test.ts +24 -37
  223. package/src/domain/asset.ts +1 -8
  224. package/src/domain/{balance.operator.spec.ts → balance-operator.spec.ts} +4 -3
  225. package/src/domain/{balance.operator.ts → balance-operator.ts} +0 -0
  226. package/src/domain/balance.spec.ts +15 -12
  227. package/src/domain/balance.ts +7 -11
  228. package/src/domain/commission.ts +3 -1
  229. package/src/domain/component.ts +0 -1
  230. package/src/domain/error.ts +3 -3
  231. package/src/domain/index.ts +9 -8
  232. package/src/domain/{instrument.operator.spec.ts → instrument-operator.spec.ts} +9 -2
  233. package/src/domain/{instrument.operator.ts → instrument-operator.ts} +0 -0
  234. package/src/domain/instrument.spec.ts +8 -1
  235. package/src/domain/instrument.ts +10 -12
  236. package/src/domain/ohlc-operator.spec.ts +126 -0
  237. package/src/domain/{candle.operator.ts → ohlc-operator.ts} +33 -17
  238. package/src/domain/{candle.spec.ts → ohlc.spec.ts} +6 -6
  239. package/src/domain/{candle.ts → ohlc.ts} +2 -2
  240. package/src/domain/{order.operator.spec.ts → order-operator.spec.ts} +9 -6
  241. package/src/domain/{order.operator.ts → order-operator.ts} +2 -2
  242. package/src/domain/order.spec.ts +8 -9
  243. package/src/domain/order.ts +21 -56
  244. package/src/domain/{orderbook.operator.spec.ts → orderbook-operator.spec.ts} +15 -3
  245. package/src/domain/{orderbook.operator.ts → orderbook-operator.ts} +0 -0
  246. package/src/domain/orderbook.spec.ts +11 -2
  247. package/src/domain/orderbook.ts +9 -13
  248. package/src/domain/{position.operator.spec.ts → position-operator.spec.ts} +11 -6
  249. package/src/domain/{position.operator.ts → position-operator.ts} +13 -6
  250. package/src/domain/position.spec.ts +7 -4
  251. package/src/domain/position.ts +2 -7
  252. package/src/domain/session-builder.ts +158 -0
  253. package/src/domain/session.spec.ts +2 -9
  254. package/src/domain/session.ts +86 -71
  255. package/src/domain/{trade.operator.spec.ts → trade-operator.spec.ts} +7 -3
  256. package/src/domain/{trade.operator.ts → trade-operator.ts} +0 -0
  257. package/src/domain/trade.spec.ts +6 -2
  258. package/src/domain/trade.ts +8 -11
  259. package/src/index.ts +75 -2
  260. package/src/shared/collections.spec.ts +10 -6
  261. package/src/shared/collections.ts +29 -16
  262. package/src/shared/environment.ts +13 -0
  263. package/src/shared/index.ts +1 -1
  264. package/src/shared/logger.ts +37 -7
  265. package/src/shared/pipe.ts +1 -1
  266. package/src/storage/cache.ts +3 -1
  267. package/src/storage/feed.ts +2 -0
  268. package/src/storage/storage.ts +10 -8
  269. package/src/store/error.ts +36 -0
  270. package/src/store/index.ts +7 -7
  271. package/src/store/{store-balance.event.spec.ts → store-balance-event.spec.ts} +3 -3
  272. package/src/store/{store-balance.event.ts → store-balance-event.ts} +54 -11
  273. package/src/store/{store.event.ts → store-event.ts} +0 -0
  274. package/src/store/{store-instrument.event.spec.ts → store-instrument-event.spec.ts} +6 -5
  275. package/src/store/{store-instrument.event.ts → store-instrument-event.ts} +17 -6
  276. package/src/store/store-order-event.spec.ts +32 -0
  277. package/src/store/{store-order.event.ts → store-order-event.ts} +25 -20
  278. package/src/store/{store-orderbook.event.spec.ts → store-orderbook-event.spec.ts} +11 -9
  279. package/src/store/{store-orderbook.event.ts → store-orderbook-event.ts} +7 -5
  280. package/src/store/{store-position.event.ts → store-position-event.ts} +14 -7
  281. package/src/store/store-state.ts +3 -3
  282. package/src/store/{store-trade.event.spec.ts → store-trade-event.spec.ts} +7 -5
  283. package/src/store/{store-trade.event.ts → store-trade-event.ts} +10 -4
  284. package/src/store/store.spec.ts +13 -11
  285. package/src/store/store.ts +1 -1
  286. package/tsconfig.json +12 -5
  287. package/dist/adapter/adapter-aggregate.js.map +0 -1
  288. package/dist/adapter/adapter.js.map +0 -1
  289. package/dist/adapter/backtester/backtester-adapter.js.map +0 -1
  290. package/dist/adapter/backtester/backtester-adapter.spec.d.ts +0 -1
  291. package/dist/adapter/backtester/backtester-adapter.spec.js +0 -83
  292. package/dist/adapter/backtester/backtester-adapter.spec.js.map +0 -1
  293. package/dist/adapter/backtester/backtester-cursor.js.map +0 -1
  294. package/dist/adapter/backtester/backtester-cursor.spec.d.ts +0 -1
  295. package/dist/adapter/backtester/backtester-cursor.spec.js +0 -39
  296. package/dist/adapter/backtester/backtester-cursor.spec.js.map +0 -1
  297. package/dist/adapter/backtester/backtester-streamer.js.map +0 -1
  298. package/dist/adapter/backtester/backtester-streamer.spec.d.ts +0 -1
  299. package/dist/adapter/backtester/backtester-streamer.spec.js +0 -45
  300. package/dist/adapter/backtester/backtester-streamer.spec.js.map +0 -1
  301. package/dist/adapter/backtester/index.js.map +0 -1
  302. package/dist/adapter/error.js.map +0 -1
  303. package/dist/adapter/index.js.map +0 -1
  304. package/dist/adapter/paper/engine/paper-engine.js.map +0 -1
  305. package/dist/adapter/paper/engine/paper-engine.spec.d.ts +0 -1
  306. package/dist/adapter/paper/engine/paper-engine.spec.js +0 -54
  307. package/dist/adapter/paper/engine/paper-engine.spec.js.map +0 -1
  308. package/dist/adapter/paper/index.js.map +0 -1
  309. package/dist/adapter/paper/paper-adapter.js.map +0 -1
  310. package/dist/adapter/paper/paper-adapter.spec.d.ts +0 -1
  311. package/dist/adapter/paper/paper-adapter.spec.js +0 -70
  312. package/dist/adapter/paper/paper-adapter.spec.js.map +0 -1
  313. package/dist/bootstrap.d.ts +0 -11
  314. package/dist/bootstrap.js +0 -73
  315. package/dist/bootstrap.js.map +0 -1
  316. package/dist/cli/build.js.map +0 -1
  317. package/dist/cli/dev.js.map +0 -1
  318. package/dist/cli/index.js.map +0 -1
  319. package/dist/cli/internal/workspace.js.map +0 -1
  320. package/dist/cli/pull.js.map +0 -1
  321. package/dist/cli/run.js.map +0 -1
  322. package/dist/cli/test.js.map +0 -1
  323. package/dist/domain/asset.js.map +0 -1
  324. package/dist/domain/asset.spec.d.ts +0 -1
  325. package/dist/domain/asset.spec.js +0 -55
  326. package/dist/domain/asset.spec.js.map +0 -1
  327. package/dist/domain/balance.js.map +0 -1
  328. package/dist/domain/balance.operator.js.map +0 -1
  329. package/dist/domain/balance.operator.spec.d.ts +0 -1
  330. package/dist/domain/balance.operator.spec.js +0 -23
  331. package/dist/domain/balance.operator.spec.js.map +0 -1
  332. package/dist/domain/balance.spec.d.ts +0 -1
  333. package/dist/domain/balance.spec.js +0 -83
  334. package/dist/domain/balance.spec.js.map +0 -1
  335. package/dist/domain/candle.js.map +0 -1
  336. package/dist/domain/candle.operator.d.ts +0 -10
  337. package/dist/domain/candle.operator.js.map +0 -1
  338. package/dist/domain/candle.operator.spec.d.ts +0 -1
  339. package/dist/domain/candle.operator.spec.js +0 -112
  340. package/dist/domain/candle.operator.spec.js.map +0 -1
  341. package/dist/domain/candle.spec.d.ts +0 -1
  342. package/dist/domain/candle.spec.js +0 -26
  343. package/dist/domain/candle.spec.js.map +0 -1
  344. package/dist/domain/commission.js.map +0 -1
  345. package/dist/domain/commission.spec.d.ts +0 -1
  346. package/dist/domain/commission.spec.js +0 -31
  347. package/dist/domain/commission.spec.js.map +0 -1
  348. package/dist/domain/component.js.map +0 -1
  349. package/dist/domain/error.js.map +0 -1
  350. package/dist/domain/index.js.map +0 -1
  351. package/dist/domain/instrument.js.map +0 -1
  352. package/dist/domain/instrument.operator.js.map +0 -1
  353. package/dist/domain/instrument.operator.spec.d.ts +0 -1
  354. package/dist/domain/instrument.operator.spec.js +0 -24
  355. package/dist/domain/instrument.operator.spec.js.map +0 -1
  356. package/dist/domain/instrument.spec.d.ts +0 -1
  357. package/dist/domain/instrument.spec.js +0 -49
  358. package/dist/domain/instrument.spec.js.map +0 -1
  359. package/dist/domain/order.js.map +0 -1
  360. package/dist/domain/order.operator.js +0 -14
  361. package/dist/domain/order.operator.js.map +0 -1
  362. package/dist/domain/order.operator.spec.d.ts +0 -1
  363. package/dist/domain/order.operator.spec.js +0 -65
  364. package/dist/domain/order.operator.spec.js.map +0 -1
  365. package/dist/domain/order.spec.d.ts +0 -1
  366. package/dist/domain/order.spec.js +0 -34
  367. package/dist/domain/order.spec.js.map +0 -1
  368. package/dist/domain/orderbook.js.map +0 -1
  369. package/dist/domain/orderbook.operator.js.map +0 -1
  370. package/dist/domain/orderbook.operator.spec.d.ts +0 -1
  371. package/dist/domain/orderbook.operator.spec.js +0 -22
  372. package/dist/domain/orderbook.operator.spec.js.map +0 -1
  373. package/dist/domain/orderbook.spec.d.ts +0 -1
  374. package/dist/domain/orderbook.spec.js +0 -13
  375. package/dist/domain/orderbook.spec.js.map +0 -1
  376. package/dist/domain/position.js.map +0 -1
  377. package/dist/domain/position.operator.js.map +0 -1
  378. package/dist/domain/position.operator.spec.d.ts +0 -1
  379. package/dist/domain/position.operator.spec.js +0 -49
  380. package/dist/domain/position.operator.spec.js.map +0 -1
  381. package/dist/domain/position.spec.d.ts +0 -1
  382. package/dist/domain/position.spec.js +0 -31
  383. package/dist/domain/position.spec.js.map +0 -1
  384. package/dist/domain/session.js.map +0 -1
  385. package/dist/domain/session.spec.d.ts +0 -1
  386. package/dist/domain/session.spec.js +0 -23
  387. package/dist/domain/session.spec.js.map +0 -1
  388. package/dist/domain/timeframe.js.map +0 -1
  389. package/dist/domain/trade.js.map +0 -1
  390. package/dist/domain/trade.operator.js.map +0 -1
  391. package/dist/domain/trade.operator.spec.d.ts +0 -1
  392. package/dist/domain/trade.operator.spec.js +0 -24
  393. package/dist/domain/trade.operator.spec.js.map +0 -1
  394. package/dist/domain/trade.spec.d.ts +0 -1
  395. package/dist/domain/trade.spec.js +0 -13
  396. package/dist/domain/trade.spec.js.map +0 -1
  397. package/dist/index.js.map +0 -1
  398. package/dist/indicator/atr.d.ts +0 -4
  399. package/dist/indicator/atr.js +0 -16
  400. package/dist/indicator/atr.js.map +0 -1
  401. package/dist/indicator/cross.d.ts +0 -4
  402. package/dist/indicator/cross.js +0 -41
  403. package/dist/indicator/cross.js.map +0 -1
  404. package/dist/indicator/cross.spec.d.ts +0 -1
  405. package/dist/indicator/cross.spec.js +0 -102
  406. package/dist/indicator/cross.spec.js.map +0 -1
  407. package/dist/indicator/donchian.d.ts +0 -10
  408. package/dist/indicator/donchian.js +0 -16
  409. package/dist/indicator/donchian.js.map +0 -1
  410. package/dist/indicator/drawdown.d.ts +0 -3
  411. package/dist/indicator/drawdown.js +0 -28
  412. package/dist/indicator/drawdown.js.map +0 -1
  413. package/dist/indicator/ema.d.ts +0 -3
  414. package/dist/indicator/ema.js +0 -24
  415. package/dist/indicator/ema.js.map +0 -1
  416. package/dist/indicator/ema.spec.d.ts +0 -1
  417. package/dist/indicator/ema.spec.js +0 -24
  418. package/dist/indicator/ema.spec.js.map +0 -1
  419. package/dist/indicator/envelope.d.ts +0 -6
  420. package/dist/indicator/envelope.js +0 -18
  421. package/dist/indicator/envelope.js.map +0 -1
  422. package/dist/indicator/index.d.ts +0 -17
  423. package/dist/indicator/index.js +0 -34
  424. package/dist/indicator/index.js.map +0 -1
  425. package/dist/indicator/macd.d.ts +0 -3
  426. package/dist/indicator/macd.js +0 -13
  427. package/dist/indicator/macd.js.map +0 -1
  428. package/dist/indicator/min-max.d.ts +0 -6
  429. package/dist/indicator/min-max.js +0 -22
  430. package/dist/indicator/min-max.js.map +0 -1
  431. package/dist/indicator/ring-buffer.d.ts +0 -16
  432. package/dist/indicator/ring-buffer.js +0 -56
  433. package/dist/indicator/ring-buffer.js.map +0 -1
  434. package/dist/indicator/rma.d.ts +0 -3
  435. package/dist/indicator/rma.js +0 -24
  436. package/dist/indicator/rma.js.map +0 -1
  437. package/dist/indicator/sma.d.ts +0 -3
  438. package/dist/indicator/sma.js +0 -17
  439. package/dist/indicator/sma.js.map +0 -1
  440. package/dist/indicator/sma.spec.d.ts +0 -1
  441. package/dist/indicator/sma.spec.js +0 -20
  442. package/dist/indicator/sma.spec.js.map +0 -1
  443. package/dist/indicator/swma.d.ts +0 -3
  444. package/dist/indicator/swma.js +0 -24
  445. package/dist/indicator/swma.js.map +0 -1
  446. package/dist/indicator/tma.d.ts +0 -3
  447. package/dist/indicator/tma.js +0 -16
  448. package/dist/indicator/tma.js.map +0 -1
  449. package/dist/indicator/tma.spec.d.ts +0 -1
  450. package/dist/indicator/tma.spec.js +0 -20
  451. package/dist/indicator/tma.spec.js.map +0 -1
  452. package/dist/indicator/trailing.d.ts +0 -14
  453. package/dist/indicator/trailing.js +0 -68
  454. package/dist/indicator/trailing.js.map +0 -1
  455. package/dist/indicator/trailing.spec.d.ts +0 -1
  456. package/dist/indicator/trailing.spec.js +0 -70
  457. package/dist/indicator/trailing.spec.js.map +0 -1
  458. package/dist/indicator/true-range.d.ts +0 -4
  459. package/dist/indicator/true-range.js +0 -20
  460. package/dist/indicator/true-range.js.map +0 -1
  461. package/dist/indicator/true-range.spec.d.ts +0 -1
  462. package/dist/indicator/true-range.spec.js +0 -28
  463. package/dist/indicator/true-range.spec.js.map +0 -1
  464. package/dist/indicator/window.d.ts +0 -3
  465. package/dist/indicator/window.js +0 -22
  466. package/dist/indicator/window.js.map +0 -1
  467. package/dist/indicator/wma.d.ts +0 -3
  468. package/dist/indicator/wma.js +0 -23
  469. package/dist/indicator/wma.js.map +0 -1
  470. package/dist/indicator/wma.spec.d.ts +0 -1
  471. package/dist/indicator/wma.spec.js +0 -20
  472. package/dist/indicator/wma.spec.js.map +0 -1
  473. package/dist/shared/collections.js.map +0 -1
  474. package/dist/shared/collections.spec.d.ts +0 -1
  475. package/dist/shared/collections.spec.js +0 -28
  476. package/dist/shared/collections.spec.js.map +0 -1
  477. package/dist/shared/datetime.js.map +0 -1
  478. package/dist/shared/decimals.js.map +0 -1
  479. package/dist/shared/decimals.spec.d.ts +0 -1
  480. package/dist/shared/decimals.spec.js +0 -29
  481. package/dist/shared/decimals.spec.js.map +0 -1
  482. package/dist/shared/index.js.map +0 -1
  483. package/dist/shared/io.d.ts +0 -1
  484. package/dist/shared/io.js +0 -8
  485. package/dist/shared/io.js.map +0 -1
  486. package/dist/shared/logger.js.map +0 -1
  487. package/dist/shared/pipe.js.map +0 -1
  488. package/dist/shared/policy.js.map +0 -1
  489. package/dist/storage/cache.js.map +0 -1
  490. package/dist/storage/cache.spec.d.ts +0 -1
  491. package/dist/storage/cache.spec.js +0 -18
  492. package/dist/storage/cache.spec.js.map +0 -1
  493. package/dist/storage/feed.js.map +0 -1
  494. package/dist/storage/index.js.map +0 -1
  495. package/dist/storage/measurement.js.map +0 -1
  496. package/dist/storage/storage.js.map +0 -1
  497. package/dist/store/index.js.map +0 -1
  498. package/dist/store/store-balance.event.js.map +0 -1
  499. package/dist/store/store-balance.event.spec.d.ts +0 -1
  500. package/dist/store/store-balance.event.spec.js +0 -26
  501. package/dist/store/store-balance.event.spec.js.map +0 -1
  502. package/dist/store/store-instrument.event.js.map +0 -1
  503. package/dist/store/store-instrument.event.spec.d.ts +0 -1
  504. package/dist/store/store-instrument.event.spec.js +0 -22
  505. package/dist/store/store-instrument.event.spec.js.map +0 -1
  506. package/dist/store/store-order.event.js.map +0 -1
  507. package/dist/store/store-order.event.spec.d.ts +0 -1
  508. package/dist/store/store-order.event.spec.js +0 -21
  509. package/dist/store/store-order.event.spec.js.map +0 -1
  510. package/dist/store/store-orderbook.event.js.map +0 -1
  511. package/dist/store/store-orderbook.event.spec.d.ts +0 -1
  512. package/dist/store/store-orderbook.event.spec.js +0 -28
  513. package/dist/store/store-orderbook.event.spec.js.map +0 -1
  514. package/dist/store/store-position.event.js.map +0 -1
  515. package/dist/store/store-state.js.map +0 -1
  516. package/dist/store/store-trade.event.js.map +0 -1
  517. package/dist/store/store-trade.event.spec.d.ts +0 -1
  518. package/dist/store/store-trade.event.spec.js +0 -44
  519. package/dist/store/store-trade.event.spec.js.map +0 -1
  520. package/dist/store/store.event.js.map +0 -1
  521. package/dist/store/store.js.map +0 -1
  522. package/dist/store/store.spec.d.ts +0 -1
  523. package/dist/store/store.spec.js +0 -119
  524. package/dist/store/store.spec.js.map +0 -1
  525. package/dist/tsconfig.tsbuildinfo +0 -1
  526. package/jestconfig.json +0 -13
  527. package/src/adapter/backtester/backtester-adapter.spec.ts +0 -133
  528. package/src/adapter/paper/paper-adapter.spec.ts +0 -114
  529. package/src/bootstrap.ts +0 -139
  530. package/src/domain/candle.operator.spec.ts +0 -126
  531. package/src/indicator/atr.ts +0 -21
  532. package/src/indicator/cross.spec.ts +0 -136
  533. package/src/indicator/cross.ts +0 -59
  534. package/src/indicator/donchian.ts +0 -38
  535. package/src/indicator/drawdown.ts +0 -29
  536. package/src/indicator/ema.spec.ts +0 -39
  537. package/src/indicator/ema.ts +0 -27
  538. package/src/indicator/envelope.ts +0 -25
  539. package/src/indicator/index.ts +0 -17
  540. package/src/indicator/macd.ts +0 -22
  541. package/src/indicator/min-max.ts +0 -28
  542. package/src/indicator/ring-buffer.ts +0 -63
  543. package/src/indicator/rma.ts +0 -26
  544. package/src/indicator/sma.spec.ts +0 -21
  545. package/src/indicator/sma.ts +0 -25
  546. package/src/indicator/swma.ts +0 -28
  547. package/src/indicator/tma.spec.ts +0 -21
  548. package/src/indicator/tma.ts +0 -20
  549. package/src/indicator/trailing.spec.ts +0 -88
  550. package/src/indicator/trailing.ts +0 -81
  551. package/src/indicator/true-range.spec.ts +0 -32
  552. package/src/indicator/true-range.ts +0 -32
  553. package/src/indicator/window.ts +0 -28
  554. package/src/indicator/wma.spec.ts +0 -20
  555. package/src/indicator/wma.ts +0 -29
  556. package/src/shared/io.ts +0 -3
  557. package/src/store/store-order.event.spec.ts +0 -28
@@ -4,20 +4,25 @@ import { d } from '../shared';
4
4
  import { State } from '../store';
5
5
  import { Asset } from './asset';
6
6
  import { Balance } from './balance';
7
+ import { Commission } from './commission';
7
8
  import { Component } from './component';
8
9
  import { Instrument } from './instrument';
9
10
  import { Position } from './position';
10
- import { position, positions } from './position.operator';
11
+ import { position, positions } from './position-operator';
11
12
 
12
13
  const instrument = new Instrument(
14
+ 0,
13
15
  new Asset('abc', 'xyz', 4),
14
16
  new Asset('def', 'xyz', 4),
15
- 'abc-def'
17
+ 'abc-def',
18
+ Commission.Zero
16
19
  );
17
20
 
18
21
  describe('position', () => {
19
22
  test('should pipe a position', done => {
20
- new BehaviorSubject<Component>(new Position('1', instrument, 'CROSS', d(10), d(2), 3))
23
+ new BehaviorSubject<Component>(
24
+ new Position(0, '1', instrument, 'CROSS', d(10), d(2), 3)
25
+ )
21
26
  .pipe(position(instrument))
22
27
  .subscribe({
23
28
  next: it => {
@@ -37,9 +42,9 @@ describe('position', () => {
37
42
 
38
43
  describe('positions', () => {
39
44
  const state = new State();
40
- const balance = new Balance(instrument.quote);
41
- const position1 = new Position('1', instrument, 'CROSS', d(10), d(2), 3);
42
- const position2 = new Position('2', instrument, 'CROSS', d(20), d(2), 3);
45
+ const balance = new Balance(0, instrument.quote);
46
+ const position1 = new Position(0, '1', instrument, 'CROSS', d(10), d(2), 3);
47
+ const position2 = new Position(0, '2', instrument, 'CROSS', d(20), d(2), 3);
43
48
 
44
49
  beforeEach(() => {
45
50
  state.balance.upsert(balance);
@@ -2,24 +2,31 @@ import { filter, map, Observable, share, startWith } from 'rxjs';
2
2
 
3
3
  import { d, decimal, weightedMean } from '../shared';
4
4
  import { State } from '../store';
5
+ import { Component } from './component';
6
+ import { invalidInstrumentSelectorError } from './error';
5
7
  import { InstrumentSelector } from './instrument';
6
8
  import { Position } from './position';
7
9
 
8
10
  export function position(selector: InstrumentSelector) {
9
- return (source: Observable<Position>) =>
11
+ return (source: Observable<Component>) =>
10
12
  source.pipe(
11
- filter(it => it.kind == 'position' && it.instrument.id == selector.id),
13
+ filter(it => it instanceof Position && it.instrument.id == selector.id),
12
14
  map(it => it as Readonly<Position>)
13
15
  );
14
16
  }
15
17
 
16
18
  export function positions(selector: InstrumentSelector, state: State) {
19
+ const balance = state.balance.get(selector.quote.id);
20
+ if (!balance) {
21
+ throw invalidInstrumentSelectorError(selector.id);
22
+ }
23
+
17
24
  const getter = () =>
18
- Object.values(state.balance.get(selector.quote.id).position).filter(
19
- it => it.instrument.id == selector.id
20
- );
25
+ Object.values(balance.position)
26
+ .filter(it => it.instrument.id == selector.id)
27
+ .map(it => it as Readonly<Position>);
21
28
 
22
- return (source: Observable<Position>) =>
29
+ return (source: Observable<Component>) =>
23
30
  source.pipe(
24
31
  position(selector),
25
32
  map(() => getter()),
@@ -1,17 +1,20 @@
1
1
  import { d } from '../shared';
2
2
  import { Asset } from './asset';
3
+ import { Commission } from './commission';
3
4
  import { Instrument } from './instrument';
4
5
  import { Position } from './position';
5
6
 
6
7
  describe('Position', () => {
7
8
  const instrument = new Instrument(
9
+ 0,
8
10
  new Asset('abc', 'xyz', 4),
9
11
  new Asset('def', 'xyz', 4),
10
- 'abc-def'
12
+ 'abc-def',
13
+ Commission.Zero
11
14
  );
12
15
 
13
16
  test('should construct a position', () => {
14
- const sut = new Position('1', instrument, 'CROSS', d(10), d(2), 3);
17
+ const sut = new Position(0, '1', instrument, 'CROSS', d(10), d(2), 3);
15
18
 
16
19
  expect(sut.id).toEqual('1');
17
20
  expect(sut.mode).toEqual('CROSS');
@@ -23,14 +26,14 @@ describe('Position', () => {
23
26
  });
24
27
 
25
28
  test('should calculate correct margin', () => {
26
- const sut = new Position('1', instrument, 'CROSS', d(2511.81), d(10.31), 20);
29
+ const sut = new Position(0, '1', instrument, 'CROSS', d(2511.81), d(10.31), 20);
27
30
 
28
31
  expect(sut.margin).toEqual(d(0.5155));
29
32
  expect(sut.estimatedUnrealizedPnL).toEqual(undefined);
30
33
  });
31
34
 
32
35
  test('should calculate correct unrealized pnl', () => {
33
- const sut = new Position('1', instrument, 'CROSS', d(2511.81), d(10.31), 20);
36
+ const sut = new Position(0, '1', instrument, 'CROSS', d(2511.81), d(10.31), 20);
34
37
 
35
38
  const pnl = sut.calculateEstimatedUnrealizedPnL(d(2576.44));
36
39
 
@@ -1,12 +1,10 @@
1
1
  import { Instrument } from '../domain';
2
- import { decimal, pnl, timestamp } from '../shared';
2
+ import { decimal, pnl } from '../shared';
3
3
  import { Component } from './component';
4
4
 
5
5
  export type PositionMode = 'CROSS' | 'ISOLATED';
6
6
 
7
7
  export class Position implements Component {
8
- kind = 'position';
9
- timestamp: timestamp;
10
8
  estimatedUnrealizedPnL?: decimal;
11
9
 
12
10
  get margin(): decimal {
@@ -14,6 +12,7 @@ export class Position implements Component {
14
12
  }
15
13
 
16
14
  constructor(
15
+ public timestamp: number,
17
16
  readonly id: string,
18
17
  readonly instrument: Instrument,
19
18
  readonly mode: PositionMode,
@@ -29,8 +28,4 @@ export class Position implements Component {
29
28
 
30
29
  return this.estimatedUnrealizedPnL;
31
30
  }
32
-
33
- toString() {
34
- return this.id;
35
- }
36
31
  }
@@ -0,0 +1,158 @@
1
+ import {
2
+ AdapterAggregate,
3
+ AdapterFactory,
4
+ BacktesterListener,
5
+ BacktesterStreamer,
6
+ createBacktesterAdapterFactory,
7
+ createPaperAdapterFactory,
8
+ DefaultTimeProvider
9
+ } from '../adapter';
10
+ import { decimal, now } from '../shared';
11
+ import {
12
+ Cache,
13
+ Feed,
14
+ inMemoryStorageFactory,
15
+ Measurement,
16
+ StorageFactory
17
+ } from '../storage';
18
+ import { Store } from '../store';
19
+ import { AssetSelector } from './asset';
20
+ import { Session } from './session';
21
+
22
+ export type SessionFeature = (builder: SessionBuilder) => void;
23
+
24
+ export function deposit(selector: AssetSelector, amount: decimal): SessionFeature {
25
+ return (builder: SessionBuilder) => {
26
+ builder.useBalance(selector, amount);
27
+ };
28
+ }
29
+
30
+ export function period(from: Date, to?: Date): SessionFeature {
31
+ return (builder: SessionBuilder) => {
32
+ builder.usePeriod(from.getTime(), to?.getTime() ?? now());
33
+ };
34
+ }
35
+
36
+ export class SessionBuilder {
37
+ public id: number = now();
38
+ public adapter = new Array<AdapterFactory>();
39
+ public storage: StorageFactory = inMemoryStorageFactory();
40
+ public balance: Record<string, decimal> = {};
41
+ public period = {
42
+ from: 0,
43
+ to: Number.MAX_VALUE
44
+ };
45
+
46
+ /**
47
+ * Unique session identifier, used to identify session in the storage.
48
+ * You can generate new id every time you start the new session or provide
49
+ * session id explicitly to resume previous session (in code or via CLI).
50
+ * If you don't provide session id, it will generate new one based on time.
51
+ */
52
+ useSessionId(id: number): SessionBuilder {
53
+ this.id = id;
54
+
55
+ return this;
56
+ }
57
+
58
+ /**
59
+ * Collection of adapters used to connect to the exchanges.
60
+ */
61
+ useAdapter(adapter: AdapterFactory): SessionBuilder {
62
+ this.adapter.push(adapter);
63
+
64
+ return this;
65
+ }
66
+
67
+ /**
68
+ * Provides historical data for backtest, it's not required for live and paper
69
+ * sessions. Stores session variables i.e. indicators, orders, or any other type of time
70
+ * series data. You can install @quantform/editor to render this data in your browser.
71
+ */
72
+ useStorage(storage: StorageFactory): SessionBuilder {
73
+ this.storage = storage;
74
+
75
+ return this;
76
+ }
77
+
78
+ useBalance(selector: AssetSelector, amount: decimal): SessionBuilder {
79
+ this.balance[selector.id] = amount;
80
+
81
+ return this;
82
+ }
83
+
84
+ usePeriod(from: number, to: number): SessionBuilder {
85
+ this.period.from = from;
86
+ this.period.to = to;
87
+
88
+ return this;
89
+ }
90
+
91
+ /**
92
+ * Starts a new backtest session.
93
+ * @param listener backtest event listener.
94
+ * @returns new session object.
95
+ */
96
+ backtest(listener?: BacktesterListener): [Session, BacktesterStreamer] {
97
+ const store = new Store();
98
+ const feed = new Feed(this.storage('feed'));
99
+ const cache = new Cache(this.storage('cache'));
100
+ const measurement = new Measurement(this.storage('measurement'));
101
+
102
+ const streamer = new BacktesterStreamer(store, feed, this.period, listener);
103
+
104
+ const aggregate = new AdapterAggregate(
105
+ this.adapter.map(it =>
106
+ createBacktesterAdapterFactory(
107
+ createPaperAdapterFactory(it, { balance: this.balance }),
108
+ streamer
109
+ )
110
+ ),
111
+ streamer.getTimeProvider(),
112
+ store,
113
+ cache
114
+ );
115
+
116
+ const session = new Session(this.id, store, aggregate, measurement);
117
+
118
+ return [session, streamer];
119
+ }
120
+
121
+ /**
122
+ * Starts a new paper session.
123
+ * @returns new session object.
124
+ */
125
+ paper(): Session {
126
+ const store = new Store();
127
+ const cache = new Cache(this.storage('cache'));
128
+ const measurement = new Measurement(this.storage('measurement'));
129
+
130
+ const aggregate = new AdapterAggregate(
131
+ this.adapter.map(it => createPaperAdapterFactory(it, { balance: this.balance })),
132
+ DefaultTimeProvider,
133
+ store,
134
+ cache
135
+ );
136
+
137
+ return new Session(this.id, store, aggregate, measurement);
138
+ }
139
+
140
+ /**
141
+ * Starts a new live session.
142
+ * @returns new session object.
143
+ */
144
+ live(): Session {
145
+ const store = new Store();
146
+ const cache = new Cache(this.storage('cache'));
147
+ const measurement = new Measurement(this.storage('measurement'));
148
+
149
+ const aggregate = new AdapterAggregate(
150
+ this.adapter,
151
+ DefaultTimeProvider,
152
+ store,
153
+ cache
154
+ );
155
+
156
+ return new Session(this.id, store, aggregate, measurement);
157
+ }
158
+ }
@@ -1,17 +1,10 @@
1
- import { Bootstrap } from '../bootstrap';
2
- import { Asset, Commission } from '../domain';
1
+ import { Asset, Commission, SessionBuilder } from '../domain';
3
2
  import { d, now } from '../shared';
4
3
  import { InstrumentPatchEvent } from '../store';
5
- import { SessionDescriptor } from './session';
6
4
 
7
5
  describe('Session', () => {
8
- const descriptor: SessionDescriptor = {
9
- id: now(),
10
- adapter: []
11
- };
12
-
13
6
  test('should trigger once', done => {
14
- const session = new Bootstrap(descriptor).paper();
7
+ const session = new SessionBuilder().paper();
15
8
 
16
9
  session.instruments().subscribe({
17
10
  next: it => {
@@ -1,91 +1,61 @@
1
1
  import {
2
+ concat,
2
3
  defer,
3
4
  filter,
4
- finalize,
5
5
  from,
6
6
  map,
7
7
  mergeMap,
8
8
  Observable,
9
+ of,
10
+ ReplaySubject,
11
+ share,
9
12
  shareReplay,
10
13
  startWith,
11
- Subscription,
12
14
  switchMap,
13
15
  take
14
16
  } from 'rxjs';
17
+ import { v4 } from 'uuid';
15
18
 
16
- import { AdapterFactory, BacktesterOptions, PaperOptions } from '../adapter';
17
19
  import { AdapterAggregate } from '../adapter/adapter-aggregate';
18
20
  import {
19
21
  AssetSelector,
20
22
  Balance,
21
- Candle,
22
23
  Instrument,
23
24
  InstrumentSelector,
25
+ invalidInstrumentSelectorError,
26
+ Ohlc,
24
27
  Order,
25
28
  Orderbook,
26
29
  Position,
27
30
  Trade
28
31
  } from '../domain';
29
- import { now } from '../shared';
30
- import { StorageFactory } from '../storage';
32
+ import { decimal } from '../shared';
33
+ import { Measurement } from '../storage';
31
34
  import { Store } from '../store';
32
- import { balance } from './balance.operator';
33
- import { instrument, instruments } from './instrument.operator';
34
- import { order, orders } from './order.operator';
35
- import { orderbook } from './orderbook.operator';
36
- import { position, positions } from './position.operator';
37
- import { trade } from './trade.operator';
38
-
39
- /**
40
- * Describes a single session.
41
- */
42
- export interface SessionDescriptor {
43
- /**
44
- * Unique session identifier, used to identify session in the storage.
45
- * You can generate new id every time you start the new session or provide
46
- * session id explicitly to resume previous session (in code or via CLI).
47
- * If you don't provide session id, it will generate new one based on time.
48
- */
49
- id?: number;
50
-
51
- /**
52
- * Collection of adapters used to connect to the exchanges.
53
- */
54
- adapter: AdapterFactory[];
35
+ import { balance } from './balance-operator';
36
+ import { instrument, instruments } from './instrument-operator';
37
+ import { order, orders } from './order-operator';
38
+ import { orderbook } from './orderbook-operator';
39
+ import { position, positions } from './position-operator';
40
+ import { trade } from './trade-operator';
55
41
 
56
- /**
57
- * Provides historical data for backtest, it's not required for live and paper
58
- * sessions. Stores session variables i.e. indicators, orders, or any other type of time
59
- * series data. You can install @quantform/editor to render this data in your browser.
60
- */
61
- storage?: StorageFactory;
62
-
63
- /**
64
- * Session additional options.
65
- */
66
- simulation?: PaperOptions & BacktesterOptions;
67
- }
42
+ type Optional<T, K extends keyof T> = Omit<T, K> & Partial<T>;
68
43
 
69
44
  export class Session {
70
45
  private initialized = false;
71
- private subscription: Subscription;
72
46
 
73
47
  get timestamp(): number {
74
48
  return this.store.snapshot.timestamp;
75
49
  }
76
50
 
77
51
  constructor(
52
+ readonly id: number,
78
53
  readonly store: Store,
79
54
  readonly aggregate: AdapterAggregate,
80
- readonly descriptor?: SessionDescriptor
81
- ) {
82
- // generate session id based on time if not provided.
83
- if (descriptor && !descriptor.id) {
84
- descriptor.id = now();
85
- }
86
- }
55
+ readonly measurement: Measurement | undefined
56
+ ) {}
87
57
 
88
- async awake(describe: (session: Session) => Observable<any>): Promise<void> {
58
+ async awake(): Promise<void> {
89
59
  if (this.initialized) {
90
60
  return;
91
61
  }
@@ -94,12 +64,6 @@ export class Session {
94
64
 
95
65
  // awake all adapters and synchronize trading accounts with store.
96
66
  await this.aggregate.awake();
97
-
98
- if (describe) {
99
- this.subscription = describe(this)
100
- .pipe(finalize(() => this.dispose()))
101
- .subscribe();
102
- }
103
67
  }
104
68
 
105
69
  async dispose(): Promise<void> {
@@ -107,11 +71,6 @@ export class Session {
107
71
  return;
108
72
  }
109
73
 
110
- if (this.subscription) {
111
- this.subscription.unsubscribe();
112
- this.subscription = undefined;
113
- }
114
-
115
74
  this.store.dispose();
116
75
 
117
76
  await this.aggregate.dispose();
@@ -129,12 +88,31 @@ export class Session {
129
88
 
130
89
  /**
131
90
  * Opens a new order.
132
- * Example of buy order:
133
- * session.open(Order.market(instrument, 100));
134
91
  */
135
- open(order: Order): Observable<Readonly<Order>> {
136
- return from(this.aggregate.open(order)).pipe(
137
- switchMap(() => this.order(order.instrument).pipe(filter(it => it.id == order.id)))
92
+ open(order: {
93
+ instrument: InstrumentSelector;
94
+ quantity: decimal;
95
+ rate?: decimal;
96
+ }): Observable<Readonly<Order>> {
97
+ const instrument = this.store.snapshot.universe.instrument.get(order.instrument.id);
98
+ if (!instrument) {
99
+ throw invalidInstrumentSelectorError(order.instrument.id);
100
+ }
101
+
102
+ const newOrder = new Order(
103
+ this.timestamp,
104
+ v4(),
105
+ instrument,
106
+ order.quantity,
107
+ this.timestamp,
108
+ order.rate
109
+ );
110
+
111
+ return of(newOrder).pipe(
112
+ switchMap(() => this.aggregate.open(newOrder)),
113
+ switchMap(() =>
114
+ this.order(order.instrument).pipe(filter(it => it.id == newOrder.id))
115
+ )
138
116
  );
139
117
  }
140
118
 
@@ -143,10 +121,7 @@ export class Session {
143
121
  */
144
122
  cancel(order: Order): Observable<Readonly<Order>> {
145
123
  return defer(() => from(this.aggregate.cancel(order))).pipe(
146
- switchMap(() =>
147
- this.store.changes$.pipe(filter(it => it instanceof Order && order.id == it.id))
148
- ),
149
- map(it => it as Order)
124
+ switchMap(() => this.order(order.instrument).pipe(filter(it => it.id == order.id)))
150
125
  );
151
126
  }
152
127
 
@@ -228,7 +203,7 @@ export class Session {
228
203
  selector: InstrumentSelector,
229
204
  timeframe: number,
230
205
  length: number
231
- ): Observable<Readonly<Candle>> {
206
+ ): Observable<Readonly<Ohlc>> {
232
207
  return this.store.changes$.pipe(
233
208
  startWith(this.store.snapshot.universe.instrument.get(selector.id)),
234
209
  filter(it => it instanceof Instrument && it.id == selector.id),
@@ -238,4 +213,44 @@ export class Session {
238
213
  mergeMap(it => it)
239
214
  );
240
215
  }
216
+
217
+ measure<T extends { timestamp: number }>(
218
+ spec: {
219
+ kind: string;
220
+ timestamp?: number;
221
+ },
222
+ defaultValue?: Optional<T, 'timestamp'>
223
+ ): [Observable<T>, (value: T) => void] {
224
+ if (!this.measurement) {
225
+ throw new Error();
226
+ }
227
+
228
+ const changes$ = new ReplaySubject<Optional<T, 'timestamp'>>();
229
+ const persisted$ = from(
230
+ this.measurement.query(this.id, {
231
+ to: spec.timestamp ?? this.timestamp,
232
+ kind: spec.kind,
233
+ count: 1
234
+ })
235
+ ).pipe(
236
+ map(it =>
237
+ it.length ? { timestamp: it[0].timestamp, ...it[0].payload } : defaultValue
238
+ ),
239
+ share()
240
+ );
241
+
242
+ const setter = (value: Optional<T, 'timestamp'>) => {
243
+ const timestamp = value.timestamp ?? this.timestamp;
244
+ const measure = { timestamp, kind: spec.kind, payload: value };
245
+
246
+ this.measurement?.save(this.id, [measure]);
247
+
248
+ changes$.next({ ...value, timestamp });
249
+ };
250
+
251
+ return [
252
+ concat(persisted$, changes$.asObservable()).pipe(filter(it => it !== undefined)),
253
+ setter
254
+ ];
255
+ }
241
256
  }
@@ -1,23 +1,27 @@
1
1
  import { Subject } from 'rxjs';
2
2
 
3
+ import { d } from '../shared';
3
4
  import { State } from '../store';
4
5
  import { Asset } from './asset';
6
+ import { Commission } from './commission';
5
7
  import { Component } from './component';
6
8
  import { Instrument } from './instrument';
7
9
  import { Trade } from './trade';
8
- import { trade } from './trade.operator';
10
+ import { trade } from './trade-operator';
9
11
 
10
12
  describe('trade', () => {
11
13
  const instrument = new Instrument(
14
+ 0,
12
15
  new Asset('abc', 'xyz', 4),
13
16
  new Asset('def', 'xyz', 4),
14
- 'abc-def'
17
+ 'abc-def',
18
+ Commission.Zero
15
19
  );
16
20
 
17
21
  const state = new State();
18
22
 
19
23
  beforeEach(() => {
20
- state.trade.upsert(new Trade(instrument));
24
+ state.trade.upsert(new Trade(0, instrument, d.Zero, d.Zero));
21
25
  });
22
26
 
23
27
  test('should pipe an orderbook on subscription', done => {
@@ -1,16 +1,20 @@
1
+ import { d } from '../shared';
1
2
  import { Asset } from './asset';
3
+ import { Commission } from './commission';
2
4
  import { Instrument } from './instrument';
3
5
  import { Trade } from './trade';
4
6
 
5
7
  describe('Trade', () => {
6
8
  const instrument = new Instrument(
9
+ 0,
7
10
  new Asset('abc', 'xyz', 4),
8
11
  new Asset('def', 'xyz', 4),
9
- 'abc-def'
12
+ 'abc-def',
13
+ Commission.Zero
10
14
  );
11
15
 
12
16
  test('should construct an empty trade', () => {
13
- const sut = new Trade(instrument);
17
+ const sut = new Trade(0, instrument, d.Zero, d.Zero);
14
18
 
15
19
  expect(sut.id).toEqual(instrument.id);
16
20
  });
@@ -1,4 +1,4 @@
1
- import { decimal, timestamp } from '../shared';
1
+ import { decimal } from '../shared';
2
2
  import { Instrument } from '.';
3
3
  import { Component } from './component';
4
4
 
@@ -7,17 +7,14 @@ import { Component } from './component';
7
7
  * and seller of the same asset.
8
8
  */
9
9
  export class Trade implements Component {
10
- id: string;
11
- kind = 'trade';
12
- timestamp: timestamp;
13
- rate: decimal;
14
- quantity: decimal;
10
+ readonly id: string;
15
11
 
16
- constructor(public readonly instrument: Instrument) {
12
+ constructor(
13
+ public timestamp: number,
14
+ public readonly instrument: Instrument,
15
+ public rate: decimal,
16
+ public quantity: decimal
17
+ ) {
17
18
  this.id = instrument.id;
18
19
  }
19
-
20
- toString() {
21
- return this.instrument.toString();
22
- }
23
20
  }