@quantform/core 0.4.11 → 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 (490) hide show
  1. package/dist/adapter/adapter-aggregate.d.ts +7 -3
  2. package/dist/adapter/adapter-aggregate.js +17 -18
  3. package/dist/adapter/adapter-aggregate.js.map +1 -1
  4. package/dist/adapter/adapter.d.ts +21 -21
  5. package/dist/adapter/adapter.js +8 -40
  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 +15 -13
  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/backtester/index.js +5 -1
  24. package/dist/adapter/backtester/index.js.map +1 -1
  25. package/dist/adapter/error.d.ts +2 -0
  26. package/dist/adapter/error.js +12 -0
  27. package/dist/adapter/error.js.map +1 -0
  28. package/dist/adapter/index.js +5 -1
  29. package/dist/adapter/index.js.map +1 -1
  30. package/dist/adapter/paper/engine/paper-engine.d.ts +11 -0
  31. package/dist/adapter/paper/engine/paper-engine.js +103 -0
  32. package/dist/adapter/paper/engine/paper-engine.js.map +1 -0
  33. package/dist/adapter/paper/{simulator/paper-spot-simulator.spec.d.ts → engine/paper-engine.spec.d.ts} +0 -0
  34. package/dist/adapter/paper/engine/paper-engine.spec.js +54 -0
  35. package/dist/adapter/paper/engine/paper-engine.spec.js.map +1 -0
  36. package/dist/adapter/paper/index.d.ts +1 -2
  37. package/dist/adapter/paper/index.js +6 -3
  38. package/dist/adapter/paper/index.js.map +1 -1
  39. package/dist/adapter/paper/paper-adapter.d.ts +7 -7
  40. package/dist/adapter/paper/paper-adapter.js +21 -19
  41. package/dist/adapter/paper/paper-adapter.js.map +1 -1
  42. package/dist/adapter/paper/paper-adapter.spec.js +35 -15
  43. package/dist/adapter/paper/paper-adapter.spec.js.map +1 -1
  44. package/dist/bootstrap.js +32 -15
  45. package/dist/bootstrap.js.map +1 -1
  46. package/dist/cli/build.d.ts +1 -0
  47. package/dist/cli/build.js +16 -0
  48. package/dist/cli/build.js.map +1 -0
  49. package/dist/cli/dev.d.ts +1 -0
  50. package/dist/cli/dev.js +17 -0
  51. package/dist/cli/dev.js.map +1 -0
  52. package/dist/cli/index.d.ts +2 -0
  53. package/dist/cli/index.js +72 -0
  54. package/dist/cli/index.js.map +1 -0
  55. package/dist/cli/internal/workspace.d.ts +8 -0
  56. package/dist/cli/internal/workspace.js +14 -0
  57. package/dist/cli/internal/workspace.js.map +1 -0
  58. package/dist/cli/pull.d.ts +1 -0
  59. package/dist/cli/pull.js +52 -0
  60. package/dist/cli/pull.js.map +1 -0
  61. package/dist/cli/run.d.ts +1 -0
  62. package/dist/cli/run.js +19 -0
  63. package/dist/cli/run.js.map +1 -0
  64. package/dist/cli/test.d.ts +1 -0
  65. package/dist/cli/test.js +41 -0
  66. package/dist/cli/test.js.map +1 -0
  67. package/dist/domain/asset.d.ts +6 -5
  68. package/dist/domain/asset.js +22 -16
  69. package/dist/domain/asset.js.map +1 -1
  70. package/dist/domain/asset.spec.js +32 -32
  71. package/dist/domain/asset.spec.js.map +1 -1
  72. package/dist/domain/balance.d.ts +11 -10
  73. package/dist/domain/balance.js +38 -32
  74. package/dist/domain/balance.js.map +1 -1
  75. package/dist/domain/balance.operator.d.ts +6 -0
  76. package/dist/domain/balance.operator.js +10 -0
  77. package/dist/domain/balance.operator.js.map +1 -0
  78. package/dist/{ipc.spec.d.ts → domain/balance.operator.spec.d.ts} +0 -0
  79. package/dist/domain/balance.operator.spec.js +23 -0
  80. package/dist/domain/balance.operator.spec.js.map +1 -0
  81. package/dist/domain/balance.spec.js +69 -9
  82. package/dist/domain/balance.spec.js.map +1 -1
  83. package/dist/domain/candle.d.ts +2 -15
  84. package/dist/domain/candle.js +3 -66
  85. package/dist/domain/candle.js.map +1 -1
  86. package/dist/domain/candle.operator.d.ts +9 -0
  87. package/dist/domain/candle.operator.js +64 -0
  88. package/dist/domain/candle.operator.js.map +1 -0
  89. package/dist/{shared/policy.spec.d.ts → domain/candle.operator.spec.d.ts} +0 -0
  90. package/dist/domain/candle.operator.spec.js +111 -0
  91. package/dist/domain/candle.operator.spec.js.map +1 -0
  92. package/dist/domain/candle.spec.js +11 -53
  93. package/dist/domain/candle.spec.js.map +1 -1
  94. package/dist/domain/commission.d.ts +4 -1
  95. package/dist/domain/commission.js +2 -2
  96. package/dist/domain/commission.js.map +1 -1
  97. package/dist/{shared/topic.spec.d.ts → domain/commission.spec.d.ts} +0 -0
  98. package/dist/domain/commission.spec.js +30 -0
  99. package/dist/domain/commission.spec.js.map +1 -0
  100. package/dist/domain/component.d.ts +2 -0
  101. package/dist/domain/error.d.ts +5 -0
  102. package/dist/domain/error.js +24 -0
  103. package/dist/domain/error.js.map +1 -0
  104. package/dist/domain/index.d.ts +8 -1
  105. package/dist/domain/index.js +13 -2
  106. package/dist/domain/index.js.map +1 -1
  107. package/dist/domain/instrument.d.ts +4 -2
  108. package/dist/domain/instrument.js +18 -9
  109. package/dist/domain/instrument.js.map +1 -1
  110. package/dist/domain/instrument.operator.d.ts +6 -0
  111. package/dist/domain/instrument.operator.js +14 -0
  112. package/dist/domain/instrument.operator.js.map +1 -0
  113. package/dist/{shared/worker.spec.d.ts → domain/instrument.operator.spec.d.ts} +0 -0
  114. package/dist/domain/instrument.operator.spec.js +24 -0
  115. package/dist/domain/instrument.operator.spec.js.map +1 -0
  116. package/dist/domain/instrument.spec.js +22 -30
  117. package/dist/domain/instrument.spec.js.map +1 -1
  118. package/dist/domain/order.d.ts +15 -16
  119. package/dist/domain/order.js +39 -26
  120. package/dist/domain/order.js.map +1 -1
  121. package/dist/domain/order.operator.d.ts +7 -0
  122. package/dist/domain/order.operator.js +14 -0
  123. package/dist/domain/order.operator.js.map +1 -0
  124. package/dist/{store/event/store-balance.event.spec.d.ts → domain/order.operator.spec.d.ts} +0 -0
  125. package/dist/domain/order.operator.spec.js +64 -0
  126. package/dist/domain/order.operator.spec.js.map +1 -0
  127. package/dist/{store/event/store-candle.event.spec.d.ts → domain/order.spec.d.ts} +0 -0
  128. package/dist/domain/order.spec.js +33 -0
  129. package/dist/domain/order.spec.js.map +1 -0
  130. package/dist/domain/orderbook.d.ts +2 -0
  131. package/dist/domain/orderbook.js +2 -0
  132. package/dist/domain/orderbook.js.map +1 -1
  133. package/dist/domain/orderbook.operator.d.ts +6 -0
  134. package/dist/domain/orderbook.operator.js +10 -0
  135. package/dist/domain/orderbook.operator.js.map +1 -0
  136. package/dist/{store/event/store-instrument.event.spec.d.ts → domain/orderbook.operator.spec.d.ts} +0 -0
  137. package/dist/domain/orderbook.operator.spec.js +22 -0
  138. package/dist/domain/orderbook.operator.spec.js.map +1 -0
  139. package/dist/{store/event/store-order.event.spec.d.ts → domain/orderbook.spec.d.ts} +0 -0
  140. package/dist/domain/orderbook.spec.js +13 -0
  141. package/dist/domain/orderbook.spec.js.map +1 -0
  142. package/dist/domain/position.d.ts +6 -10
  143. package/dist/domain/position.js +10 -31
  144. package/dist/domain/position.js.map +1 -1
  145. package/dist/domain/position.operator.d.ts +10 -0
  146. package/dist/domain/position.operator.js +38 -0
  147. package/dist/domain/position.operator.js.map +1 -0
  148. package/dist/{store/event/store-trade.event.spec.d.ts → domain/position.operator.spec.d.ts} +0 -0
  149. package/dist/domain/position.operator.spec.js +48 -0
  150. package/dist/domain/position.operator.spec.js.map +1 -0
  151. package/dist/domain/position.spec.js +21 -17
  152. package/dist/domain/position.spec.js.map +1 -1
  153. package/dist/domain/session.d.ts +18 -35
  154. package/dist/domain/session.js +27 -53
  155. package/dist/domain/session.js.map +1 -1
  156. package/dist/domain/session.spec.js +1 -1
  157. package/dist/domain/session.spec.js.map +1 -1
  158. package/dist/domain/trade.d.ts +3 -1
  159. package/dist/domain/trade.js +2 -0
  160. package/dist/domain/trade.js.map +1 -1
  161. package/dist/domain/trade.operator.d.ts +6 -0
  162. package/dist/domain/trade.operator.js +10 -0
  163. package/dist/domain/trade.operator.js.map +1 -0
  164. package/dist/domain/trade.operator.spec.d.ts +1 -0
  165. package/dist/domain/trade.operator.spec.js +24 -0
  166. package/dist/domain/trade.operator.spec.js.map +1 -0
  167. package/dist/domain/trade.spec.d.ts +1 -0
  168. package/dist/domain/trade.spec.js +13 -0
  169. package/dist/domain/trade.spec.js.map +1 -0
  170. package/dist/index.d.ts +0 -1
  171. package/dist/index.js +5 -2
  172. package/dist/index.js.map +1 -1
  173. package/dist/indicator/atr.js.map +1 -1
  174. package/dist/indicator/cross.spec.js +2 -2
  175. package/dist/indicator/cross.spec.js.map +1 -1
  176. package/dist/indicator/donchian.js.map +1 -1
  177. package/dist/indicator/ema.js.map +1 -1
  178. package/dist/indicator/ema.spec.js +1 -1
  179. package/dist/indicator/ema.spec.js.map +1 -1
  180. package/dist/indicator/envelope.js.map +1 -1
  181. package/dist/indicator/index.js +5 -1
  182. package/dist/indicator/index.js.map +1 -1
  183. package/dist/indicator/macd.js.map +1 -1
  184. package/dist/indicator/min-max.js.map +1 -1
  185. package/dist/indicator/rma.js.map +1 -1
  186. package/dist/indicator/sma.js.map +1 -1
  187. package/dist/indicator/sma.spec.js +1 -1
  188. package/dist/indicator/sma.spec.js.map +1 -1
  189. package/dist/indicator/swma.js.map +1 -1
  190. package/dist/indicator/tma.js.map +1 -1
  191. package/dist/indicator/tma.spec.js +1 -1
  192. package/dist/indicator/tma.spec.js.map +1 -1
  193. package/dist/indicator/trailing.spec.js +2 -2
  194. package/dist/indicator/trailing.spec.js.map +1 -1
  195. package/dist/indicator/truerange.js.map +1 -1
  196. package/dist/indicator/truerange.spec.js +1 -1
  197. package/dist/indicator/truerange.spec.js.map +1 -1
  198. package/dist/indicator/window.js.map +1 -1
  199. package/dist/indicator/wma.js.map +1 -1
  200. package/dist/indicator/wma.spec.js +1 -1
  201. package/dist/indicator/wma.spec.js.map +1 -1
  202. package/dist/shared/collections.d.ts +10 -0
  203. package/dist/shared/collections.js +33 -0
  204. package/dist/shared/collections.js.map +1 -0
  205. package/dist/shared/datetime.d.ts +0 -1
  206. package/dist/shared/datetime.js +1 -12
  207. package/dist/shared/datetime.js.map +1 -1
  208. package/dist/shared/decimals.d.ts +1 -1
  209. package/dist/shared/decimals.js +4 -5
  210. package/dist/shared/decimals.js.map +1 -1
  211. package/dist/shared/decimals.spec.js +2 -1
  212. package/dist/shared/decimals.spec.js.map +1 -1
  213. package/dist/shared/index.d.ts +1 -3
  214. package/dist/shared/index.js +6 -4
  215. package/dist/shared/index.js.map +1 -1
  216. package/dist/shared/io.js.map +1 -1
  217. package/dist/shared/policy.d.ts +0 -1
  218. package/dist/shared/policy.js +1 -11
  219. package/dist/shared/policy.js.map +1 -1
  220. package/dist/storage/cache.d.ts +9 -0
  221. package/dist/storage/cache.js +32 -0
  222. package/dist/storage/cache.js.map +1 -0
  223. package/dist/storage/cache.spec.d.ts +1 -0
  224. package/dist/storage/cache.spec.js +18 -0
  225. package/dist/storage/cache.spec.js.map +1 -0
  226. package/dist/storage/feed.d.ts +3 -4
  227. package/dist/storage/feed.js +16 -6
  228. package/dist/storage/feed.js.map +1 -1
  229. package/dist/storage/index.d.ts +1 -0
  230. package/dist/storage/index.js +6 -1
  231. package/dist/storage/index.js.map +1 -1
  232. package/dist/storage/storage.d.ts +2 -0
  233. package/dist/storage/storage.js +6 -1
  234. package/dist/storage/storage.js.map +1 -1
  235. package/dist/store/index.d.ts +8 -2
  236. package/dist/store/index.js +13 -3
  237. package/dist/store/index.js.map +1 -1
  238. package/dist/store/store-balance.event.d.ts +33 -0
  239. package/dist/store/store-balance.event.js +90 -0
  240. package/dist/store/store-balance.event.js.map +1 -0
  241. package/dist/store/store-balance.event.spec.d.ts +1 -0
  242. package/dist/store/{event/store-balance.event.spec.js → store-balance.event.spec.js} +8 -8
  243. package/dist/store/store-balance.event.spec.js.map +1 -0
  244. package/dist/store/{event/store-instrument.event.d.ts → store-instrument.event.d.ts} +5 -8
  245. package/dist/store/store-instrument.event.js +52 -0
  246. package/dist/store/store-instrument.event.js.map +1 -0
  247. package/dist/store/store-instrument.event.spec.d.ts +1 -0
  248. package/dist/store/store-instrument.event.spec.js +22 -0
  249. package/dist/store/store-instrument.event.spec.js.map +1 -0
  250. package/dist/store/store-order.event.d.ts +59 -0
  251. package/dist/store/store-order.event.js +181 -0
  252. package/dist/store/store-order.event.js.map +1 -0
  253. package/dist/store/store-order.event.spec.d.ts +1 -0
  254. package/dist/store/{event/store-order.event.spec.js → store-order.event.spec.js} +8 -8
  255. package/dist/store/store-order.event.spec.js.map +1 -0
  256. package/dist/store/{event/store-orderbook.event.d.ts → store-orderbook.event.d.ts} +4 -5
  257. package/dist/store/store-orderbook.event.js +42 -0
  258. package/dist/store/store-orderbook.event.js.map +1 -0
  259. package/dist/store/{event/store-position.event.d.ts → store-position.event.d.ts} +5 -7
  260. package/dist/store/store-position.event.js +77 -0
  261. package/dist/store/store-position.event.js.map +1 -0
  262. package/dist/store/store-state.d.ts +27 -0
  263. package/dist/store/store-state.js +29 -0
  264. package/dist/store/store-state.js.map +1 -0
  265. package/dist/store/{event/store-trade.event.d.ts → store-trade.event.d.ts} +4 -5
  266. package/dist/store/store-trade.event.js +25 -0
  267. package/dist/store/store-trade.event.js.map +1 -0
  268. package/dist/store/store-trade.event.spec.d.ts +1 -0
  269. package/dist/store/{event/store-trade.event.spec.js → store-trade.event.spec.js} +14 -14
  270. package/dist/store/store-trade.event.spec.js.map +1 -0
  271. package/dist/store/store.d.ts +4 -25
  272. package/dist/store/store.event.d.ts +6 -0
  273. package/dist/store/{event/store.event.js → store.event.js} +0 -0
  274. package/dist/store/store.event.js.map +1 -0
  275. package/dist/store/store.js +7 -195
  276. package/dist/store/store.js.map +1 -1
  277. package/dist/store/store.spec.d.ts +1 -0
  278. package/dist/store/store.spec.js +119 -0
  279. package/dist/store/store.spec.js.map +1 -0
  280. package/dist/tsconfig.tsbuildinfo +1 -1
  281. package/{jestconfig.unit.json → jestconfig.json} +1 -2
  282. package/package.json +24 -20
  283. package/src/adapter/adapter-aggregate.ts +31 -34
  284. package/src/adapter/adapter.ts +26 -49
  285. package/src/adapter/backtester/backtester-adapter.spec.ts +124 -0
  286. package/src/adapter/backtester/backtester-adapter.ts +30 -17
  287. package/src/adapter/backtester/backtester-cursor.spec.ts +18 -19
  288. package/src/adapter/backtester/backtester-cursor.ts +7 -7
  289. package/src/adapter/backtester/backtester-streamer.spec.ts +19 -19
  290. package/src/adapter/backtester/backtester-streamer.ts +50 -20
  291. package/src/adapter/error.ts +9 -0
  292. package/src/adapter/paper/engine/paper-engine.spec.ts +92 -0
  293. package/src/adapter/paper/engine/paper-engine.ts +135 -0
  294. package/src/adapter/paper/index.ts +1 -2
  295. package/src/adapter/paper/paper-adapter.spec.ts +55 -17
  296. package/src/adapter/paper/paper-adapter.ts +27 -24
  297. package/src/bootstrap.ts +57 -21
  298. package/src/cli/build.ts +15 -0
  299. package/src/cli/dev.ts +18 -0
  300. package/src/cli/index.ts +81 -0
  301. package/src/cli/internal/workspace.ts +18 -0
  302. package/src/cli/pull.ts +71 -0
  303. package/src/cli/run.ts +22 -0
  304. package/src/cli/test.ts +53 -0
  305. package/src/domain/asset.spec.ts +33 -29
  306. package/src/domain/asset.ts +27 -21
  307. package/src/domain/balance.operator.spec.ts +25 -0
  308. package/src/domain/balance.operator.ts +15 -0
  309. package/src/domain/balance.spec.ts +97 -9
  310. package/src/domain/balance.ts +48 -41
  311. package/src/domain/candle.operator.spec.ts +125 -0
  312. package/src/domain/candle.operator.ts +106 -0
  313. package/src/domain/candle.spec.ts +12 -67
  314. package/src/domain/candle.ts +2 -104
  315. package/src/domain/commission.spec.ts +33 -0
  316. package/src/domain/commission.ts +2 -2
  317. package/src/domain/component.ts +2 -0
  318. package/src/domain/error.ts +25 -0
  319. package/src/domain/index.ts +8 -1
  320. package/src/domain/instrument.operator.spec.ts +28 -0
  321. package/src/domain/instrument.operator.ts +25 -0
  322. package/src/domain/instrument.spec.ts +22 -30
  323. package/src/domain/instrument.ts +21 -11
  324. package/src/domain/order.operator.spec.ts +81 -0
  325. package/src/domain/order.operator.ts +23 -0
  326. package/src/domain/order.spec.ts +43 -0
  327. package/src/domain/order.ts +46 -47
  328. package/src/domain/orderbook.operator.spec.ts +28 -0
  329. package/src/domain/orderbook.operator.ts +15 -0
  330. package/src/domain/orderbook.spec.ts +17 -0
  331. package/src/domain/orderbook.ts +5 -1
  332. package/src/domain/position.operator.spec.ts +58 -0
  333. package/src/domain/position.operator.ts +61 -0
  334. package/src/domain/position.spec.ts +28 -24
  335. package/src/domain/position.ts +17 -47
  336. package/src/domain/session.spec.ts +1 -1
  337. package/src/domain/session.ts +57 -197
  338. package/src/domain/trade.operator.spec.ts +31 -0
  339. package/src/domain/trade.operator.ts +15 -0
  340. package/src/domain/trade.spec.ts +17 -0
  341. package/src/domain/trade.ts +6 -2
  342. package/src/index.ts +0 -1
  343. package/src/indicator/atr.ts +1 -0
  344. package/src/indicator/cross.spec.ts +3 -2
  345. package/src/indicator/donchian.ts +1 -0
  346. package/src/indicator/ema.spec.ts +2 -1
  347. package/src/indicator/ema.ts +1 -0
  348. package/src/indicator/envelope.ts +1 -0
  349. package/src/indicator/macd.ts +1 -0
  350. package/src/indicator/min-max.ts +1 -0
  351. package/src/indicator/rma.ts +1 -0
  352. package/src/indicator/sma.spec.ts +2 -1
  353. package/src/indicator/sma.ts +1 -0
  354. package/src/indicator/swma.ts +1 -0
  355. package/src/indicator/tma.spec.ts +2 -1
  356. package/src/indicator/tma.ts +1 -0
  357. package/src/indicator/trailing.spec.ts +3 -2
  358. package/src/indicator/truerange.spec.ts +2 -1
  359. package/src/indicator/truerange.ts +1 -0
  360. package/src/indicator/window.ts +1 -0
  361. package/src/indicator/wma.spec.ts +2 -1
  362. package/src/indicator/wma.ts +1 -0
  363. package/src/shared/collections.ts +35 -0
  364. package/src/shared/datetime.ts +0 -12
  365. package/src/shared/decimals.spec.ts +2 -1
  366. package/src/shared/decimals.ts +6 -6
  367. package/src/shared/index.ts +1 -3
  368. package/src/shared/io.ts +0 -2
  369. package/src/shared/policy.ts +0 -13
  370. package/src/storage/cache.spec.ts +18 -0
  371. package/src/storage/cache.ts +35 -0
  372. package/src/storage/feed.ts +26 -16
  373. package/src/storage/index.ts +1 -0
  374. package/src/storage/storage.ts +11 -0
  375. package/src/store/index.ts +8 -2
  376. package/src/store/{event/store-balance.event.spec.ts → store-balance.event.spec.ts} +7 -7
  377. package/src/store/store-balance.event.ts +124 -0
  378. package/src/store/store-instrument.event.spec.ts +25 -0
  379. package/src/store/store-instrument.event.ts +72 -0
  380. package/src/store/store-order.event.spec.ts +28 -0
  381. package/src/store/store-order.event.ts +214 -0
  382. package/src/store/store-orderbook.event.ts +54 -0
  383. package/src/store/store-position.event.ts +102 -0
  384. package/src/store/store-state.ts +48 -0
  385. package/src/store/{event/store-trade.event.spec.ts → store-trade.event.spec.ts} +15 -15
  386. package/src/store/store-trade.event.ts +36 -0
  387. package/src/store/store.event.ts +8 -0
  388. package/src/store/store.spec.ts +180 -0
  389. package/src/store/store.ts +11 -208
  390. package/tsconfig.json +2 -2
  391. package/dist/adapter/paper/simulator/paper-margin-simulator.d.ts +0 -10
  392. package/dist/adapter/paper/simulator/paper-margin-simulator.js +0 -69
  393. package/dist/adapter/paper/simulator/paper-margin-simulator.js.map +0 -1
  394. package/dist/adapter/paper/simulator/paper-simulator.d.ts +0 -16
  395. package/dist/adapter/paper/simulator/paper-simulator.js +0 -93
  396. package/dist/adapter/paper/simulator/paper-simulator.js.map +0 -1
  397. package/dist/adapter/paper/simulator/paper-spot-simulator.d.ts +0 -13
  398. package/dist/adapter/paper/simulator/paper-spot-simulator.js +0 -81
  399. package/dist/adapter/paper/simulator/paper-spot-simulator.js.map +0 -1
  400. package/dist/adapter/paper/simulator/paper-spot-simulator.spec.js +0 -49
  401. package/dist/adapter/paper/simulator/paper-spot-simulator.spec.js.map +0 -1
  402. package/dist/domain/statement.d.ts +0 -4
  403. package/dist/domain/statement.js +0 -87
  404. package/dist/domain/statement.js.map +0 -1
  405. package/dist/ipc.d.ts +0 -33
  406. package/dist/ipc.js +0 -244
  407. package/dist/ipc.js.map +0 -1
  408. package/dist/ipc.spec.js +0 -57
  409. package/dist/ipc.spec.js.map +0 -1
  410. package/dist/shared/policy.spec.js +0 -26
  411. package/dist/shared/policy.spec.js.map +0 -1
  412. package/dist/shared/task.d.ts +0 -6
  413. package/dist/shared/task.js +0 -25
  414. package/dist/shared/task.js.map +0 -1
  415. package/dist/shared/topic.d.ts +0 -14
  416. package/dist/shared/topic.js +0 -40
  417. package/dist/shared/topic.js.map +0 -1
  418. package/dist/shared/topic.spec.js +0 -43
  419. package/dist/shared/topic.spec.js.map +0 -1
  420. package/dist/shared/worker.d.ts +0 -10
  421. package/dist/shared/worker.js +0 -46
  422. package/dist/shared/worker.js.map +0 -1
  423. package/dist/shared/worker.spec.js +0 -18
  424. package/dist/shared/worker.spec.js.map +0 -1
  425. package/dist/store/event/index.d.ts +0 -8
  426. package/dist/store/event/index.js +0 -21
  427. package/dist/store/event/index.js.map +0 -1
  428. package/dist/store/event/store-balance.event.d.ts +0 -37
  429. package/dist/store/event/store-balance.event.js +0 -119
  430. package/dist/store/event/store-balance.event.js.map +0 -1
  431. package/dist/store/event/store-balance.event.spec.js.map +0 -1
  432. package/dist/store/event/store-candle.event.d.ts +0 -18
  433. package/dist/store/event/store-candle.event.js +0 -63
  434. package/dist/store/event/store-candle.event.js.map +0 -1
  435. package/dist/store/event/store-candle.event.spec.js +0 -23
  436. package/dist/store/event/store-candle.event.spec.js.map +0 -1
  437. package/dist/store/event/store-instrument.event.js +0 -78
  438. package/dist/store/event/store-instrument.event.js.map +0 -1
  439. package/dist/store/event/store-instrument.event.spec.js +0 -21
  440. package/dist/store/event/store-instrument.event.spec.js.map +0 -1
  441. package/dist/store/event/store-order.event.d.ts +0 -61
  442. package/dist/store/event/store-order.event.js +0 -205
  443. package/dist/store/event/store-order.event.js.map +0 -1
  444. package/dist/store/event/store-order.event.spec.js.map +0 -1
  445. package/dist/store/event/store-orderbook.event.js +0 -65
  446. package/dist/store/event/store-orderbook.event.js.map +0 -1
  447. package/dist/store/event/store-position.event.js +0 -97
  448. package/dist/store/event/store-position.event.js.map +0 -1
  449. package/dist/store/event/store-trade.event.js +0 -47
  450. package/dist/store/event/store-trade.event.js.map +0 -1
  451. package/dist/store/event/store-trade.event.spec.js.map +0 -1
  452. package/dist/store/event/store.event.d.ts +0 -5
  453. package/dist/store/event/store.event.js.map +0 -1
  454. package/dist/store/store.state.d.ts +0 -21
  455. package/dist/store/store.state.js +0 -21
  456. package/dist/store/store.state.js.map +0 -1
  457. package/dist/tests/backtester-adapter.spec.js +0 -60
  458. package/dist/tests/backtester-adapter.spec.js.map +0 -1
  459. package/dist/tests/session.spec.d.ts +0 -0
  460. package/dist/tests/session.spec.js +0 -1
  461. package/dist/tests/session.spec.js.map +0 -1
  462. package/jestconfig.integration.json +0 -12
  463. package/src/adapter/paper/simulator/paper-margin-simulator.ts +0 -108
  464. package/src/adapter/paper/simulator/paper-simulator.ts +0 -120
  465. package/src/adapter/paper/simulator/paper-spot-simulator.spec.ts +0 -87
  466. package/src/adapter/paper/simulator/paper-spot-simulator.ts +0 -134
  467. package/src/domain/statement.ts +0 -118
  468. package/src/ipc.spec.ts +0 -73
  469. package/src/ipc.ts +0 -321
  470. package/src/shared/policy.spec.ts +0 -29
  471. package/src/shared/task.ts +0 -30
  472. package/src/shared/topic.spec.ts +0 -34
  473. package/src/shared/topic.ts +0 -43
  474. package/src/shared/worker.spec.ts +0 -25
  475. package/src/shared/worker.ts +0 -55
  476. package/src/store/event/index.ts +0 -8
  477. package/src/store/event/store-balance.event.ts +0 -161
  478. package/src/store/event/store-candle.event.spec.ts +0 -30
  479. package/src/store/event/store-candle.event.ts +0 -71
  480. package/src/store/event/store-instrument.event.spec.ts +0 -25
  481. package/src/store/event/store-instrument.event.ts +0 -84
  482. package/src/store/event/store-order.event.spec.ts +0 -28
  483. package/src/store/event/store-order.event.ts +0 -218
  484. package/src/store/event/store-orderbook.event.ts +0 -70
  485. package/src/store/event/store-position.event.ts +0 -109
  486. package/src/store/event/store-trade.event.ts +0 -52
  487. package/src/store/event/store.event.ts +0 -6
  488. package/src/store/store.state.ts +0 -43
  489. package/src/tests/backtester-adapter.spec.ts +0 -87
  490. package/src/tests/session.spec.ts +0 -121
