@quantform/core 0.5.14 → 0.5.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/adapter-aggregate.d.ts +4 -2
- package/dist/adapter/adapter-aggregate.js +16 -18
- package/dist/adapter/adapter-aggregate.js.map +1 -1
- package/dist/adapter/adapter.d.ts +20 -21
- package/dist/adapter/adapter.js +8 -43
- package/dist/adapter/adapter.js.map +1 -1
- package/dist/adapter/backtester/backtester-adapter.d.ts +9 -7
- package/dist/adapter/backtester/backtester-adapter.js +13 -12
- package/dist/adapter/backtester/backtester-adapter.js.map +1 -1
- package/dist/{tests → adapter/backtester}/backtester-adapter.spec.d.ts +0 -0
- package/dist/adapter/backtester/backtester-adapter.spec.js +82 -0
- package/dist/adapter/backtester/backtester-adapter.spec.js.map +1 -0
- package/dist/adapter/backtester/backtester-cursor.d.ts +3 -4
- package/dist/adapter/backtester/backtester-cursor.js +2 -1
- package/dist/adapter/backtester/backtester-cursor.js.map +1 -1
- package/dist/adapter/backtester/backtester-cursor.spec.js +17 -18
- package/dist/adapter/backtester/backtester-cursor.spec.js.map +1 -1
- package/dist/adapter/backtester/backtester-streamer.d.ts +4 -1
- package/dist/adapter/backtester/backtester-streamer.js +39 -18
- package/dist/adapter/backtester/backtester-streamer.js.map +1 -1
- package/dist/adapter/backtester/backtester-streamer.spec.js +13 -13
- package/dist/adapter/backtester/backtester-streamer.spec.js.map +1 -1
- package/dist/adapter/error.d.ts +2 -0
- package/dist/adapter/error.js +12 -0
- package/dist/adapter/error.js.map +1 -0
- package/dist/adapter/paper/engine/paper-engine.d.ts +11 -0
- package/dist/adapter/paper/engine/paper-engine.js +103 -0
- package/dist/adapter/paper/engine/paper-engine.js.map +1 -0
- package/dist/adapter/paper/{simulator/paper-spot-simulator.spec.d.ts → engine/paper-engine.spec.d.ts} +0 -0
- package/dist/adapter/paper/engine/paper-engine.spec.js +54 -0
- package/dist/adapter/paper/engine/paper-engine.spec.js.map +1 -0
- package/dist/adapter/paper/index.d.ts +1 -2
- package/dist/adapter/paper/index.js +1 -2
- package/dist/adapter/paper/index.js.map +1 -1
- package/dist/adapter/paper/paper-adapter.d.ts +7 -7
- package/dist/adapter/paper/paper-adapter.js +20 -18
- package/dist/adapter/paper/paper-adapter.js.map +1 -1
- package/dist/adapter/paper/paper-adapter.spec.js +35 -17
- package/dist/adapter/paper/paper-adapter.spec.js.map +1 -1
- package/dist/bootstrap.js +11 -10
- package/dist/bootstrap.js.map +1 -1
- package/dist/cli/pull.js +3 -1
- package/dist/cli/pull.js.map +1 -1
- package/dist/cli/test.js +5 -1
- package/dist/cli/test.js.map +1 -1
- package/dist/domain/asset.d.ts +6 -5
- package/dist/domain/asset.js +22 -16
- package/dist/domain/asset.js.map +1 -1
- package/dist/domain/asset.spec.js +32 -32
- package/dist/domain/asset.spec.js.map +1 -1
- package/dist/domain/balance.d.ts +7 -7
- package/dist/domain/balance.js +26 -21
- package/dist/domain/balance.js.map +1 -1
- package/dist/domain/balance.operator.d.ts +6 -0
- package/dist/domain/balance.operator.js +10 -0
- package/dist/domain/balance.operator.js.map +1 -0
- package/dist/{shared/policy.spec.d.ts → domain/balance.operator.spec.d.ts} +0 -0
- package/dist/domain/balance.operator.spec.js +23 -0
- package/dist/domain/balance.operator.spec.js.map +1 -0
- package/dist/domain/balance.spec.js +67 -7
- package/dist/domain/balance.spec.js.map +1 -1
- package/dist/domain/candle.d.ts +2 -17
- package/dist/domain/candle.js +3 -70
- package/dist/domain/candle.js.map +1 -1
- package/dist/domain/candle.operator.d.ts +9 -0
- package/dist/domain/candle.operator.js +64 -0
- package/dist/domain/candle.operator.js.map +1 -0
- package/dist/{shared/topic.spec.d.ts → domain/candle.operator.spec.d.ts} +0 -0
- package/dist/domain/candle.operator.spec.js +111 -0
- package/dist/domain/candle.operator.spec.js.map +1 -0
- package/dist/domain/candle.spec.js +11 -53
- package/dist/domain/candle.spec.js.map +1 -1
- package/dist/domain/commission.d.ts +4 -1
- package/dist/domain/commission.js +2 -2
- package/dist/domain/commission.js.map +1 -1
- package/dist/{store/event/store-balance.event.spec.d.ts → domain/commission.spec.d.ts} +0 -0
- package/dist/domain/commission.spec.js +30 -0
- package/dist/domain/commission.spec.js.map +1 -0
- package/dist/domain/component.d.ts +1 -0
- package/dist/domain/error.d.ts +5 -0
- package/dist/domain/error.js +24 -0
- package/dist/domain/error.js.map +1 -0
- package/dist/domain/index.d.ts +8 -1
- package/dist/domain/index.js +8 -1
- package/dist/domain/index.js.map +1 -1
- package/dist/domain/instrument.d.ts +3 -2
- package/dist/domain/instrument.js +17 -9
- package/dist/domain/instrument.js.map +1 -1
- package/dist/domain/instrument.operator.d.ts +6 -0
- package/dist/domain/instrument.operator.js +14 -0
- package/dist/domain/instrument.operator.js.map +1 -0
- package/dist/{store/event/store-candle.event.spec.d.ts → domain/instrument.operator.spec.d.ts} +0 -0
- package/dist/domain/instrument.operator.spec.js +24 -0
- package/dist/domain/instrument.operator.spec.js.map +1 -0
- package/dist/domain/instrument.spec.js +22 -30
- package/dist/domain/instrument.spec.js.map +1 -1
- package/dist/domain/order.d.ts +12 -14
- package/dist/domain/order.js +37 -26
- package/dist/domain/order.js.map +1 -1
- package/dist/domain/order.operator.d.ts +7 -0
- package/dist/domain/order.operator.js +14 -0
- package/dist/domain/order.operator.js.map +1 -0
- package/dist/{store/event/store-instrument.event.spec.d.ts → domain/order.operator.spec.d.ts} +0 -0
- package/dist/domain/order.operator.spec.js +64 -0
- package/dist/domain/order.operator.spec.js.map +1 -0
- package/dist/{store/event/store-order.event.spec.d.ts → domain/order.spec.d.ts} +0 -0
- package/dist/domain/order.spec.js +33 -0
- package/dist/domain/order.spec.js.map +1 -0
- package/dist/domain/orderbook.d.ts +1 -0
- package/dist/domain/orderbook.js +1 -0
- package/dist/domain/orderbook.js.map +1 -1
- package/dist/domain/orderbook.operator.d.ts +6 -0
- package/dist/domain/orderbook.operator.js +10 -0
- package/dist/domain/orderbook.operator.js.map +1 -0
- package/dist/{store/event/store-trade.event.spec.d.ts → domain/orderbook.operator.spec.d.ts} +0 -0
- package/dist/domain/orderbook.operator.spec.js +22 -0
- package/dist/domain/orderbook.operator.spec.js.map +1 -0
- package/dist/domain/orderbook.spec.d.ts +1 -0
- package/dist/domain/orderbook.spec.js +13 -0
- package/dist/domain/orderbook.spec.js.map +1 -0
- package/dist/domain/position.d.ts +6 -11
- package/dist/domain/position.js +9 -31
- package/dist/domain/position.js.map +1 -1
- package/dist/domain/position.operator.d.ts +10 -0
- package/dist/domain/position.operator.js +38 -0
- package/dist/domain/position.operator.js.map +1 -0
- package/dist/domain/position.operator.spec.d.ts +1 -0
- package/dist/domain/position.operator.spec.js +48 -0
- package/dist/domain/position.operator.spec.js.map +1 -0
- package/dist/domain/position.spec.js +21 -17
- package/dist/domain/position.spec.js.map +1 -1
- package/dist/domain/session.d.ts +15 -18
- package/dist/domain/session.js +21 -31
- package/dist/domain/session.js.map +1 -1
- package/dist/domain/session.spec.js +1 -1
- package/dist/domain/session.spec.js.map +1 -1
- package/dist/domain/trade.d.ts +1 -0
- package/dist/domain/trade.js +1 -0
- package/dist/domain/trade.js.map +1 -1
- package/dist/domain/trade.operator.d.ts +6 -0
- package/dist/domain/trade.operator.js +10 -0
- package/dist/domain/trade.operator.js.map +1 -0
- package/dist/domain/trade.operator.spec.d.ts +1 -0
- package/dist/domain/trade.operator.spec.js +24 -0
- package/dist/domain/trade.operator.spec.js.map +1 -0
- package/dist/domain/trade.spec.d.ts +1 -0
- package/dist/domain/trade.spec.js +13 -0
- package/dist/domain/trade.spec.js.map +1 -0
- package/dist/indicator/cross.spec.js +2 -2
- package/dist/indicator/cross.spec.js.map +1 -1
- package/dist/indicator/ema.spec.js +1 -1
- package/dist/indicator/ema.spec.js.map +1 -1
- package/dist/indicator/sma.spec.js +1 -1
- package/dist/indicator/sma.spec.js.map +1 -1
- package/dist/indicator/tma.spec.js +1 -1
- package/dist/indicator/tma.spec.js.map +1 -1
- package/dist/indicator/trailing.spec.js +2 -2
- package/dist/indicator/trailing.spec.js.map +1 -1
- package/dist/indicator/truerange.spec.js +1 -1
- package/dist/indicator/truerange.spec.js.map +1 -1
- package/dist/indicator/wma.spec.js +1 -1
- package/dist/indicator/wma.spec.js.map +1 -1
- package/dist/shared/collections.d.ts +10 -0
- package/dist/shared/collections.js +33 -0
- package/dist/shared/collections.js.map +1 -0
- package/dist/shared/datetime.d.ts +0 -1
- package/dist/shared/datetime.js +1 -12
- package/dist/shared/datetime.js.map +1 -1
- package/dist/shared/decimals.d.ts +1 -1
- package/dist/shared/decimals.js +4 -5
- package/dist/shared/decimals.js.map +1 -1
- package/dist/shared/decimals.spec.js +2 -1
- package/dist/shared/decimals.spec.js.map +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/io.js.map +1 -1
- package/dist/shared/policy.d.ts +0 -1
- package/dist/shared/policy.js +1 -11
- package/dist/shared/policy.js.map +1 -1
- package/dist/storage/cache.js +1 -1
- package/dist/storage/cache.js.map +1 -1
- package/dist/storage/cache.spec.d.ts +1 -0
- package/dist/storage/cache.spec.js +18 -0
- package/dist/storage/cache.spec.js.map +1 -0
- package/dist/storage/feed.d.ts +3 -4
- package/dist/storage/feed.js +16 -6
- package/dist/storage/feed.js.map +1 -1
- package/dist/storage/storage.d.ts +2 -7
- package/dist/storage/storage.js +6 -11
- package/dist/storage/storage.js.map +1 -1
- package/dist/store/index.d.ts +8 -2
- package/dist/store/index.js +8 -2
- package/dist/store/index.js.map +1 -1
- package/dist/store/store-balance.event.d.ts +33 -0
- package/dist/store/store-balance.event.js +90 -0
- package/dist/store/store-balance.event.js.map +1 -0
- package/dist/store/store-balance.event.spec.d.ts +1 -0
- package/dist/store/{event/store-balance.event.spec.js → store-balance.event.spec.js} +7 -7
- package/dist/store/store-balance.event.spec.js.map +1 -0
- package/dist/store/{event/store-instrument.event.d.ts → store-instrument.event.d.ts} +5 -8
- package/dist/store/store-instrument.event.js +52 -0
- package/dist/store/store-instrument.event.js.map +1 -0
- package/dist/store/store-instrument.event.spec.d.ts +1 -0
- package/dist/store/store-instrument.event.spec.js +22 -0
- package/dist/store/store-instrument.event.spec.js.map +1 -0
- package/dist/store/store-order.event.d.ts +59 -0
- package/dist/store/store-order.event.js +181 -0
- package/dist/store/store-order.event.js.map +1 -0
- package/dist/store/store-order.event.spec.d.ts +1 -0
- package/dist/store/{event/store-order.event.spec.js → store-order.event.spec.js} +8 -8
- package/dist/store/store-order.event.spec.js.map +1 -0
- package/dist/store/{event/store-orderbook.event.d.ts → store-orderbook.event.d.ts} +4 -5
- package/dist/store/store-orderbook.event.js +42 -0
- package/dist/store/store-orderbook.event.js.map +1 -0
- package/dist/store/{event/store-position.event.d.ts → store-position.event.d.ts} +5 -7
- package/dist/store/store-position.event.js +77 -0
- package/dist/store/store-position.event.js.map +1 -0
- package/dist/store/store-state.d.ts +27 -0
- package/dist/store/store-state.js +29 -0
- package/dist/store/store-state.js.map +1 -0
- package/dist/store/{event/store-trade.event.d.ts → store-trade.event.d.ts} +4 -5
- package/dist/store/store-trade.event.js +25 -0
- package/dist/store/store-trade.event.js.map +1 -0
- package/dist/store/store-trade.event.spec.d.ts +1 -0
- package/dist/store/{event/store-trade.event.spec.js → store-trade.event.spec.js} +13 -13
- package/dist/store/store-trade.event.spec.js.map +1 -0
- package/dist/store/store.d.ts +4 -25
- package/dist/store/store.event.d.ts +6 -0
- package/dist/store/{event/store.event.js → store.event.js} +0 -0
- package/dist/store/store.event.js.map +1 -0
- package/dist/store/store.js +7 -195
- package/dist/store/store.js.map +1 -1
- package/dist/store/store.spec.d.ts +1 -0
- package/dist/store/store.spec.js +119 -0
- package/dist/store/store.spec.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/{jestconfig.unit.json → jestconfig.json} +1 -2
- package/package.json +2 -6
- package/src/adapter/adapter-aggregate.ts +27 -35
- package/src/adapter/adapter.ts +25 -54
- package/src/adapter/backtester/backtester-adapter.spec.ts +124 -0
- package/src/adapter/backtester/backtester-adapter.ts +28 -17
- package/src/adapter/backtester/backtester-cursor.spec.ts +18 -19
- package/src/adapter/backtester/backtester-cursor.ts +7 -7
- package/src/adapter/backtester/backtester-streamer.spec.ts +19 -19
- package/src/adapter/backtester/backtester-streamer.ts +50 -20
- package/src/adapter/error.ts +9 -0
- package/src/adapter/paper/engine/paper-engine.spec.ts +92 -0
- package/src/adapter/paper/engine/paper-engine.ts +135 -0
- package/src/adapter/paper/index.ts +1 -2
- package/src/adapter/paper/paper-adapter.spec.ts +55 -19
- package/src/adapter/paper/paper-adapter.ts +27 -24
- package/src/bootstrap.ts +26 -19
- package/src/cli/pull.ts +5 -1
- package/src/cli/test.ts +5 -2
- package/src/domain/asset.spec.ts +33 -29
- package/src/domain/asset.ts +27 -21
- package/src/domain/balance.operator.spec.ts +25 -0
- package/src/domain/balance.operator.ts +15 -0
- package/src/domain/balance.spec.ts +95 -7
- package/src/domain/balance.ts +35 -29
- package/src/domain/candle.operator.spec.ts +125 -0
- package/src/domain/candle.operator.ts +106 -0
- package/src/domain/candle.spec.ts +12 -68
- package/src/domain/candle.ts +2 -114
- package/src/domain/commission.spec.ts +33 -0
- package/src/domain/commission.ts +2 -2
- package/src/domain/component.ts +1 -0
- package/src/domain/error.ts +25 -0
- package/src/domain/index.ts +8 -1
- package/src/domain/instrument.operator.spec.ts +28 -0
- package/src/domain/instrument.operator.ts +25 -0
- package/src/domain/instrument.spec.ts +22 -30
- package/src/domain/instrument.ts +20 -11
- package/src/domain/order.operator.spec.ts +81 -0
- package/src/domain/order.operator.ts +23 -0
- package/src/domain/order.spec.ts +43 -0
- package/src/domain/order.ts +43 -46
- package/src/domain/orderbook.operator.spec.ts +28 -0
- package/src/domain/orderbook.operator.ts +15 -0
- package/src/domain/orderbook.spec.ts +17 -0
- package/src/domain/orderbook.ts +4 -1
- package/src/domain/position.operator.spec.ts +58 -0
- package/src/domain/position.operator.ts +61 -0
- package/src/domain/position.spec.ts +28 -24
- package/src/domain/position.ts +16 -48
- package/src/domain/session.spec.ts +1 -1
- package/src/domain/session.ts +41 -131
- package/src/domain/trade.operator.spec.ts +31 -0
- package/src/domain/trade.operator.ts +15 -0
- package/src/domain/trade.spec.ts +17 -0
- package/src/domain/trade.ts +4 -1
- package/src/indicator/cross.spec.ts +2 -2
- package/src/indicator/ema.spec.ts +1 -1
- package/src/indicator/sma.spec.ts +1 -1
- package/src/indicator/tma.spec.ts +1 -1
- package/src/indicator/trailing.spec.ts +2 -2
- package/src/indicator/truerange.spec.ts +1 -1
- package/src/indicator/wma.spec.ts +1 -1
- package/src/shared/collections.ts +35 -0
- package/src/shared/datetime.ts +0 -12
- package/src/shared/decimals.spec.ts +2 -1
- package/src/shared/decimals.ts +6 -6
- package/src/shared/index.ts +1 -1
- package/src/shared/io.ts +0 -2
- package/src/shared/policy.ts +0 -13
- package/src/storage/cache.spec.ts +18 -0
- package/src/storage/cache.ts +1 -1
- package/src/storage/feed.ts +26 -16
- package/src/storage/storage.ts +9 -13
- package/src/store/index.ts +8 -2
- package/src/store/{event/store-balance.event.spec.ts → store-balance.event.spec.ts} +6 -6
- package/src/store/store-balance.event.ts +124 -0
- package/src/store/store-instrument.event.spec.ts +25 -0
- package/src/store/store-instrument.event.ts +72 -0
- package/src/store/store-order.event.spec.ts +28 -0
- package/src/store/store-order.event.ts +214 -0
- package/src/store/store-orderbook.event.ts +54 -0
- package/src/store/store-position.event.ts +102 -0
- package/src/store/store-state.ts +48 -0
- package/src/store/{event/store-trade.event.spec.ts → store-trade.event.spec.ts} +14 -14
- package/src/store/store-trade.event.ts +36 -0
- package/src/store/store.event.ts +8 -0
- package/src/store/store.spec.ts +180 -0
- package/src/store/store.ts +10 -208
- package/dist/adapter/paper/simulator/paper-margin-simulator.d.ts +0 -10
- package/dist/adapter/paper/simulator/paper-margin-simulator.js +0 -69
- package/dist/adapter/paper/simulator/paper-margin-simulator.js.map +0 -1
- package/dist/adapter/paper/simulator/paper-simulator.d.ts +0 -16
- package/dist/adapter/paper/simulator/paper-simulator.js +0 -93
- package/dist/adapter/paper/simulator/paper-simulator.js.map +0 -1
- package/dist/adapter/paper/simulator/paper-spot-simulator.d.ts +0 -13
- package/dist/adapter/paper/simulator/paper-spot-simulator.js +0 -81
- package/dist/adapter/paper/simulator/paper-spot-simulator.js.map +0 -1
- package/dist/adapter/paper/simulator/paper-spot-simulator.spec.js +0 -49
- package/dist/adapter/paper/simulator/paper-spot-simulator.spec.js.map +0 -1
- package/dist/domain/statement.d.ts +0 -4
- package/dist/domain/statement.js +0 -87
- package/dist/domain/statement.js.map +0 -1
- package/dist/shared/policy.spec.js +0 -22
- package/dist/shared/policy.spec.js.map +0 -1
- package/dist/shared/topic.d.ts +0 -14
- package/dist/shared/topic.js +0 -40
- package/dist/shared/topic.js.map +0 -1
- package/dist/shared/topic.spec.js +0 -43
- package/dist/shared/topic.spec.js.map +0 -1
- package/dist/store/event/index.d.ts +0 -8
- package/dist/store/event/index.js +0 -25
- package/dist/store/event/index.js.map +0 -1
- package/dist/store/event/store-balance.event.d.ts +0 -37
- package/dist/store/event/store-balance.event.js +0 -119
- package/dist/store/event/store-balance.event.js.map +0 -1
- package/dist/store/event/store-balance.event.spec.js.map +0 -1
- package/dist/store/event/store-candle.event.d.ts +0 -18
- package/dist/store/event/store-candle.event.js +0 -63
- package/dist/store/event/store-candle.event.js.map +0 -1
- package/dist/store/event/store-candle.event.spec.js +0 -23
- package/dist/store/event/store-candle.event.spec.js.map +0 -1
- package/dist/store/event/store-instrument.event.js +0 -78
- package/dist/store/event/store-instrument.event.js.map +0 -1
- package/dist/store/event/store-instrument.event.spec.js +0 -21
- package/dist/store/event/store-instrument.event.spec.js.map +0 -1
- package/dist/store/event/store-order.event.d.ts +0 -61
- package/dist/store/event/store-order.event.js +0 -205
- package/dist/store/event/store-order.event.js.map +0 -1
- package/dist/store/event/store-order.event.spec.js.map +0 -1
- package/dist/store/event/store-orderbook.event.js +0 -65
- package/dist/store/event/store-orderbook.event.js.map +0 -1
- package/dist/store/event/store-position.event.js +0 -97
- package/dist/store/event/store-position.event.js.map +0 -1
- package/dist/store/event/store-trade.event.js +0 -47
- package/dist/store/event/store-trade.event.js.map +0 -1
- package/dist/store/event/store-trade.event.spec.js.map +0 -1
- package/dist/store/event/store.event.d.ts +0 -5
- package/dist/store/event/store.event.js.map +0 -1
- package/dist/store/store.state.d.ts +0 -21
- package/dist/store/store.state.js +0 -21
- package/dist/store/store.state.js.map +0 -1
- package/dist/tests/backtester-adapter.spec.js +0 -61
- package/dist/tests/backtester-adapter.spec.js.map +0 -1
- package/dist/tests/session.spec.d.ts +0 -0
- package/dist/tests/session.spec.js +0 -1
- package/dist/tests/session.spec.js.map +0 -1
- package/jestconfig.integration.json +0 -12
- package/src/adapter/paper/simulator/paper-margin-simulator.ts +0 -108
- package/src/adapter/paper/simulator/paper-simulator.ts +0 -121
- package/src/adapter/paper/simulator/paper-spot-simulator.spec.ts +0 -87
- package/src/adapter/paper/simulator/paper-spot-simulator.ts +0 -134
- package/src/domain/statement.ts +0 -119
- package/src/shared/policy.spec.ts +0 -25
- package/src/shared/topic.spec.ts +0 -34
- package/src/shared/topic.ts +0 -43
- package/src/store/event/index.ts +0 -8
- package/src/store/event/store-balance.event.ts +0 -161
- package/src/store/event/store-candle.event.spec.ts +0 -30
- package/src/store/event/store-candle.event.ts +0 -71
- package/src/store/event/store-instrument.event.spec.ts +0 -25
- package/src/store/event/store-instrument.event.ts +0 -84
- package/src/store/event/store-order.event.spec.ts +0 -28
- package/src/store/event/store-order.event.ts +0 -218
- package/src/store/event/store-orderbook.event.ts +0 -70
- package/src/store/event/store-position.event.ts +0 -109
- package/src/store/event/store-trade.event.ts +0 -52
- package/src/store/event/store.event.ts +0 -6
- package/src/store/store.state.ts +0 -43
- package/src/tests/backtester-adapter.spec.ts +0 -88
- package/src/tests/session.spec.ts +0 -121
package/src/storage/feed.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { InstrumentSelector } from '../domain';
|
|
1
|
+
import { Candle, InstrumentSelector } from '../domain';
|
|
2
2
|
import { StoreEvent } from '../store';
|
|
3
3
|
import { Storage, StorageQueryOptions } from './storage';
|
|
4
4
|
|
|
@@ -19,18 +19,22 @@ export class Feed {
|
|
|
19
19
|
/**
|
|
20
20
|
*
|
|
21
21
|
* @param instrument
|
|
22
|
-
* @param
|
|
22
|
+
* @param candles
|
|
23
23
|
* @returns
|
|
24
24
|
*/
|
|
25
|
-
save(instrument: InstrumentSelector,
|
|
25
|
+
save(instrument: InstrumentSelector, candles: Candle[]): Promise<void> {
|
|
26
26
|
return this.storage.save(
|
|
27
27
|
instrument.toString(),
|
|
28
|
-
|
|
28
|
+
candles.map(it => ({
|
|
29
29
|
timestamp: it.timestamp,
|
|
30
|
-
kind:
|
|
31
|
-
json: JSON.stringify(
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
kind: 'candle',
|
|
31
|
+
json: JSON.stringify({
|
|
32
|
+
o: it.open,
|
|
33
|
+
h: it.high,
|
|
34
|
+
l: it.low,
|
|
35
|
+
c: it.close,
|
|
36
|
+
v: it.volume
|
|
37
|
+
})
|
|
34
38
|
}))
|
|
35
39
|
);
|
|
36
40
|
}
|
|
@@ -44,14 +48,20 @@ export class Feed {
|
|
|
44
48
|
async query(
|
|
45
49
|
instrument: InstrumentSelector,
|
|
46
50
|
options: StorageQueryOptions
|
|
47
|
-
): Promise<
|
|
48
|
-
const rows = await this.storage.query(instrument.
|
|
51
|
+
): Promise<Candle[]> {
|
|
52
|
+
const rows = await this.storage.query(instrument.id, options);
|
|
49
53
|
|
|
50
|
-
return rows.map(it =>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
return rows.map(it => {
|
|
55
|
+
const payload = JSON.parse(it.json);
|
|
56
|
+
|
|
57
|
+
return new Candle(
|
|
58
|
+
it.timestamp,
|
|
59
|
+
payload.o,
|
|
60
|
+
payload.h,
|
|
61
|
+
payload.l,
|
|
62
|
+
payload.c,
|
|
63
|
+
payload.v
|
|
64
|
+
);
|
|
65
|
+
});
|
|
56
66
|
}
|
|
57
67
|
}
|
package/src/storage/storage.ts
CHANGED
|
@@ -11,6 +11,11 @@ export type StorageQueryOptions = {
|
|
|
11
11
|
count: number;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
export type StorageFactory = (type: string) => Storage;
|
|
18
|
+
|
|
14
19
|
/**
|
|
15
20
|
*
|
|
16
21
|
*/
|
|
@@ -35,11 +40,10 @@ export interface Storage {
|
|
|
35
40
|
query(library: string, options: StorageQueryOptions): Promise<StorageDocument[]>;
|
|
36
41
|
}
|
|
37
42
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
create(type: string): Storage;
|
|
43
|
+
export function inMemoryStorageFactory(): StorageFactory {
|
|
44
|
+
const storage: Record<string, Storage> = {};
|
|
45
|
+
|
|
46
|
+
return (type: string) => storage[type] ?? (storage[type] = new InMemoryStorage());
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
/**
|
|
@@ -118,11 +122,3 @@ export class InMemoryStorage implements Storage {
|
|
|
118
122
|
this.tables = {};
|
|
119
123
|
}
|
|
120
124
|
}
|
|
121
|
-
|
|
122
|
-
export class InMemoryStorageFactory implements StorageFactory {
|
|
123
|
-
private readonly storage: Record<string, Storage> = {};
|
|
124
|
-
|
|
125
|
-
create(type: string): Storage {
|
|
126
|
-
return this.storage[type] ?? (this.storage[type] = new InMemoryStorage());
|
|
127
|
-
}
|
|
128
|
-
}
|
package/src/store/index.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
export * from './event';
|
|
2
1
|
export * from './store';
|
|
3
|
-
export * from './store
|
|
2
|
+
export * from './store-state';
|
|
3
|
+
export * from './store-balance.event';
|
|
4
|
+
export * from './store-instrument.event';
|
|
5
|
+
export * from './store-order.event';
|
|
6
|
+
export * from './store-orderbook.event';
|
|
7
|
+
export * from './store-position.event';
|
|
8
|
+
export * from './store-trade.event';
|
|
9
|
+
export * from './store.event';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Asset, Commission } from '
|
|
2
|
-
import { now } from '
|
|
3
|
-
import { Store } from '
|
|
4
|
-
import { BalancePatchEvent } from '.';
|
|
1
|
+
import { Asset, Commission } from '../domain';
|
|
2
|
+
import { now } from '../shared';
|
|
3
|
+
import { Store } from '.';
|
|
4
|
+
import { BalancePatchEvent } from './store-balance.event';
|
|
5
5
|
import { InstrumentPatchEvent } from './store-instrument.event';
|
|
6
6
|
|
|
7
|
-
describe('
|
|
7
|
+
describe('BalancePatchEvent', () => {
|
|
8
8
|
test('should patch a store', () => {
|
|
9
9
|
const base = new Asset('de30', 'cex', 2);
|
|
10
10
|
const quote = new Asset('usd', 'cex', 2);
|
|
@@ -19,7 +19,7 @@ describe('balance event tests', () => {
|
|
|
19
19
|
);
|
|
20
20
|
store.dispatch(new BalancePatchEvent(base, 100, 0, timestamp));
|
|
21
21
|
|
|
22
|
-
const balance = store.snapshot.balance
|
|
22
|
+
const balance = store.snapshot.balance.get(base.id);
|
|
23
23
|
|
|
24
24
|
expect(balance).toEqual(component);
|
|
25
25
|
expect(balance.free).toEqual(100);
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { AssetSelector, Balance, InstrumentSelector } from '../domain';
|
|
2
|
+
import { timestamp } from '../shared';
|
|
3
|
+
import { StoreEvent } from './store.event';
|
|
4
|
+
import { State, StateChangeTracker } from './store-state';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Updates the free and freezed balance of the given asset.
|
|
8
|
+
*/
|
|
9
|
+
export class BalancePatchEvent implements StoreEvent {
|
|
10
|
+
constructor(
|
|
11
|
+
readonly asset: AssetSelector,
|
|
12
|
+
readonly free: number,
|
|
13
|
+
readonly freezed: number,
|
|
14
|
+
readonly timestamp: timestamp
|
|
15
|
+
) {}
|
|
16
|
+
|
|
17
|
+
handle(state: State, changes: StateChangeTracker) {
|
|
18
|
+
// you can have not tradeable assets in wallet, skip them.
|
|
19
|
+
const asset = state.universe.asset.get(this.asset.id);
|
|
20
|
+
if (!asset) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const balance = state.balance.tryGetOrSet(this.asset.id, () => new Balance(asset));
|
|
25
|
+
|
|
26
|
+
balance.timestamp = this.timestamp;
|
|
27
|
+
balance.set(this.free, this.freezed);
|
|
28
|
+
|
|
29
|
+
state.timestamp = this.timestamp;
|
|
30
|
+
|
|
31
|
+
changes.commit(balance);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
export class BalanceTransactEvent implements StoreEvent {
|
|
38
|
+
constructor(
|
|
39
|
+
readonly asset: AssetSelector,
|
|
40
|
+
readonly amount: number,
|
|
41
|
+
readonly timestamp: timestamp
|
|
42
|
+
) {}
|
|
43
|
+
|
|
44
|
+
handle(state: State, changes: StateChangeTracker) {
|
|
45
|
+
const balance = state.balance.tryGetOrSet(this.asset.id, () => {
|
|
46
|
+
const asset = state.universe.asset.get(this.asset.id);
|
|
47
|
+
|
|
48
|
+
return new Balance(asset);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
balance.timestamp = this.timestamp;
|
|
52
|
+
balance.account(this.amount);
|
|
53
|
+
|
|
54
|
+
state.timestamp = this.timestamp;
|
|
55
|
+
|
|
56
|
+
changes.commit(balance);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
*
|
|
62
|
+
*/
|
|
63
|
+
export class BalanceLockOrderEvent implements StoreEvent {
|
|
64
|
+
constructor(
|
|
65
|
+
readonly orderId: string,
|
|
66
|
+
readonly instrument: InstrumentSelector,
|
|
67
|
+
readonly timestamp: timestamp
|
|
68
|
+
) {}
|
|
69
|
+
|
|
70
|
+
handle(state: State, changes: StateChangeTracker) {
|
|
71
|
+
const order = state.order.get(this.instrument.id).get(this.orderId);
|
|
72
|
+
const base = state.balance.get(order.instrument.base.id);
|
|
73
|
+
const quote = state.balance.get(order.instrument.quote.id);
|
|
74
|
+
|
|
75
|
+
const balanceToLock = order.calculateBalanceToLock(base, quote);
|
|
76
|
+
|
|
77
|
+
state.timestamp = this.timestamp;
|
|
78
|
+
|
|
79
|
+
if (balanceToLock.base > 0) {
|
|
80
|
+
base.timestamp = this.timestamp;
|
|
81
|
+
base.lock(this.orderId, balanceToLock.base);
|
|
82
|
+
|
|
83
|
+
changes.commit(base);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (balanceToLock.quote > 0) {
|
|
87
|
+
quote.timestamp = this.timestamp;
|
|
88
|
+
quote.lock(this.orderId, balanceToLock.quote);
|
|
89
|
+
|
|
90
|
+
changes.commit(quote);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
*
|
|
97
|
+
*/
|
|
98
|
+
export class BalanceUnlockOrderEvent implements StoreEvent {
|
|
99
|
+
constructor(
|
|
100
|
+
readonly orderId: string,
|
|
101
|
+
readonly instrument: InstrumentSelector,
|
|
102
|
+
readonly timestamp: timestamp
|
|
103
|
+
) {}
|
|
104
|
+
|
|
105
|
+
handle(state: State, changes: StateChangeTracker) {
|
|
106
|
+
const order = state.order.get(this.instrument.id).get(this.orderId);
|
|
107
|
+
const base = state.balance.get(order.instrument.base.id);
|
|
108
|
+
const quote = state.balance.get(order.instrument.quote.id);
|
|
109
|
+
|
|
110
|
+
state.timestamp = this.timestamp;
|
|
111
|
+
|
|
112
|
+
if (base.tryUnlock(this.orderId)) {
|
|
113
|
+
base.timestamp = this.timestamp;
|
|
114
|
+
|
|
115
|
+
changes.commit(base);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (quote.tryUnlock(this.orderId)) {
|
|
119
|
+
quote.timestamp = this.timestamp;
|
|
120
|
+
|
|
121
|
+
changes.commit(quote);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Store } from '..';
|
|
2
|
+
import { Asset, Commission } from '../domain';
|
|
3
|
+
import { now } from '../shared';
|
|
4
|
+
import { InstrumentPatchEvent } from './store-instrument.event';
|
|
5
|
+
|
|
6
|
+
describe('InstrumentPatchEvent', () => {
|
|
7
|
+
test('should patch a store', () => {
|
|
8
|
+
const timestamp = now();
|
|
9
|
+
const store = new Store();
|
|
10
|
+
const base = new Asset('de30', 'cex', 2);
|
|
11
|
+
const quote = new Asset('usd', 'cex', 2);
|
|
12
|
+
|
|
13
|
+
store.dispatch(
|
|
14
|
+
new InstrumentPatchEvent(timestamp, base, quote, new Commission(0, 0), '')
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
const { universe } = store.snapshot;
|
|
18
|
+
|
|
19
|
+
expect(universe.instrument.get('cex:de30-usd').base).toEqual(base);
|
|
20
|
+
expect(universe.instrument.get('cex:de30-usd').quote).toEqual(quote);
|
|
21
|
+
expect(universe.instrument.get('cex:de30-usd').timestamp).toEqual(timestamp);
|
|
22
|
+
expect(universe.instrument.asReadonlyArray().length).toEqual(1);
|
|
23
|
+
expect(universe.asset.asReadonlyArray().length).toEqual(2);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Asset, Commission, InstrumentSelector, Instrument } from '../domain';
|
|
2
|
+
import { timestamp } from '../shared';
|
|
3
|
+
import { State, StateChangeTracker } from '../store';
|
|
4
|
+
import { InnerSet } from './store-state';
|
|
5
|
+
import { StoreEvent } from './store.event';
|
|
6
|
+
|
|
7
|
+
export class InstrumentPatchEvent implements StoreEvent {
|
|
8
|
+
constructor(
|
|
9
|
+
readonly timestamp: timestamp,
|
|
10
|
+
readonly base: Asset,
|
|
11
|
+
readonly quote: Asset,
|
|
12
|
+
readonly commission: Commission,
|
|
13
|
+
readonly raw: string,
|
|
14
|
+
readonly leverage?: number
|
|
15
|
+
) {}
|
|
16
|
+
|
|
17
|
+
handle(state: State, changes: StateChangeTracker): void {
|
|
18
|
+
const selector = new InstrumentSelector(
|
|
19
|
+
this.base.name,
|
|
20
|
+
this.quote.name,
|
|
21
|
+
this.base.adapterName
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const instrument = state.universe.instrument.tryGetOrSet(selector.id, () => {
|
|
25
|
+
state.universe.asset.tryGetOrSet(
|
|
26
|
+
this.base.id,
|
|
27
|
+
() => new Asset(this.base.name, this.base.adapterName, 8)
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
state.universe.asset.tryGetOrSet(
|
|
31
|
+
this.quote.id,
|
|
32
|
+
() => new Asset(this.quote.name, this.quote.adapterName, 8)
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
state.order.tryGetOrSet(selector.id, () => new InnerSet(selector.id));
|
|
36
|
+
|
|
37
|
+
return new Instrument(this.base, this.quote, this.raw);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
instrument.timestamp = this.timestamp;
|
|
41
|
+
instrument.commission = this.commission;
|
|
42
|
+
|
|
43
|
+
if (this.leverage) {
|
|
44
|
+
instrument.leverage = this.leverage;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
changes.commit(instrument);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export class InstrumentSubscriptionEvent implements StoreEvent {
|
|
52
|
+
constructor(
|
|
53
|
+
readonly timestamp: timestamp,
|
|
54
|
+
readonly instrument: InstrumentSelector,
|
|
55
|
+
readonly subscribed: boolean
|
|
56
|
+
) {}
|
|
57
|
+
|
|
58
|
+
handle(state: State, changes: StateChangeTracker): void {
|
|
59
|
+
const instrument = state.universe.instrument.get(this.instrument.id);
|
|
60
|
+
if (!instrument) {
|
|
61
|
+
throw new Error('invalid instrument');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (this.subscribed) {
|
|
65
|
+
state.subscription.instrument.upsert(instrument);
|
|
66
|
+
state.subscription.asset.upsert(state.universe.asset.get(instrument.base.id));
|
|
67
|
+
state.subscription.asset.upsert(state.universe.asset.get(instrument.quote.id));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
changes.commit(instrument);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Asset, Instrument, Order } from '../domain';
|
|
2
|
+
import { now } from '../shared';
|
|
3
|
+
import { Store } from '../store';
|
|
4
|
+
import { OrderLoadEvent } from './store-order.event';
|
|
5
|
+
|
|
6
|
+
const instrument = new Instrument(
|
|
7
|
+
new Asset('btc', 'binance', 8),
|
|
8
|
+
new Asset('usdt', 'binance', 2),
|
|
9
|
+
'binance:btc-usdt'
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
describe('OrderLoadEvent', () => {
|
|
13
|
+
test('should load order to store', () => {
|
|
14
|
+
const timestamp = now();
|
|
15
|
+
const store = new Store();
|
|
16
|
+
const order = Order.market(instrument, 1.0);
|
|
17
|
+
|
|
18
|
+
order.state = 'PENDING';
|
|
19
|
+
|
|
20
|
+
store.snapshot.universe.instrument.upsert(instrument);
|
|
21
|
+
store.snapshot.subscription.instrument.upsert(instrument);
|
|
22
|
+
|
|
23
|
+
store.dispatch(new OrderLoadEvent(order, timestamp));
|
|
24
|
+
|
|
25
|
+
expect(store.snapshot.order.asReadonlyArray().length).toEqual(1);
|
|
26
|
+
expect(store.snapshot.order.get(instrument.id).get(order.id)).toEqual(order);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { InstrumentSelector, Order } from '../domain';
|
|
2
|
+
import { timestamp } from '../shared';
|
|
3
|
+
import { StoreEvent } from './store.event';
|
|
4
|
+
import { InnerSet, State, StateChangeTracker } from './store-state';
|
|
5
|
+
|
|
6
|
+
export class OrderLoadEvent implements StoreEvent {
|
|
7
|
+
constructor(readonly order: Order, readonly timestamp: timestamp) {}
|
|
8
|
+
|
|
9
|
+
handle(state: State, changes: StateChangeTracker): void {
|
|
10
|
+
this.order.timestamp = this.timestamp;
|
|
11
|
+
|
|
12
|
+
const orderByInstrument = state.order.tryGetOrSet(
|
|
13
|
+
this.order.instrument.id,
|
|
14
|
+
() => new InnerSet<Order>(this.order.instrument.id)
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
orderByInstrument.upsert(this.order);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class OrderNewEvent implements StoreEvent {
|
|
22
|
+
constructor(readonly order: Order, readonly timestamp: timestamp) {}
|
|
23
|
+
|
|
24
|
+
handle(state: State, changes: StateChangeTracker): void {
|
|
25
|
+
if (this.order.state != 'NEW') {
|
|
26
|
+
throw new Error(`Order is not new`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
this.order.createdAt = this.timestamp;
|
|
30
|
+
this.order.timestamp = this.timestamp;
|
|
31
|
+
|
|
32
|
+
const orderByInstrument = state.order.tryGetOrSet(
|
|
33
|
+
this.order.instrument.id,
|
|
34
|
+
() => new InnerSet<Order>(this.order.instrument.id)
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
orderByInstrument.upsert(this.order);
|
|
38
|
+
|
|
39
|
+
changes.commit(this.order);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export class OrderPendingEvent implements StoreEvent {
|
|
44
|
+
constructor(
|
|
45
|
+
readonly id: string,
|
|
46
|
+
readonly instrument: InstrumentSelector,
|
|
47
|
+
readonly timestamp: timestamp
|
|
48
|
+
) {}
|
|
49
|
+
|
|
50
|
+
handle(state: State, changes: StateChangeTracker): void {
|
|
51
|
+
const order = state.order
|
|
52
|
+
.tryGetOrSet(this.instrument.id, () => {
|
|
53
|
+
throw new Error(`Trying to patch unknown order: ${this.id}`);
|
|
54
|
+
})
|
|
55
|
+
.tryGetOrSet(this.id, () => {
|
|
56
|
+
throw new Error(`Trying to patch unknown order: ${this.id}`);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
if (order.state != 'NEW') {
|
|
60
|
+
throw new Error(`Order is not NEW: ${order.state}`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
order.state = 'PENDING';
|
|
64
|
+
order.timestamp = this.timestamp;
|
|
65
|
+
|
|
66
|
+
changes.commit(order);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export class OrderFilledEvent implements StoreEvent {
|
|
71
|
+
constructor(
|
|
72
|
+
readonly id: string,
|
|
73
|
+
readonly instrument: InstrumentSelector,
|
|
74
|
+
readonly averageExecutionRate: number,
|
|
75
|
+
readonly timestamp: timestamp
|
|
76
|
+
) {}
|
|
77
|
+
|
|
78
|
+
handle(state: State, changes: StateChangeTracker): void {
|
|
79
|
+
const order = state.order
|
|
80
|
+
.tryGetOrSet(this.instrument.id, () => {
|
|
81
|
+
throw new Error(`Trying to patch unknown order: ${this.id}`);
|
|
82
|
+
})
|
|
83
|
+
.tryGetOrSet(this.id, () => {
|
|
84
|
+
throw new Error(`Trying to patch unknown order: ${this.id}`);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
if (order.state != 'PENDING' && order.state != 'CANCELING') {
|
|
88
|
+
throw new Error(`Order is not PENDING or CANCELING: ${order.state}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
order.state = 'FILLED';
|
|
92
|
+
order.timestamp = this.timestamp;
|
|
93
|
+
order.quantityExecuted = order.quantity;
|
|
94
|
+
order.averageExecutionRate = this.averageExecutionRate;
|
|
95
|
+
|
|
96
|
+
changes.commit(order);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export class OrderCancelingEvent implements StoreEvent {
|
|
101
|
+
constructor(
|
|
102
|
+
readonly id: string,
|
|
103
|
+
readonly instrument: InstrumentSelector,
|
|
104
|
+
readonly timestamp: timestamp
|
|
105
|
+
) {}
|
|
106
|
+
|
|
107
|
+
handle(state: State, changes: StateChangeTracker): void {
|
|
108
|
+
const order = state.order
|
|
109
|
+
.tryGetOrSet(this.instrument.id, () => {
|
|
110
|
+
throw new Error(`Trying to patch unknown order: ${this.id}`);
|
|
111
|
+
})
|
|
112
|
+
.tryGetOrSet(this.id, () => {
|
|
113
|
+
throw new Error(`Trying to patch unknown order: ${this.id}`);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
if (order.state == 'CANCELING' || order.state == 'CANCELED') {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (order.state != 'PENDING') {
|
|
121
|
+
throw new Error(`Order is not PENDING: ${order.state}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
order.state = 'CANCELING';
|
|
125
|
+
order.timestamp = this.timestamp;
|
|
126
|
+
|
|
127
|
+
changes.commit(order);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export class OrderCanceledEvent implements StoreEvent {
|
|
132
|
+
constructor(
|
|
133
|
+
readonly id: string,
|
|
134
|
+
readonly instrument: InstrumentSelector,
|
|
135
|
+
readonly timestamp: timestamp
|
|
136
|
+
) {}
|
|
137
|
+
|
|
138
|
+
handle(state: State, changes: StateChangeTracker): void {
|
|
139
|
+
const order = state.order
|
|
140
|
+
.tryGetOrSet(this.instrument.id, () => {
|
|
141
|
+
throw new Error(`Trying to patch unknown order: ${this.id}`);
|
|
142
|
+
})
|
|
143
|
+
.tryGetOrSet(this.id, () => {
|
|
144
|
+
throw new Error(`Trying to patch unknown order: ${this.id}`);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
if (order.state == 'CANCELED') {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (order.state != 'CANCELING') {
|
|
152
|
+
throw new Error(`Order is not CANCELING: ${order.state}`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
order.state = 'CANCELED';
|
|
156
|
+
order.timestamp = this.timestamp;
|
|
157
|
+
|
|
158
|
+
changes.commit(order);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export class OrderCancelFailedEvent implements StoreEvent {
|
|
163
|
+
constructor(
|
|
164
|
+
readonly id: string,
|
|
165
|
+
readonly instrument: InstrumentSelector,
|
|
166
|
+
readonly timestamp: timestamp
|
|
167
|
+
) {}
|
|
168
|
+
|
|
169
|
+
handle(state: State, changes: StateChangeTracker): void {
|
|
170
|
+
const order = state.order
|
|
171
|
+
.tryGetOrSet(this.instrument.id, () => {
|
|
172
|
+
throw new Error(`Trying to patch unknown order: ${this.id}`);
|
|
173
|
+
})
|
|
174
|
+
.tryGetOrSet(this.id, () => {
|
|
175
|
+
throw new Error(`Trying to patch unknown order: ${this.id}`);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
if (order.state != 'CANCELING') {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
order.state = 'PENDING';
|
|
183
|
+
order.timestamp = this.timestamp;
|
|
184
|
+
|
|
185
|
+
changes.commit(order);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export class OrderRejectedEvent implements StoreEvent {
|
|
190
|
+
constructor(
|
|
191
|
+
readonly id: string,
|
|
192
|
+
readonly instrument: InstrumentSelector,
|
|
193
|
+
readonly timestamp: timestamp
|
|
194
|
+
) {}
|
|
195
|
+
|
|
196
|
+
handle(state: State, changes: StateChangeTracker): void {
|
|
197
|
+
const order = state.order
|
|
198
|
+
.tryGetOrSet(this.instrument.id, () => {
|
|
199
|
+
throw new Error(`Trying to patch unknown order: ${this.id}`);
|
|
200
|
+
})
|
|
201
|
+
.tryGetOrSet(this.id, () => {
|
|
202
|
+
throw new Error(`Trying to patch unknown order: ${this.id}`);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
if (order.state != 'NEW') {
|
|
206
|
+
throw new Error(`Order is not NEW: ${order.state}`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
order.state = 'REJECTED';
|
|
210
|
+
order.timestamp = this.timestamp;
|
|
211
|
+
|
|
212
|
+
changes.commit(order);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { InstrumentSelector, Orderbook } from '../domain';
|
|
2
|
+
import { timestamp } from '../shared';
|
|
3
|
+
import { StoreEvent } from './store.event';
|
|
4
|
+
import { State, StateChangeTracker } from './store-state';
|
|
5
|
+
|
|
6
|
+
export class OrderbookPatchEvent implements StoreEvent {
|
|
7
|
+
constructor(
|
|
8
|
+
readonly instrument: InstrumentSelector,
|
|
9
|
+
readonly bestAskRate: number,
|
|
10
|
+
readonly bestAskQuantity: number,
|
|
11
|
+
readonly bestBidRate: number,
|
|
12
|
+
readonly bestBidQuantity: number,
|
|
13
|
+
readonly timestamp: timestamp
|
|
14
|
+
) {}
|
|
15
|
+
|
|
16
|
+
handle(state: State, changes: StateChangeTracker): void {
|
|
17
|
+
if (!state.subscription.instrument.get(this.instrument.id)) {
|
|
18
|
+
throw new Error(`Trying to patch unsubscribed instrument: ${this.instrument.id}`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const orderbook = state.orderbook.tryGetOrSet(
|
|
22
|
+
this.instrument.id,
|
|
23
|
+
() => new Orderbook(state.universe.instrument.get(this.instrument.id))
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
state.timestamp = this.timestamp;
|
|
27
|
+
|
|
28
|
+
orderbook.timestamp = this.timestamp;
|
|
29
|
+
orderbook.bestAskRate = orderbook.instrument.quote.fixed(this.bestAskRate);
|
|
30
|
+
orderbook.bestAskQuantity = orderbook.instrument.base.fixed(this.bestAskQuantity);
|
|
31
|
+
orderbook.bestBidRate = orderbook.instrument.quote.fixed(this.bestBidRate);
|
|
32
|
+
orderbook.bestBidQuantity = orderbook.instrument.base.fixed(this.bestBidQuantity);
|
|
33
|
+
|
|
34
|
+
const quote = state.balance.get(orderbook.instrument.quote.id);
|
|
35
|
+
|
|
36
|
+
if (quote) {
|
|
37
|
+
for (const position of Object.values(quote.position)) {
|
|
38
|
+
if (position.instrument.id != orderbook.instrument.id) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const rate = position.size >= 0 ? orderbook.bestBidRate : orderbook.bestAskRate;
|
|
43
|
+
|
|
44
|
+
position.calculateEstimatedUnrealizedPnL(rate);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (quote.total < 0) {
|
|
48
|
+
throw new Error('liquidated');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
changes.commit(orderbook);
|
|
53
|
+
}
|
|
54
|
+
}
|