@quantform/core 0.3.267 → 0.4.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.
- package/dist/adapter/adapter-aggregate.d.ts +2 -2
- package/dist/adapter/adapter-aggregate.js.map +1 -1
- package/dist/adapter/adapter.d.ts +4 -5
- package/dist/adapter/adapter.js.map +1 -1
- package/dist/adapter/backtester/backtester-adapter.d.ts +5 -5
- package/dist/adapter/backtester/backtester-adapter.js +3 -7
- package/dist/adapter/backtester/backtester-adapter.js.map +1 -1
- package/dist/adapter/backtester/backtester-cursor.d.ts +2 -2
- package/dist/adapter/backtester/backtester-cursor.spec.js +9 -9
- package/dist/adapter/backtester/backtester-cursor.spec.js.map +1 -1
- package/dist/adapter/backtester/backtester-streamer.d.ts +6 -4
- package/dist/adapter/backtester/backtester-streamer.js +5 -5
- package/dist/adapter/backtester/backtester-streamer.js.map +1 -1
- package/dist/adapter/backtester/backtester-streamer.spec.js +9 -11
- package/dist/adapter/backtester/backtester-streamer.spec.js.map +1 -1
- package/dist/adapter/index.d.ts +2 -0
- package/dist/adapter/index.js +2 -0
- package/dist/adapter/index.js.map +1 -1
- package/dist/adapter/paper/index.d.ts +1 -1
- package/dist/adapter/paper/index.js +1 -1
- package/dist/adapter/paper/index.js.map +1 -1
- package/dist/adapter/paper/paper-adapter.d.ts +3 -3
- package/dist/adapter/paper/paper-adapter.js +4 -7
- package/dist/adapter/paper/paper-adapter.js.map +1 -1
- package/dist/adapter/paper/paper-adapter.spec.js +3 -5
- package/dist/adapter/paper/paper-adapter.spec.js.map +1 -1
- package/dist/adapter/paper/simulator/paper-margin-simulator.d.ts +1 -1
- package/dist/adapter/paper/simulator/paper-margin-simulator.js +6 -6
- package/dist/adapter/paper/simulator/paper-margin-simulator.js.map +1 -1
- package/dist/adapter/paper/simulator/paper-simulator.d.ts +1 -1
- package/dist/adapter/paper/simulator/paper-simulator.js +3 -3
- package/dist/adapter/paper/simulator/paper-simulator.js.map +1 -1
- package/dist/adapter/paper/simulator/paper-spot-simulator.d.ts +2 -2
- package/dist/adapter/paper/simulator/paper-spot-simulator.js +12 -12
- package/dist/adapter/paper/simulator/paper-spot-simulator.js.map +1 -1
- package/dist/adapter/paper/simulator/paper-spot-simulator.spec.js +8 -9
- package/dist/adapter/paper/simulator/paper-spot-simulator.spec.js.map +1 -1
- package/dist/bootstrap.d.ts +1 -1
- package/dist/bootstrap.js +3 -5
- package/dist/bootstrap.js.map +1 -1
- package/dist/domain/balance.d.ts +1 -1
- package/dist/domain/candle.d.ts +14 -0
- package/dist/domain/candle.js +65 -1
- package/dist/domain/candle.js.map +1 -1
- package/dist/domain/candle.spec.js +11 -13
- package/dist/domain/candle.spec.js.map +1 -1
- package/dist/domain/index.d.ts +6 -8
- package/dist/domain/index.js +6 -8
- package/dist/domain/index.js.map +1 -1
- package/dist/domain/order.d.ts +1 -1
- package/dist/domain/order.js.map +1 -1
- package/dist/domain/orderbook.d.ts +1 -1
- package/dist/domain/position.d.ts +2 -2
- package/dist/domain/position.js +3 -3
- package/dist/domain/position.js.map +1 -1
- package/dist/domain/session.d.ts +14 -3
- package/dist/domain/session.js +17 -18
- package/dist/domain/session.js.map +1 -1
- package/dist/domain/session.spec.js +3 -3
- package/dist/domain/session.spec.js.map +1 -1
- package/dist/domain/statement.d.ts +1 -2
- package/dist/domain/statement.js.map +1 -1
- package/dist/domain/trade.d.ts +1 -1
- package/dist/index.d.ts +4 -7
- package/dist/index.js +4 -7
- package/dist/index.js.map +1 -1
- package/dist/indicator/atr.js +3 -3
- package/dist/indicator/atr.js.map +1 -1
- package/dist/indicator/cross.js +3 -3
- package/dist/indicator/cross.js.map +1 -1
- package/dist/indicator/donchian.js +3 -4
- package/dist/indicator/donchian.js.map +1 -1
- package/dist/indicator/drawdown.js +3 -3
- package/dist/indicator/drawdown.js.map +1 -1
- package/dist/indicator/ema.js +3 -3
- package/dist/indicator/ema.js.map +1 -1
- package/dist/indicator/envelope.js +3 -3
- package/dist/indicator/envelope.js.map +1 -1
- package/dist/indicator/index.d.ts +3 -3
- package/dist/indicator/index.js +3 -3
- package/dist/indicator/index.js.map +1 -1
- package/dist/indicator/macd.js +2 -3
- package/dist/indicator/macd.js.map +1 -1
- package/dist/indicator/min-max.js +3 -3
- package/dist/indicator/min-max.js.map +1 -1
- package/dist/indicator/rma.js +3 -3
- package/dist/indicator/rma.js.map +1 -1
- package/dist/indicator/sma.js +2 -3
- package/dist/indicator/sma.js.map +1 -1
- package/dist/indicator/swma.js +3 -3
- package/dist/indicator/swma.js.map +1 -1
- package/dist/indicator/tma.js +3 -3
- package/dist/indicator/tma.js.map +1 -1
- package/dist/indicator/trailing.js +3 -3
- package/dist/indicator/trailing.js.map +1 -1
- package/dist/indicator/truerange.js +3 -3
- package/dist/indicator/truerange.js.map +1 -1
- package/dist/indicator/truerange.spec.js +2 -2
- package/dist/indicator/truerange.spec.js.map +1 -1
- package/dist/indicator/wma.js +3 -3
- package/dist/indicator/wma.js.map +1 -1
- package/dist/ipc.d.ts +1 -1
- package/dist/ipc.js +3 -3
- package/dist/ipc.js.map +1 -1
- package/dist/ipc.spec.js +3 -4
- package/dist/ipc.spec.js.map +1 -1
- package/dist/shared/index.d.ts +4 -4
- package/dist/shared/index.js +4 -4
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/policy.js +1 -1
- package/dist/shared/policy.js.map +1 -1
- package/dist/storage/feed.d.ts +1 -1
- package/dist/storage/feed.js.map +1 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.js +1 -1
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/measurement.js.map +1 -1
- package/dist/storage/storage.js.map +1 -1
- package/dist/store/event/index.d.ts +4 -4
- package/dist/store/event/index.js +4 -4
- package/dist/store/event/index.js.map +1 -1
- package/dist/store/event/store-balance.event.d.ts +1 -1
- package/dist/store/event/store-balance.event.js +1 -1
- package/dist/store/event/store-balance.event.js.map +1 -1
- package/dist/store/event/store-balance.event.spec.js +3 -3
- package/dist/store/event/store-balance.event.spec.js.map +1 -1
- package/dist/store/event/store-candle.event.d.ts +2 -2
- package/dist/store/event/store-candle.event.js +2 -2
- package/dist/store/event/store-candle.event.js.map +1 -1
- package/dist/store/event/store-candle.event.spec.js +1 -1
- package/dist/store/event/store-candle.event.spec.js.map +1 -1
- package/dist/store/event/store-instrument.event.d.ts +1 -1
- package/dist/store/event/store-instrument.event.js +1 -1
- package/dist/store/event/store-instrument.event.js.map +1 -1
- package/dist/store/event/store-instrument.event.spec.js +1 -1
- package/dist/store/event/store-instrument.event.spec.js.map +1 -1
- package/dist/store/event/store-order.event.d.ts +1 -1
- package/dist/store/event/store-order.event.js +1 -1
- package/dist/store/event/store-order.event.js.map +1 -1
- package/dist/store/event/store-order.event.spec.js +2 -2
- package/dist/store/event/store-order.event.spec.js.map +1 -1
- package/dist/store/event/store-orderbook.event.d.ts +1 -1
- package/dist/store/event/store-orderbook.event.js +1 -1
- package/dist/store/event/store-orderbook.event.js.map +1 -1
- package/dist/store/event/store-position.event.d.ts +1 -1
- package/dist/store/event/store-position.event.js +1 -1
- package/dist/store/event/store-position.event.js.map +1 -1
- package/dist/store/event/store-trade.event.d.ts +1 -1
- package/dist/store/event/store-trade.event.js +1 -1
- package/dist/store/event/store-trade.event.js.map +1 -1
- package/dist/store/event/store-trade.event.spec.js +2 -2
- package/dist/store/event/store-trade.event.spec.js.map +1 -1
- package/dist/store/index.d.ts +1 -0
- package/dist/store/index.js +1 -0
- package/dist/store/index.js.map +1 -1
- package/dist/store/store.d.ts +2 -5
- package/dist/store/store.js +4 -8
- package/dist/store/store.js.map +1 -1
- package/dist/store/store.state.d.ts +1 -1
- package/dist/tests/backtester-adapter.spec.js +6 -13
- package/dist/tests/backtester-adapter.spec.js.map +1 -1
- package/dist/tests/session.spec.d.ts +0 -1
- package/dist/tests/session.spec.js +0 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/adapter/adapter-aggregate.ts +2 -3
- package/src/adapter/adapter.ts +4 -5
- package/src/adapter/backtester/backtester-adapter.ts +6 -6
- package/src/adapter/backtester/backtester-cursor.spec.ts +1 -1
- package/src/adapter/backtester/backtester-cursor.ts +2 -2
- package/src/adapter/backtester/backtester-streamer.spec.ts +1 -3
- package/src/adapter/backtester/backtester-streamer.ts +7 -8
- package/src/adapter/index.ts +2 -0
- package/src/adapter/paper/index.ts +1 -1
- package/src/adapter/paper/paper-adapter.spec.ts +3 -5
- package/src/adapter/paper/paper-adapter.ts +3 -5
- package/src/adapter/paper/simulator/paper-margin-simulator.ts +3 -3
- package/src/adapter/paper/simulator/paper-simulator.ts +3 -3
- package/src/adapter/paper/simulator/paper-spot-simulator.spec.ts +12 -13
- package/src/adapter/paper/simulator/paper-spot-simulator.ts +4 -4
- package/src/bootstrap.ts +4 -4
- package/src/domain/balance.ts +1 -1
- package/src/domain/candle.spec.ts +3 -5
- package/src/domain/candle.ts +103 -0
- package/src/domain/index.ts +6 -8
- package/src/domain/order.ts +2 -2
- package/src/domain/orderbook.ts +1 -1
- package/src/domain/position.ts +2 -3
- package/src/domain/session.spec.ts +3 -3
- package/src/domain/session.ts +61 -8
- package/src/domain/statement.ts +1 -2
- package/src/domain/trade.ts +1 -1
- package/src/index.ts +4 -7
- package/src/indicator/atr.ts +1 -2
- package/src/indicator/cross.ts +3 -4
- package/src/indicator/donchian.ts +2 -3
- package/src/indicator/drawdown.ts +2 -3
- package/src/indicator/ema.ts +1 -2
- package/src/indicator/envelope.ts +1 -2
- package/src/indicator/index.ts +3 -3
- package/src/indicator/macd.ts +1 -2
- package/src/indicator/min-max.ts +1 -2
- package/src/indicator/rma.ts +1 -2
- package/src/indicator/sma.ts +1 -2
- package/src/indicator/swma.ts +1 -2
- package/src/indicator/tma.ts +1 -2
- package/src/indicator/trailing.ts +3 -4
- package/src/indicator/truerange.spec.ts +2 -2
- package/src/indicator/truerange.ts +1 -2
- package/src/indicator/window.ts +1 -1
- package/src/indicator/wma.ts +1 -2
- package/src/ipc.spec.ts +3 -4
- package/src/ipc.ts +6 -6
- package/src/shared/index.ts +4 -4
- package/src/shared/policy.ts +1 -1
- package/src/shared/topic.spec.ts +1 -1
- package/src/storage/feed.ts +20 -1
- package/src/storage/index.ts +1 -1
- package/src/storage/measurement.ts +19 -0
- package/src/storage/storage.ts +37 -0
- package/src/store/event/index.ts +4 -4
- package/src/store/event/store-balance.event.spec.ts +3 -3
- package/src/store/event/store-balance.event.ts +2 -2
- package/src/store/event/store-candle.event.spec.ts +1 -1
- package/src/store/event/store-candle.event.ts +5 -5
- package/src/store/event/store-instrument.event.spec.ts +1 -1
- package/src/store/event/store-instrument.event.ts +2 -2
- package/src/store/event/store-order.event.spec.ts +2 -2
- package/src/store/event/store-order.event.ts +2 -2
- package/src/store/event/store-orderbook.event.ts +2 -2
- package/src/store/event/store-position.event.ts +2 -2
- package/src/store/event/store-trade.event.spec.ts +2 -2
- package/src/store/event/store-trade.event.ts +2 -2
- package/src/store/index.ts +1 -0
- package/src/store/store.state.ts +7 -7
- package/src/store/store.ts +6 -9
- package/src/tests/backtester-adapter.spec.ts +6 -13
- package/src/tests/session.spec.ts +0 -3
- package/dist/domain/candle-builder.d.ts +0 -16
- package/dist/domain/candle-builder.js +0 -70
- package/dist/domain/candle-builder.js.map +0 -1
- package/dist/domain/session-descriptor.d.ts +0 -15
- package/dist/domain/session-descriptor.js +0 -3
- package/dist/domain/session-descriptor.js.map +0 -1
- package/src/domain/candle-builder.ts +0 -104
- package/src/domain/session-descriptor.ts +0 -53
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { PaperSpotSimulator } from '.';
|
|
2
2
|
import { AdapterContext } from '..';
|
|
3
|
-
import { Store } from '../../store';
|
|
3
|
+
import { InstrumentPatchEvent, Store } from '../../store';
|
|
4
4
|
import { Adapter } from '../adapter';
|
|
5
|
-
import {
|
|
5
|
+
import { Asset, Commission, instrumentOf, Order } from './../../domain';
|
|
6
6
|
import { PaperAdapter } from './paper-adapter';
|
|
7
|
-
import {
|
|
8
|
-
import { instrumentOf } from './../../domain/instrument';
|
|
9
|
-
import { BalancePatchEvent, InstrumentPatchEvent } from '../../store/event';
|
|
7
|
+
import { PaperSimulator } from './simulator/paper-simulator';
|
|
10
8
|
|
|
11
9
|
class DefaultAdapter extends Adapter {
|
|
12
10
|
name = 'default';
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { Adapter, AdapterContext } from '..';
|
|
2
|
-
import { Store } from '../../store';
|
|
3
|
-
import { PaperSimulator } from './simulator/paper-simulator';
|
|
4
2
|
import { assetOf, Candle, InstrumentSelector, Order } from '../../domain';
|
|
5
|
-
import { BalancePatchEvent } from '../../store
|
|
6
|
-
import { Feed } from 'src/storage';
|
|
3
|
+
import { BalancePatchEvent, Store } from '../../store';
|
|
7
4
|
import { FeedQuery, HistoryQuery } from '../adapter';
|
|
5
|
+
import { PaperSimulator } from './simulator/paper-simulator';
|
|
8
6
|
|
|
9
|
-
export
|
|
7
|
+
export interface PaperOptions {
|
|
10
8
|
balance: { [key: string]: number };
|
|
11
9
|
}
|
|
12
10
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PaperAdapter } from '..';
|
|
2
2
|
import { Order } from '../../../domain';
|
|
3
|
+
import { pnl, weightedMean } from '../../../shared';
|
|
3
4
|
import {
|
|
4
5
|
BalanceTransactEvent,
|
|
5
6
|
OrderCanceledEvent,
|
|
@@ -8,8 +9,7 @@ import {
|
|
|
8
9
|
OrderNewEvent,
|
|
9
10
|
OrderPendingEvent,
|
|
10
11
|
PositionPatchEvent
|
|
11
|
-
} from '../../../store
|
|
12
|
-
import { PaperAdapter } from '..';
|
|
12
|
+
} from '../../../store';
|
|
13
13
|
import { PaperSimulator } from './paper-simulator';
|
|
14
14
|
|
|
15
15
|
export class PaperMarginSimulator extends PaperSimulator {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { tap } from 'rxjs
|
|
2
|
-
import { Component, InstrumentSelector, Order, Orderbook, Trade } from '../../../domain';
|
|
3
|
-
import { PaperAdapter } from '..';
|
|
1
|
+
import { tap } from 'rxjs';
|
|
4
2
|
import { Set } from 'typescript-collections';
|
|
3
|
+
import { PaperAdapter } from '..';
|
|
4
|
+
import { Component, InstrumentSelector, Order, Orderbook, Trade } from '../../../domain';
|
|
5
5
|
|
|
6
6
|
export abstract class PaperSimulator {
|
|
7
7
|
private readonly pending: Record<string, Set<Order>> = {};
|
|
@@ -1,23 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PaperAdapter } from '../paper-adapter';
|
|
2
|
+
import {
|
|
3
|
+
Asset,
|
|
4
|
+
assetOf,
|
|
5
|
+
Commission,
|
|
6
|
+
commissionPercentOf,
|
|
7
|
+
instrumentOf,
|
|
8
|
+
Order
|
|
9
|
+
} from './../../../domain';
|
|
2
10
|
import {
|
|
3
11
|
BalancePatchEvent,
|
|
4
12
|
InstrumentPatchEvent,
|
|
5
13
|
InstrumentSubscriptionEvent,
|
|
6
|
-
|
|
14
|
+
Store,
|
|
7
15
|
TradePatchEvent
|
|
8
|
-
} from './../../../store
|
|
9
|
-
import {
|
|
16
|
+
} from './../../../store';
|
|
17
|
+
import { Adapter, AdapterContext } from './../../adapter';
|
|
10
18
|
import { PaperSimulator } from './paper-simulator';
|
|
11
|
-
import { PaperAdapter } from '../paper-adapter';
|
|
12
19
|
import { PaperSpotSimulator } from './paper-spot-simulator';
|
|
13
|
-
import {
|
|
14
|
-
Asset,
|
|
15
|
-
Commission,
|
|
16
|
-
Order,
|
|
17
|
-
instrumentOf,
|
|
18
|
-
assetOf,
|
|
19
|
-
commissionPercentOf
|
|
20
|
-
} from './../../../domain';
|
|
21
20
|
|
|
22
21
|
class DefaultAdapter extends Adapter {
|
|
23
22
|
name = 'default';
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PaperAdapter } from '..';
|
|
2
|
+
import { Order } from '../../../domain';
|
|
3
|
+
import { timestamp } from '../../../shared';
|
|
2
4
|
import {
|
|
3
5
|
BalanceFreezEvent,
|
|
4
6
|
BalanceTransactEvent,
|
|
@@ -8,10 +10,8 @@ import {
|
|
|
8
10
|
OrderFilledEvent,
|
|
9
11
|
OrderNewEvent,
|
|
10
12
|
OrderPendingEvent
|
|
11
|
-
} from '../../../store
|
|
12
|
-
import { PaperAdapter } from '..';
|
|
13
|
+
} from '../../../store';
|
|
13
14
|
import { PaperSimulator } from './paper-simulator';
|
|
14
|
-
import { timestamp } from '../../../shared';
|
|
15
15
|
|
|
16
16
|
export class PaperSpotSimulator extends PaperSimulator {
|
|
17
17
|
constructor(readonly adapter: PaperAdapter) {
|
package/src/bootstrap.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AdapterAggregate,
|
|
2
3
|
BacktesterAdapter,
|
|
3
4
|
BacktesterListener,
|
|
4
|
-
BacktesterStreamer
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import { PaperAdapter } from './adapter/paper';
|
|
5
|
+
BacktesterStreamer,
|
|
6
|
+
PaperAdapter
|
|
7
|
+
} from './adapter';
|
|
8
8
|
import { Session, SessionDescriptor } from './domain';
|
|
9
9
|
import { Store } from './store';
|
|
10
10
|
|
package/src/domain/balance.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { timestamp } from '../shared';
|
|
2
2
|
import { Asset } from './';
|
|
3
|
-
import { Position, PositionMode } from './position';
|
|
4
3
|
import { Component } from './component';
|
|
4
|
+
import { Position, PositionMode } from './position';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Represents single asset balance in your wallet.
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { from } from 'rxjs';
|
|
2
|
-
import { map } from 'rxjs/operators';
|
|
3
|
-
import { TradePatchEvent } from '../store/event';
|
|
1
|
+
import { from, map } from 'rxjs';
|
|
4
2
|
import { now } from '../shared';
|
|
5
|
-
import {
|
|
6
|
-
import { mergeCandle } from './candle
|
|
3
|
+
import { TradePatchEvent } from '../store';
|
|
4
|
+
import { Candle, mergeCandle } from './candle';
|
|
7
5
|
import { instrumentOf } from './instrument';
|
|
8
6
|
import { Timeframe } from './timeframe';
|
|
9
7
|
|
package/src/domain/candle.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
concat,
|
|
3
|
+
filter,
|
|
4
|
+
last,
|
|
5
|
+
map,
|
|
6
|
+
mergeMap,
|
|
7
|
+
Observable,
|
|
8
|
+
share,
|
|
9
|
+
skipLast,
|
|
10
|
+
withLatestFrom
|
|
11
|
+
} from 'rxjs';
|
|
1
12
|
import { timestamp } from '../shared';
|
|
13
|
+
import { tf } from './timeframe';
|
|
2
14
|
|
|
3
15
|
export class Candle {
|
|
4
16
|
constructor(
|
|
@@ -15,3 +27,94 @@ export class Candle {
|
|
|
15
27
|
this.close = value;
|
|
16
28
|
}
|
|
17
29
|
}
|
|
30
|
+
|
|
31
|
+
export class CandleBuilder {
|
|
32
|
+
private _candle: Candle;
|
|
33
|
+
|
|
34
|
+
get candle(): Candle {
|
|
35
|
+
return this._candle;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
constructor(readonly timeframe: number) {}
|
|
39
|
+
|
|
40
|
+
append(value: number, timestamp: timestamp): Candle {
|
|
41
|
+
const frame = tf(timestamp, this.timeframe);
|
|
42
|
+
|
|
43
|
+
if (!this._candle) {
|
|
44
|
+
this._candle = new Candle(frame, value, value, value, value);
|
|
45
|
+
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (this.candle.timestamp == frame) {
|
|
50
|
+
this.candle.apply(value);
|
|
51
|
+
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const previous = this._candle;
|
|
56
|
+
|
|
57
|
+
this._candle = new Candle(frame, value, value, value, value);
|
|
58
|
+
return previous;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function candle<T extends { timestamp: number }>(
|
|
63
|
+
timeframe: number,
|
|
64
|
+
fn: (x: T) => number
|
|
65
|
+
) {
|
|
66
|
+
return function (source: Observable<T>): Observable<Candle> {
|
|
67
|
+
const builder = new CandleBuilder(timeframe);
|
|
68
|
+
let candle: Candle;
|
|
69
|
+
|
|
70
|
+
return source.pipe(
|
|
71
|
+
filter(it => {
|
|
72
|
+
return (candle = builder.append(fn(it), it.timestamp)) != null;
|
|
73
|
+
}),
|
|
74
|
+
map(_ => candle),
|
|
75
|
+
share()
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function mergeCandle<T extends { timestamp: number }>(
|
|
81
|
+
timeframe: number,
|
|
82
|
+
fn: (x: T) => number,
|
|
83
|
+
history$: Observable<Candle>
|
|
84
|
+
) {
|
|
85
|
+
return function (source$: Observable<T>): Observable<Candle> {
|
|
86
|
+
const builder = new CandleBuilder(timeframe);
|
|
87
|
+
let hasMergedHistory = false;
|
|
88
|
+
|
|
89
|
+
return concat(
|
|
90
|
+
history$.pipe(skipLast(1)),
|
|
91
|
+
source$.pipe(
|
|
92
|
+
withLatestFrom(history$.pipe(last())),
|
|
93
|
+
mergeMap(([it, history]) => {
|
|
94
|
+
const completed = builder.append(fn(it), it.timestamp);
|
|
95
|
+
|
|
96
|
+
if (completed) {
|
|
97
|
+
if (completed.timestamp == history.timestamp) {
|
|
98
|
+
completed.open = history.open;
|
|
99
|
+
completed.high = Math.max(completed.high, history.high);
|
|
100
|
+
completed.low = Math.min(completed.low, history.low);
|
|
101
|
+
|
|
102
|
+
hasMergedHistory = true;
|
|
103
|
+
} else if (completed.timestamp > history.timestamp) {
|
|
104
|
+
if (!hasMergedHistory) {
|
|
105
|
+
hasMergedHistory = true;
|
|
106
|
+
return [history, completed];
|
|
107
|
+
}
|
|
108
|
+
} else if (completed.timestamp < history.timestamp) {
|
|
109
|
+
throw new Error('invalid candle sequence, input data is to old.');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return [completed];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return [];
|
|
116
|
+
})
|
|
117
|
+
)
|
|
118
|
+
);
|
|
119
|
+
};
|
|
120
|
+
}
|
package/src/domain/index.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
export * from './asset';
|
|
2
|
-
export * from './instrument';
|
|
3
2
|
export * from './balance';
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './orderbook';
|
|
3
|
+
export * from './candle';
|
|
6
4
|
export * from './commission';
|
|
7
5
|
export * from './component';
|
|
8
|
-
export * from './
|
|
9
|
-
export * from './
|
|
10
|
-
export * from './
|
|
6
|
+
export * from './instrument';
|
|
7
|
+
export * from './order';
|
|
8
|
+
export * from './orderbook';
|
|
11
9
|
export * from './position';
|
|
12
|
-
export * from './trade';
|
|
13
10
|
export * from './session';
|
|
14
|
-
export * from './session-descriptor';
|
|
15
11
|
export * from './statement';
|
|
12
|
+
export * from './timeframe';
|
|
13
|
+
export * from './trade';
|
package/src/domain/order.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Component } from './component';
|
|
2
1
|
import { v4 } from 'uuid';
|
|
3
|
-
import { InstrumentSelector } from './instrument';
|
|
4
2
|
import { timestamp } from '../shared';
|
|
3
|
+
import { Component } from './component';
|
|
4
|
+
import { InstrumentSelector } from './instrument';
|
|
5
5
|
|
|
6
6
|
export type OrderSide = 'SELL' | 'BUY';
|
|
7
7
|
export type OrderType = 'MARKET' | 'LIMIT' | 'STOP-MARKET' | 'STOP-LIMIT';
|
package/src/domain/orderbook.ts
CHANGED
package/src/domain/position.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
+
import { map, Observable, share } from 'rxjs';
|
|
1
2
|
import { Instrument } from '../domain';
|
|
2
|
-
import { Component } from './component';
|
|
3
3
|
import { pnl, timestamp, weightedMean } from '../shared';
|
|
4
|
-
import {
|
|
5
|
-
import { map, share } from 'rxjs/operators';
|
|
4
|
+
import { Component } from './component';
|
|
6
5
|
|
|
7
6
|
export type PositionMode = 'CROSS' | 'ISOLATED';
|
|
8
7
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Bootstrap } from '../bootstrap';
|
|
2
2
|
import { Asset, Commission } from '../domain';
|
|
3
3
|
import { now } from '../shared';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { InstrumentPatchEvent } from '../store';
|
|
5
|
+
import { SessionDescriptor } from './session';
|
|
6
6
|
|
|
7
7
|
describe('session tests', () => {
|
|
8
8
|
const descriptor: SessionDescriptor = {
|
package/src/domain/session.ts
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
|
+
concat,
|
|
2
3
|
distinctUntilChanged,
|
|
3
4
|
filter,
|
|
5
|
+
from,
|
|
4
6
|
map,
|
|
5
7
|
mergeMap,
|
|
8
|
+
Observable,
|
|
6
9
|
share,
|
|
7
10
|
shareReplay,
|
|
8
11
|
startWith,
|
|
12
|
+
Subject,
|
|
13
|
+
Subscription,
|
|
9
14
|
switchMap,
|
|
10
15
|
take
|
|
11
|
-
} from 'rxjs
|
|
16
|
+
} from 'rxjs';
|
|
17
|
+
import { Adapter, BacktesterOptions, PaperOptions } from '../adapter';
|
|
18
|
+
import { AdapterAggregate } from '../adapter/adapter-aggregate';
|
|
12
19
|
import {
|
|
13
20
|
AssetSelector,
|
|
14
21
|
Balance,
|
|
@@ -16,19 +23,65 @@ import {
|
|
|
16
23
|
Instrument,
|
|
17
24
|
InstrumentSelector,
|
|
18
25
|
Order,
|
|
19
|
-
Position,
|
|
20
26
|
Orderbook,
|
|
21
|
-
OrderState
|
|
27
|
+
OrderState,
|
|
28
|
+
Position
|
|
22
29
|
} from '../domain';
|
|
23
|
-
import { Store } from '../store';
|
|
24
|
-
import { concat, from, Observable, Subject, Subscription } from 'rxjs';
|
|
25
|
-
import { AdapterAggregate } from '../adapter/adapter-aggregate';
|
|
26
|
-
import { Worker, now } from '../shared';
|
|
27
30
|
import { Trade } from '../domain/trade';
|
|
28
|
-
import {
|
|
31
|
+
import { now, Worker } from '../shared';
|
|
32
|
+
import { Feed, Measurement } from '../storage';
|
|
33
|
+
import { Store } from '../store';
|
|
29
34
|
|
|
30
35
|
type Optional<T, K extends keyof T> = Omit<T, K> & Partial<T>;
|
|
31
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Describes a single session.
|
|
39
|
+
* You can use @run function to start a new session managed by CLI.
|
|
40
|
+
* To start managed session you should install @quantform/cli package and run
|
|
41
|
+
* specific command:
|
|
42
|
+
* - qf paper (to paper trade strategy)
|
|
43
|
+
* - qf backtest (to backtest strategy based on provided feed)
|
|
44
|
+
* - qf live (to live trade strategy)
|
|
45
|
+
* or run on your own in code:
|
|
46
|
+
* - paper(descriptor, options)
|
|
47
|
+
* - backtest(descriptor, options)
|
|
48
|
+
* - live(descriptor)
|
|
49
|
+
*/
|
|
50
|
+
export interface SessionDescriptor {
|
|
51
|
+
/**
|
|
52
|
+
* Unique session identifier, used to identify session in the storage.
|
|
53
|
+
* You can generate new id every time you start the new session or provide
|
|
54
|
+
* session id explicitly to resume previous session (in code or via CLI).
|
|
55
|
+
* If you don't provide session id, it will generate new one based on time.
|
|
56
|
+
*/
|
|
57
|
+
id?: number;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Collection of adapters used to connect to the exchanges.
|
|
61
|
+
*/
|
|
62
|
+
adapter: Adapter[];
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Provides historical data for backtest, it's not required for live and paper
|
|
66
|
+
* sessions.
|
|
67
|
+
*/
|
|
68
|
+
feed?: Feed;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Stores session variables i.e. indicators, orders, or any other type of time
|
|
72
|
+
* series data. You can install @quantform/editor to render this data in your browser.
|
|
73
|
+
*/
|
|
74
|
+
measurement?: Measurement;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Session additional options.
|
|
78
|
+
*/
|
|
79
|
+
options?: {
|
|
80
|
+
backtester?: BacktesterOptions;
|
|
81
|
+
paper?: PaperOptions;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
32
85
|
export class Session {
|
|
33
86
|
private initialized = false;
|
|
34
87
|
private subscription: Subscription;
|
package/src/domain/statement.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { Session } from '.';
|
|
2
|
-
import { InstrumentSelector } from '.';
|
|
3
1
|
import { combineLatest, finalize, map, take, tap } from 'rxjs';
|
|
2
|
+
import { InstrumentSelector, Session } from '.';
|
|
4
3
|
import { drawdown } from '../indicator';
|
|
5
4
|
import { floor, precision } from '../shared';
|
|
6
5
|
|
package/src/domain/trade.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
export * from './shared';
|
|
2
|
-
export * from './domain';
|
|
3
1
|
export * from './adapter';
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './
|
|
2
|
+
export * from './bootstrap';
|
|
3
|
+
export * from './domain';
|
|
6
4
|
export * from './indicator';
|
|
5
|
+
export * from './ipc';
|
|
6
|
+
export * from './shared';
|
|
7
7
|
export * from './storage';
|
|
8
8
|
export * from './store';
|
|
9
|
-
export * from './store/event';
|
|
10
|
-
export * from './bootstrap';
|
|
11
|
-
export * from './ipc';
|
package/src/indicator/atr.ts
CHANGED
package/src/indicator/cross.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { Observable } from 'rxjs';
|
|
2
|
-
import { filter } from 'rxjs/operators';
|
|
1
|
+
import { filter, Observable } from 'rxjs';
|
|
3
2
|
|
|
4
3
|
export function crossunder<T>(limitFn: (it: T) => number, currentFn: (it: T) => number) {
|
|
5
|
-
return function(source: Observable<T>): Observable<T> {
|
|
4
|
+
return function (source: Observable<T>): Observable<T> {
|
|
6
5
|
let triggered = false;
|
|
7
6
|
|
|
8
7
|
return source.pipe(
|
|
@@ -27,7 +26,7 @@ export function crossunder<T>(limitFn: (it: T) => number, currentFn: (it: T) =>
|
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
export function crossover<T>(limitFn: (it: T) => number, currentFn: (it: T) => number) {
|
|
30
|
-
return function(source: Observable<T>): Observable<T> {
|
|
29
|
+
return function (source: Observable<T>): Observable<T> {
|
|
31
30
|
let triggered = false;
|
|
32
31
|
|
|
33
32
|
return source.pipe(
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { Observable, withLatestFrom } from 'rxjs';
|
|
2
|
-
import { map, share } from 'rxjs/operators';
|
|
3
|
-
import { minMax } from './min-max';
|
|
1
|
+
import { map, Observable, share, withLatestFrom } from 'rxjs';
|
|
4
2
|
import { Candle } from '../domain';
|
|
3
|
+
import { minMax } from './min-max';
|
|
5
4
|
|
|
6
5
|
export function donchian<T>(length: number, fn: (it: T) => Candle) {
|
|
7
6
|
return function (source: Observable<T>): Observable<
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { Observable } from 'rxjs';
|
|
2
|
-
import { map, share } from 'rxjs/operators';
|
|
1
|
+
import { map, Observable, share } from 'rxjs';
|
|
3
2
|
|
|
4
3
|
export function drawdown<T>(fn: (it: T) => number) {
|
|
5
|
-
return function(source: Observable<T>): Observable<number> {
|
|
4
|
+
return function (source: Observable<T>): Observable<number> {
|
|
6
5
|
let rate;
|
|
7
6
|
let max = 0;
|
|
8
7
|
|
package/src/indicator/ema.ts
CHANGED
package/src/indicator/index.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
export * from './atr';
|
|
1
2
|
export * from './cross';
|
|
3
|
+
export * from './donchian';
|
|
4
|
+
export * from './drawdown';
|
|
2
5
|
export * from './ema';
|
|
3
6
|
export * from './envelope';
|
|
4
7
|
export * from './macd';
|
|
@@ -12,6 +15,3 @@ export * from './trailing';
|
|
|
12
15
|
export * from './truerange';
|
|
13
16
|
export * from './window';
|
|
14
17
|
export * from './wma';
|
|
15
|
-
export * from './donchian';
|
|
16
|
-
export * from './atr';
|
|
17
|
-
export * from './drawdown';
|
package/src/indicator/macd.ts
CHANGED
package/src/indicator/min-max.ts
CHANGED
package/src/indicator/rma.ts
CHANGED
package/src/indicator/sma.ts
CHANGED
package/src/indicator/swma.ts
CHANGED
package/src/indicator/tma.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { Observable } from 'rxjs';
|
|
2
|
-
import { filter } from 'rxjs/operators';
|
|
1
|
+
import { filter, Observable } from 'rxjs';
|
|
3
2
|
|
|
4
3
|
export class Trailing {
|
|
5
4
|
private triggered = false;
|
|
@@ -56,7 +55,7 @@ export class Trailing {
|
|
|
56
55
|
}
|
|
57
56
|
|
|
58
57
|
export function trailingup<T>(trigger: number, buffer: number, value: (it: T) => number) {
|
|
59
|
-
return function(source: Observable<T>): Observable<T> {
|
|
58
|
+
return function (source: Observable<T>): Observable<T> {
|
|
60
59
|
const trailing = new Trailing(trigger, buffer);
|
|
61
60
|
|
|
62
61
|
return source.pipe(filter(it => trailing.up(value(it))));
|
|
@@ -68,7 +67,7 @@ export function trailingdown<T>(
|
|
|
68
67
|
buffer: number,
|
|
69
68
|
value: (it: T) => number
|
|
70
69
|
) {
|
|
71
|
-
return function(source: Observable<T>): Observable<T> {
|
|
70
|
+
return function (source: Observable<T>): Observable<T> {
|
|
72
71
|
const trailing = new Trailing(trigger, buffer);
|
|
73
72
|
|
|
74
73
|
return source.pipe(filter(it => trailing.down(value(it))));
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { from } from 'rxjs';
|
|
2
2
|
import { Candle } from '../domain';
|
|
3
|
-
import { truerange } from './truerange';
|
|
4
|
-
import { sma } from './sma';
|
|
5
3
|
import { now } from '../shared';
|
|
4
|
+
import { sma } from './sma';
|
|
5
|
+
import { truerange } from './truerange';
|
|
6
6
|
|
|
7
7
|
describe('truerange atr tests', () => {
|
|
8
8
|
test('should return expected value', done => {
|
package/src/indicator/window.ts
CHANGED