package/src/bootstrap.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  import {
2
2
  AdapterAggregate,
3
- BacktesterAdapter,
4
3
  BacktesterListener,
5
4
  BacktesterStreamer,
6
- PaperAdapter
5
+ createBacktesterAdapterFactory,
6
+ createPaperAdapterFactory,
7
+ DefaultTimeProvider
7
8
  } from './adapter';
8
9
  import { Session, SessionDescriptor } from './domain';
10
+ import { Cache, Feed, inMemoryStorageFactory } from './storage';
9
11
  import { Store } from './store';
10
12
 
11
13
  export class Bootstrap {
@@ -29,12 +31,20 @@ export class Bootstrap {
29
31
  * @param to
30
32
  */
31
33
  useBacktestPeriod(from?: number, to?: number): Bootstrap {
34
+ if (!this.descriptor.simulation) {
35
+ this.descriptor.simulation = {
36
+ balance: {},
37
+ from: undefined,
38
+ to: undefined
39
+ };
40
+ }
41
+
32
42
  if (from) {
33
- this.descriptor.options.backtester.from = from;
43
+ this.descriptor.simulation.from = from;
34
44
  }
35
45
 
36
46
  if (to) {
37
- this.descriptor.options.backtester.to = to;
47
+ this.descriptor.simulation.to = to;
38
48
  }
39
49
 
40
50
  return this;
@@ -47,16 +57,27 @@ export class Bootstrap {
47
57
  */
48
58
  backtest(listener?: BacktesterListener): [Session, BacktesterStreamer] {
49
59
  const store = new Store();
50
- const { feed } = this.descriptor;
51
- const { backtester } = this.descriptor.options;
52
-
53
- const streamer = new BacktesterStreamer(store, feed, backtester, listener);
60
+ const storage = this.descriptor.storage ?? inMemoryStorageFactory();
61
+ const feed = new Feed(storage('feed'));
62
+ const cache = new Cache(storage('cache'));
63
+
64
+ const streamer = new BacktesterStreamer(
65
+ store,
66
+ feed,
67
+ this.descriptor.simulation,
68
+ listener
69
+ );
54
70
 
55
71
  const aggregate = new AdapterAggregate(
56
- this.descriptor.adapter.map(
57
- it => new BacktesterAdapter(new PaperAdapter(it, store, backtester), streamer)
72
+ this.descriptor.adapter.map(it =>
73
+ createBacktesterAdapterFactory(
74
+ createPaperAdapterFactory(it, this.descriptor.simulation),
75
+ streamer
76
+ )
58
77
  ),
59
- store
78
+ streamer.getTimeProvider(),
79
+ store,
80
+ cache
60
81
  );
61
82
 
62
83
  const session = new Session(store, aggregate, this.descriptor);
@@ -69,22 +90,29 @@ export class Bootstrap {
69
90
  * @returns new session object.
70
91
  */
71
92
  paper(): Session {
72
- if (!this.descriptor.options) {
73
- this.descriptor.options = {};
93
+ if (!this.descriptor.simulation) {
94
+ this.descriptor.simulation = {
95
+ balance: {},
96
+ from: undefined,
97
+ to: undefined
98
+ };
74
99
  }
75
100
 
76
- if (!this.descriptor.options.paper) {
77
- this.descriptor.options.paper = {
78
- balance: {}
79
- };
101
+ if (!this.descriptor.simulation.balance) {
102
+ this.descriptor.simulation.balance = {};
80
103
  }
81
104
 
82
105
  const store = new Store();
83
- const { paper } = this.descriptor.options;
106
+ const storage = this.descriptor.storage ?? inMemoryStorageFactory();
107
+ const cache = new Cache(storage('cache'));
84
108
 
85
109
  const aggregate = new AdapterAggregate(
86
- this.descriptor.adapter.map(it => new PaperAdapter(it, store, paper)),
87
- store
110
+ this.descriptor.adapter.map(it =>
111
+ createPaperAdapterFactory(it, this.descriptor.simulation)
112
+ ),
113
+ DefaultTimeProvider,
114
+ store,
115
+ cache
88
116
  );
89
117
 
90
118
  return new Session(store, aggregate, this.descriptor);
@@ -96,7 +124,15 @@ export class Bootstrap {
96
124
  */
97
125
  live(): Session {
98
126
  const store = new Store();
99
- const aggregate = new AdapterAggregate(this.descriptor.adapter, store);
127
+ const storage = this.descriptor.storage ?? inMemoryStorageFactory();
128
+ const cache = new Cache(storage('cache'));
129
+
130
+ const aggregate = new AdapterAggregate(
131
+ this.descriptor.adapter,
132
+ DefaultTimeProvider,
133
+ store,
134
+ cache
135
+ );
100
136
 
101
137
  return new Session(store, aggregate, this.descriptor);
102
138
  }
@@ -0,0 +1,15 @@
1
+ import { spawn } from 'child_process';
2
+
3
+ import { buildDirectory } from './internal/workspace';
4
+
5
+ export default async function (): Promise<number> {
6
+ return new Promise<number>((resolve, reject) => {
7
+ const process = spawn('swc', ['./src', '--out-dir', buildDirectory()], {
8
+ stdio: 'inherit',
9
+ shell: false
10
+ });
11
+
12
+ process.once('exit', resolve);
13
+ process.once('error', reject);
14
+ });
15
+ }
package/src/cli/dev.ts ADDED
@@ -0,0 +1,18 @@
1
+ import { Bootstrap } from '../bootstrap';
2
+ import build from './build';
3
+ import { getModule } from './internal/workspace';
4
+
5
+ export default async function (name: string, options: any) {
6
+ if (await build()) {
7
+ return;
8
+ }
9
+
10
+ const id = options.id ? Number(options.id) : undefined;
11
+
12
+ const module = await getModule(name);
13
+
14
+ const bootstrap = new Bootstrap(module.descriptor);
15
+ const session = bootstrap.useSessionId(id).paper();
16
+
17
+ await session.awake(module.default);
18
+ }
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { ChildProcess, spawn } from 'child_process';
4
+ import { program } from 'commander';
5
+ import watch from 'node-watch';
6
+
7
+ import build from './build';
8
+ import dev from './dev';
9
+ import pull from './pull';
10
+ import run from './run';
11
+ import test from './test';
12
+
13
+ program
14
+ .command('build')
15
+ .description('builds a production version of the app')
16
+ .action(async () => {
17
+ await build();
18
+ });
19
+
20
+ program
21
+ .command('run')
22
+ .argument('<name>', 'strategy to execute')
23
+ .option('-i, --id <id>', 'session identifier')
24
+ .option('-w', 'watch mode')
25
+ .description('executes strategy in live trading mode')
26
+ .action(run);
27
+
28
+ program
29
+ .command('dev')
30
+ .argument('<name>', 'strategy to execute')
31
+ .option('-i, --id <id>', 'session identifier')
32
+ .option('-w', 'watch mode')
33
+ .description('executes strategy in paper e.g. simulation mode')
34
+ .action(dev);
35
+
36
+ program
37
+ .command('test')
38
+ .description('executes strategy in backtesting mode for specified period')
39
+ .argument('<name>', 'strategy to execute')
40
+ .option('-f, --from <from>', 'date from')
41
+ .option('-t, --to <to>', 'date to')
42
+ .option('-w', 'watch mode')
43
+ .action(test);
44
+
45
+ program
46
+ .command('pull')
47
+ .description('pulls instrument historical data to storage')
48
+ .argument('<name>', 'strategy to execute')
49
+ .argument('<instrument>', 'instrument to import')
50
+ .option('-f, --from <from>', 'date from')
51
+ .option('-t, --to <to>', 'date to')
52
+ .action(pull);
53
+
54
+ program.name('quantform').description('quantform tools');
55
+
56
+ if (process.argv.length < 3) {
57
+ program.help();
58
+ } else {
59
+ if (process.argv.every(it => it != '-w')) {
60
+ program.parse(process.argv);
61
+ } else {
62
+ const argv = process.argv.splice(1).filter(it => it != '-w');
63
+ let child: ChildProcess;
64
+
65
+ const spawnChildProcess = () => {
66
+ console.clear();
67
+
68
+ if (child) {
69
+ child.kill();
70
+ }
71
+
72
+ child = spawn('node', argv, {
73
+ stdio: ['inherit', 'inherit', 'inherit', 'ipc']
74
+ });
75
+ };
76
+
77
+ spawnChildProcess();
78
+
79
+ watch(process.cwd() + '/src', { recursive: true }, () => spawnChildProcess());
80
+ }
81
+ }
@@ -0,0 +1,18 @@
1
+ import { join } from 'path';
2
+ import { Observable } from 'rxjs';
3
+
4
+ import { Session, SessionDescriptor } from './../../domain';
5
+ import { workingDirectory } from './../../shared';
6
+
7
+ export type StrategyModule = {
8
+ descriptor: SessionDescriptor;
9
+ default: (session: Session) => Observable<any>;
10
+ };
11
+
12
+ export function buildDirectory() {
13
+ return join(process.cwd(), workingDirectory(), 'build');
14
+ }
15
+
16
+ export async function getModule(name: string): Promise<StrategyModule> {
17
+ return await import(join(buildDirectory(), name));
18
+ }
@@ -0,0 +1,71 @@
1
+ import { Presets, SingleBar } from 'cli-progress';
2
+
3
+ import { Bootstrap } from '../bootstrap';
4
+ import { instrumentOf } from '../domain';
5
+ import { Feed } from '../storage';
6
+ import build from './build';
7
+ import { getModule } from './internal/workspace';
8
+
9
+ export default async function (name: string, instrument: string, options: any) {
10
+ if (await build()) {
11
+ return;
12
+ }
13
+
14
+ const id = options.id ? Number(options.id) : undefined;
15
+
16
+ const module = await getModule(name);
17
+
18
+ const bootstrap = new Bootstrap(module.descriptor);
19
+ const session = bootstrap.useSessionId(id).paper();
20
+
21
+ if (!module.descriptor.storage) {
22
+ throw new Error('Please provide a "storage" property in session descriptor.');
23
+ }
24
+
25
+ const from = options.from
26
+ ? Date.parse(options.from)
27
+ : module.descriptor.simulation.from;
28
+
29
+ if (!from) {
30
+ throw new Error(
31
+ 'Please set a "from" date in session descriptor or provide the date as parameter.'
32
+ );
33
+ }
34
+
35
+ const to = options.to ? Date.parse(options.to) : module.descriptor.simulation.to;
36
+
37
+ if (!to) {
38
+ throw new Error(
39
+ 'Please set a "to" date in session descriptor or provide the date as parameter.'
40
+ );
41
+ }
42
+
43
+ console.time('Pulling completed in');
44
+
45
+ await session.awake(undefined);
46
+
47
+ const bar = new SingleBar({}, Presets.shades_classic);
48
+ const feed = new Feed(module.descriptor.storage('feed'));
49
+
50
+ bar.start(100, 0);
51
+
52
+ await session.aggregate.feed({
53
+ instrument: instrumentOf(instrument),
54
+ from,
55
+ to,
56
+ destination: feed,
57
+ callback: timestamp => {
58
+ const duration = to - from;
59
+ const completed = timestamp - from;
60
+
61
+ bar.update(Math.floor((completed / duration) * 100));
62
+ }
63
+ });
64
+
65
+ bar.update(100);
66
+ bar.stop();
67
+
68
+ await session.dispose();
69
+
70
+ console.timeLog('Pulling completed in');
71
+ }
package/src/cli/run.ts ADDED
@@ -0,0 +1,22 @@
1
+ import * as dotenv from 'dotenv';
2
+
3
+ import { Bootstrap } from '../bootstrap';
4
+ import build from './build';
5
+ import { getModule } from './internal/workspace';
6
+
7
+ export default async function (name, options: any) {
8
+ if (await build()) {
9
+ return;
10
+ }
11
+
12
+ dotenv.config();
13
+
14
+ const id = options.id ? Number(options.id) : undefined;
15
+
16
+ const module = await getModule(name);
17
+
18
+ const bootstrap = new Bootstrap(module.descriptor);
19
+ const session = bootstrap.useSessionId(id).live();
20
+
21
+ await session.awake(module.default);
22
+ }
@@ -0,0 +1,53 @@
1
+ import { Bootstrap } from '../bootstrap';
2
+ import build from './build';
3
+ import { getModule } from './internal/workspace';
4
+
5
+ export default async function (name, options: any) {
6
+ if (await build()) {
7
+ return;
8
+ }
9
+
10
+ const module = await getModule(name);
11
+
12
+ const bootstrap = new Bootstrap(module.descriptor);
13
+
14
+ if (!module.descriptor.storage) {
15
+ throw new Error('Please provide a "storage" property in session descriptor.');
16
+ }
17
+
18
+ const from = options.from
19
+ ? Date.parse(options.from)
20
+ : module.descriptor.simulation.from;
21
+
22
+ if (!from) {
23
+ throw new Error(
24
+ 'Please set a "from" date in session descriptor or provide the date as parameter.'
25
+ );
26
+ }
27
+
28
+ const to = options.to ? Date.parse(options.to) : module.descriptor.simulation.to;
29
+
30
+ if (!to) {
31
+ throw new Error(
32
+ 'Please set a "to" date in session descriptor or provide the date as parameter.'
33
+ );
34
+ }
35
+
36
+ await new Promise<void>(async resolve => {
37
+ const [session] = bootstrap.useBacktestPeriod(from, to).backtest({
38
+ onBacktestStarted: () => {
39
+ console.log('backtest started');
40
+ console.time('backtest completed');
41
+ },
42
+ onBacktestCompleted: async () => {
43
+ await session.dispose();
44
+
45
+ console.timeEnd('backtest completed');
46
+
47
+ resolve();
48
+ }
49
+ });
50
+
51
+ await session.awake(module.default);
52
+ });
53
+ }
@@ -1,66 +1,70 @@
1
1
  import { Asset, assetOf } from './asset';
2
2
 
3
- describe('asset tests', () => {
4
- test('should instantiate proper asset', () => {
3
+ describe('Asset', () => {
4
+ test('should construct a new asset', () => {
5
5
  const sut = new Asset('abc', 'xyz', 4);
6
6
 
7
7
  expect(sut.name).toEqual('abc');
8
- expect(sut.adapter).toEqual('xyz');
8
+ expect(sut.adapterName).toEqual('xyz');
9
9
  expect(sut.scale).toEqual(4);
10
10
  expect(sut.tickSize).toEqual(0.0001);
11
11
  expect(sut.fixed(1.1234567)).toEqual(1.1234);
12
12
  expect(sut.floor(1.1234567)).toEqual(1.1234);
13
13
  expect(sut.ceil(1.1234567)).toEqual(1.1235);
14
- expect(sut.toString()).toEqual('xyz:abc');
14
+ expect(sut.id).toEqual('xyz:abc');
15
+ });
16
+
17
+ test('should throw for missing asset name', () => {
18
+ const fn = () => new Asset('xyz', '', 5);
19
+
20
+ expect(fn).toThrowError();
21
+ });
22
+
23
+ test('should throw for missing adapter name', () => {
24
+ const fn = () => new Asset('', 'xyz', 5);
25
+
26
+ expect(fn).toThrowError();
15
27
  });
16
28
  });
17
29
 
18
- describe('asset selector tests', () => {
19
- test('should instantiate proper asset selector', () => {
30
+ describe('AssetSelector', () => {
31
+ test('should construct a new asset selector from unified string', () => {
20
32
  const sut = assetOf('xyz:abc');
21
33
 
22
34
  expect(sut.name).toEqual('abc');
23
- expect(sut.adapter).toEqual('xyz');
24
- expect(sut.toString()).toEqual('xyz:abc');
35
+ expect(sut.adapterName).toEqual('xyz');
36
+ expect(sut.id).toEqual('xyz:abc');
25
37
  });
26
38
 
27
39
  test('should instantiate proper asset selector capital case', () => {
28
40
  const sut = assetOf('XYZ:ABC');
29
41
 
30
42
  expect(sut.name).toEqual('abc');
31
- expect(sut.adapter).toEqual('xyz');
32
- expect(sut.toString()).toEqual('xyz:abc');
43
+ expect(sut.adapterName).toEqual('xyz');
44
+ expect(sut.id).toEqual('xyz:abc');
33
45
  });
34
46
 
35
47
  test('should throw invalid format message for missing separator', () => {
36
- const fn = () => {
37
- assetOf('xyzabc');
38
- };
48
+ const fn = () => assetOf('xyzabc');
39
49
 
40
- expect(fn).toThrow(Error);
50
+ expect(fn).toThrowError();
41
51
  });
42
52
 
43
- test('should throw invalid format message for multiple separators', () => {
44
- const fn = () => {
45
- assetOf('xyz:abc:');
46
- };
53
+ test('should throw for multiple separators', () => {
54
+ const fn = () => assetOf('xyz:abc:');
47
55
 
48
- expect(fn).toThrow(Error);
56
+ expect(fn).toThrowError();
49
57
  });
50
58
 
51
- test('should throw invalid format message for missing asset name', () => {
52
- const fn = () => {
53
- assetOf('xyz:');
54
- };
59
+ test('should throw for missing asset name', () => {
60
+ const fn = () => assetOf('xyz:');
55
61
 
56
- expect(fn).toThrow(Error);
62
+ expect(fn).toThrowError();
57
63
  });
58
64
 
59
- test('should throw invalid format message for missing adapter name', () => {
60
- const fn = () => {
61
- assetOf(':abc');
62
- };
65
+ test('should throw for missing adapter name', () => {
66
+ const fn = () => assetOf(':abc');
63
67
 
64
- expect(fn).toThrow(Error);
68
+ expect(fn).toThrowError();
65
69
  });
66
70
  });
@@ -1,19 +1,28 @@
1
1
  import { ceil, fixed, floor } from '../shared/decimals';
2
+ import { invalidArgumentError, invalidAssetSelectorError } from './error';
3
+
4
+ export const AssetSelectorSeparator = ':';
2
5
 
3
6
  /**
4
7
  * Supposed to query specific @see Asset from based on string notation.
5
8
  */
6
9
  export class AssetSelector {
7
- private readonly id: string;
8
-
10
+ readonly id: string;
9
11
  readonly name: string;
10
- readonly adapter: string;
12
+ readonly adapterName: string;
11
13
 
12
- constructor(name: string, adapter: string) {
13
- this.name = name.toLowerCase();
14
- this.adapter = adapter.toLowerCase();
14
+ constructor(name: string, adapterName: string) {
15
+ if (!name?.length) {
16
+ throw invalidArgumentError(name);
17
+ }
15
18
 
16
- this.id = `${this.adapter}:${this.name}`;
19
+ if (!adapterName?.length) {
20
+ throw invalidArgumentError(adapterName);
21
+ }
22
+
23
+ this.name = name.toLowerCase();
24
+ this.adapterName = adapterName.toLowerCase();
25
+ this.id = `${this.adapterName}${AssetSelectorSeparator}${this.name}`;
17
26
  }
18
27
 
19
28
  /**
@@ -27,21 +36,14 @@ export class AssetSelector {
27
36
  /**
28
37
  * Creates @see AssetSelector based on unified string notation.
29
38
  */
30
- export function assetOf(asset: string): AssetSelector {
31
- const section = asset.split(':');
39
+ export function assetOf(selector: string): AssetSelector {
40
+ const [adapterName, name, ...rest] = selector.split(AssetSelectorSeparator);
32
41
 
33
- if (section.length != 2) {
34
- throw Error('invalid asset format');
42
+ if (!adapterName || !name || rest.length) {
43
+ throw invalidAssetSelectorError(selector);
35
44
  }
36
45
 
37
- const assetName = section[1];
38
- const adapterName = section[0];
39
-
40
- if (assetName.length == 0 || adapterName.length == 0) {
41
- throw Error('invalid asset format');
42
- }
43
-
44
- return new AssetSelector(assetName, adapterName);
46
+ return new AssetSelector(name, adapterName);
45
47
  }
46
48
 
47
49
  /**
@@ -51,8 +53,12 @@ export function assetOf(asset: string): AssetSelector {
51
53
  export class Asset extends AssetSelector {
52
54
  readonly tickSize: number;
53
55
 
54
- constructor(name: string, adapter: string, public readonly scale: number) {
55
- super(name, adapter);
56
+ constructor(name: string, adapterName: string, public readonly scale: number) {
57
+ super(name, adapterName);
58
+
59
+ if (scale && (scale < 0 || Number.isNaN(scale))) {
60
+ throw invalidArgumentError(scale);
61
+ }
56
62
 
57
63
  this.tickSize = 1.0 / Math.pow(10, this.scale);
58
64
  }
@@ -0,0 +1,25 @@
1
+ import { Subject } from 'rxjs';
2
+
3
+ import { State } from '../store';
4
+ import { Asset } from './asset';
5
+ import { Balance } from './balance';
6
+ import { balance } from './balance.operator';
7
+ import { Component } from './component';
8
+
9
+ describe('balance', () => {
10
+ const asset = new Asset('abc', 'xyz', 4);
11
+ const state = new State();
12
+
13
+ beforeEach(() => {
14
+ state.balance.upsert(new Balance(asset));
15
+ });
16
+
17
+ test('should pipe a balance on subscription', done => {
18
+ new Subject<Component>().pipe(balance(asset, state)).subscribe({
19
+ next: it => {
20
+ expect(it.asset).toEqual(asset);
21
+ done();
22
+ }
23
+ });
24
+ });
25
+ });
@@ -0,0 +1,15 @@
1
+ import { filter, map, Observable, startWith } from 'rxjs';
2
+
3
+ import { State } from '../store';
4
+ import { AssetSelector } from './asset';
5
+ import { Balance } from './balance';
6
+ import { Component } from './component';
7
+
8
+ export function balance(selector: AssetSelector, state: State) {
9
+ return (source$: Observable<Component>) =>
10
+ source$.pipe(
11
+ startWith(state.balance.get(selector.id)),
12
+ filter(it => it instanceof Balance && (!selector || it.asset.id == selector.id)),
13
+ map(it => it as Balance)
14
+ );
15
+ }