@quantform/core 0.3.214 → 0.3.220
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/paper/model/paper-margin-model.d.ts +2 -2
- package/dist/adapter/paper/model/paper-margin-model.js +2 -2
- package/dist/adapter/paper/model/paper-margin-model.js.map +1 -1
- package/dist/adapter/paper/model/paper-model.d.ts +4 -4
- package/dist/adapter/paper/model/paper-model.js +26 -12
- package/dist/adapter/paper/model/paper-model.js.map +1 -1
- package/dist/adapter/paper/model/paper-spot-model.d.ts +3 -2
- package/dist/adapter/paper/model/paper-spot-model.js +2 -2
- package/dist/adapter/paper/model/paper-spot-model.js.map +1 -1
- package/dist/indicator/atr.d.ts +1 -2
- package/dist/indicator/atr.js +4 -1
- package/dist/indicator/atr.js.map +1 -1
- package/dist/indicator/donchian.d.ts +7 -6
- package/dist/indicator/donchian.js +6 -15
- package/dist/indicator/donchian.js.map +1 -1
- package/dist/indicator/ema.d.ts +1 -10
- package/dist/indicator/ema.js +13 -32
- package/dist/indicator/ema.js.map +1 -1
- package/dist/indicator/ema.spec.js +4 -23
- package/dist/indicator/ema.spec.js.map +1 -1
- package/dist/indicator/envelope.js +4 -8
- package/dist/indicator/envelope.js.map +1 -1
- package/dist/indicator/index.d.ts +1 -1
- package/dist/indicator/index.js +1 -1
- package/dist/indicator/index.js.map +1 -1
- package/dist/indicator/macd.js +3 -12
- package/dist/indicator/macd.js.map +1 -1
- package/dist/indicator/min-max.d.ts +4 -11
- package/dist/indicator/min-max.js +12 -29
- package/dist/indicator/min-max.js.map +1 -1
- package/dist/indicator/rma.d.ts +1 -10
- package/dist/indicator/rma.js +13 -32
- package/dist/indicator/rma.js.map +1 -1
- package/dist/indicator/sma.d.ts +1 -10
- package/dist/indicator/sma.js +11 -22
- package/dist/indicator/sma.js.map +1 -1
- package/dist/indicator/sma.spec.js +1 -1
- package/dist/indicator/sma.spec.js.map +1 -1
- package/dist/indicator/swma.d.ts +1 -9
- package/dist/indicator/swma.js +11 -26
- package/dist/indicator/swma.js.map +1 -1
- package/dist/indicator/tma.d.ts +1 -2
- package/dist/indicator/tma.js +4 -1
- package/dist/indicator/tma.js.map +1 -1
- package/dist/indicator/tma.spec.js +1 -1
- package/dist/indicator/tma.spec.js.map +1 -1
- package/dist/indicator/truerange.d.ts +1 -1
- package/dist/indicator/truerange.js +3 -1
- 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/window.d.ts +3 -0
- package/dist/indicator/window.js +22 -0
- package/dist/indicator/window.js.map +1 -0
- package/dist/indicator/wma.d.ts +1 -11
- package/dist/indicator/wma.js +13 -33
- package/dist/indicator/wma.js.map +1 -1
- package/dist/indicator/wma.spec.js +1 -1
- package/dist/indicator/wma.spec.js.map +1 -1
- package/dist/session/session-descriptor.d.ts +0 -1
- package/dist/session/session-optimizer.js.map +1 -1
- package/dist/session/session.d.ts +4 -4
- package/dist/session/session.js +13 -13
- package/dist/session/session.js.map +1 -1
- package/dist/store/event/store-candle.event.d.ts +2 -0
- package/dist/store/event/store-candle.event.js +12 -1
- package/dist/store/event/store-candle.event.js.map +1 -1
- package/dist/store/store.d.ts +2 -1
- package/dist/store/store.js +9 -0
- package/dist/store/store.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/adapter/paper/model/paper-margin-model.ts +5 -5
- package/src/adapter/paper/model/paper-model.ts +35 -18
- package/src/adapter/paper/model/paper-spot-model.ts +5 -5
- package/src/indicator/atr.ts +9 -4
- package/src/indicator/donchian.ts +26 -26
- package/src/indicator/ema.spec.ts +4 -23
- package/src/indicator/ema.ts +15 -42
- package/src/indicator/envelope.ts +8 -14
- package/src/indicator/index.ts +1 -1
- package/src/indicator/macd.ts +8 -19
- package/src/indicator/min-max.ts +15 -37
- package/src/indicator/rma.ts +15 -43
- package/src/indicator/sma.spec.ts +1 -1
- package/src/indicator/sma.ts +13 -29
- package/src/indicator/swma.ts +14 -35
- package/src/indicator/tma.spec.ts +1 -1
- package/src/indicator/tma.ts +9 -4
- package/src/indicator/truerange.spec.ts +2 -2
- package/src/indicator/truerange.ts +15 -10
- package/src/indicator/window.ts +27 -0
- package/src/indicator/wma.spec.ts +1 -1
- package/src/indicator/wma.ts +16 -44
- package/src/session/session-descriptor.ts +0 -2
- package/src/session/session-optimizer.ts +1 -1
- package/src/session/session.ts +19 -14
- package/src/store/event/store-candle.event.ts +15 -0
- package/src/store/store.ts +10 -0
- package/dist/indicator/window-indicator.d.ts +0 -10
- package/dist/indicator/window-indicator.js +0 -28
- package/dist/indicator/window-indicator.js.map +0 -1
- package/src/indicator/window-indicator.ts +0 -35
|
@@ -18,10 +18,10 @@ describe('truerange atr tests', () => {
|
|
|
18
18
|
])
|
|
19
19
|
.pipe(
|
|
20
20
|
truerange(it => it),
|
|
21
|
-
sma(4, it => it)
|
|
21
|
+
sma(4, ([, it]) => it)
|
|
22
22
|
)
|
|
23
23
|
.subscribe({
|
|
24
|
-
next: it => (value = it
|
|
24
|
+
next: ([, it]) => (value = it),
|
|
25
25
|
complete: () => {
|
|
26
26
|
expect(parseFloat(value.toFixed(2))).toBe(42.41);
|
|
27
27
|
done();
|
|
@@ -3,22 +3,27 @@ import { map, share } from 'rxjs/operators';
|
|
|
3
3
|
import { Candle } from '../domain';
|
|
4
4
|
|
|
5
5
|
export function truerange<T>(fn: (it: T) => Candle) {
|
|
6
|
-
return function(source: Observable<T>): Observable<number> {
|
|
6
|
+
return function (source: Observable<T>): Observable<[T, number]> {
|
|
7
7
|
let previous;
|
|
8
8
|
|
|
9
9
|
return source.pipe(
|
|
10
10
|
map(it => {
|
|
11
11
|
const current = fn(it);
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
const value =
|
|
14
|
+
previous == null
|
|
15
|
+
? current.high - current.low
|
|
16
|
+
: Math.max(
|
|
17
|
+
Math.max(
|
|
18
|
+
current.high - current.low,
|
|
19
|
+
Math.abs(current.high - previous.close)
|
|
20
|
+
),
|
|
21
|
+
Math.abs(current.low - previous.close)
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const tuple: [T, number] = [it, value];
|
|
25
|
+
|
|
26
|
+
return tuple;
|
|
22
27
|
}),
|
|
23
28
|
share()
|
|
24
29
|
);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Observable, share, map } from 'rxjs';
|
|
2
|
+
import { RingBuffer } from './ring-buffer';
|
|
3
|
+
|
|
4
|
+
export function window<T, Y>(length: number, fn: (value: T) => Y) {
|
|
5
|
+
return function (source: Observable<T>): Observable<[T, RingBuffer<Y>, Y, Y]> {
|
|
6
|
+
const buffer = new RingBuffer<Y>(length);
|
|
7
|
+
|
|
8
|
+
return source.pipe(
|
|
9
|
+
map(it => {
|
|
10
|
+
let removed = null;
|
|
11
|
+
|
|
12
|
+
if (buffer.isFull) {
|
|
13
|
+
removed = buffer.peek();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const value = fn(it);
|
|
17
|
+
|
|
18
|
+
buffer.enqueue(value);
|
|
19
|
+
|
|
20
|
+
const tuple: [T, RingBuffer<Y>, Y, Y] = [it, buffer, value, removed];
|
|
21
|
+
|
|
22
|
+
return tuple;
|
|
23
|
+
}),
|
|
24
|
+
share()
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -8,7 +8,7 @@ describe('wma tests', () => {
|
|
|
8
8
|
from([18136.17, 18092.15, 18082.39, 18065.4, 18046.47])
|
|
9
9
|
.pipe(wma(5, it => it))
|
|
10
10
|
.subscribe({
|
|
11
|
-
next: it => (value = it
|
|
11
|
+
next: ([, it]) => (value = it),
|
|
12
12
|
complete: () => {
|
|
13
13
|
expect(parseFloat(value.toFixed(2))).toBe(18070.77);
|
|
14
14
|
done();
|
package/src/indicator/wma.ts
CHANGED
|
@@ -1,55 +1,27 @@
|
|
|
1
1
|
import { Observable } from 'rxjs';
|
|
2
2
|
import { filter, map, share } from 'rxjs/operators';
|
|
3
|
-
import {
|
|
4
|
-
import { SMA } from './sma';
|
|
5
|
-
import { WindowIndicator } from './window-indicator';
|
|
3
|
+
import { window } from './window';
|
|
6
4
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
constructor(capacity: number) {
|
|
17
|
-
super(capacity);
|
|
18
|
-
|
|
19
|
-
this._k = 1.0 / capacity;
|
|
20
|
-
this._sma = new SMA(capacity);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
calculate(added: number, removed: number, buffer: RingBuffer<number>) {
|
|
24
|
-
if (!this.isCompleted) {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
let norm = 0.0;
|
|
29
|
-
let sum = 0.0;
|
|
30
|
-
|
|
31
|
-
for (let i = 0; i < this.capacity; i++) {
|
|
32
|
-
const weight = (this.capacity - i) * this.capacity;
|
|
33
|
-
norm = norm + weight;
|
|
34
|
-
|
|
35
|
-
sum = sum + buffer.at(this.capacity - (i + 1)) * weight;
|
|
36
|
-
}
|
|
5
|
+
export function wma<T>(length: number, fn: (it: T) => number) {
|
|
6
|
+
return function (source: Observable<T>): Observable<[T, number]> {
|
|
7
|
+
return source.pipe(
|
|
8
|
+
window(length, fn),
|
|
9
|
+
filter(([, buffer]) => buffer.isFull),
|
|
10
|
+
map(([it, buffer]) => {
|
|
11
|
+
let norm = 0.0;
|
|
12
|
+
let sum = 0.0;
|
|
37
13
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
14
|
+
for (let i = 0; i < buffer.capacity; i++) {
|
|
15
|
+
const weight = (buffer.capacity - i) * buffer.capacity;
|
|
41
16
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
17
|
+
norm = norm + weight;
|
|
18
|
+
sum = sum + buffer.at(buffer.capacity - (i + 1)) * weight;
|
|
19
|
+
}
|
|
45
20
|
|
|
46
|
-
|
|
47
|
-
filter(it => {
|
|
48
|
-
indicator.append(fn(it));
|
|
21
|
+
const tuple: [T, number] = [it, sum / norm];
|
|
49
22
|
|
|
50
|
-
return
|
|
23
|
+
return tuple;
|
|
51
24
|
}),
|
|
52
|
-
map(_ => indicator),
|
|
53
25
|
share()
|
|
54
26
|
);
|
|
55
27
|
};
|
package/src/session/session.ts
CHANGED
|
@@ -83,33 +83,38 @@ export class Session {
|
|
|
83
83
|
await this.worker.wait();
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
if (!this.
|
|
86
|
+
statement(output: Record<string, any>) {
|
|
87
|
+
if (!this.behaviour?.statement) {
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
this.
|
|
92
|
-
this.descriptor.measurement.save(this.descriptor.id, measure)
|
|
93
|
-
);
|
|
91
|
+
this.behaviour.statement(output);
|
|
94
92
|
}
|
|
95
93
|
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
useMeasure<T extends Measure>(
|
|
95
|
+
params: { type: string; timestamp?: number },
|
|
96
|
+
defaultValue: T = undefined
|
|
97
|
+
) {
|
|
98
|
+
const query$ = from(
|
|
98
99
|
this.descriptor.measurement.query(this.descriptor.id, {
|
|
99
100
|
type: params.type,
|
|
100
101
|
timestamp: params.timestamp ?? this.store.snapshot.timestamp,
|
|
101
102
|
limit: 1,
|
|
102
103
|
direction: 'BACKWARD'
|
|
103
104
|
})
|
|
104
|
-
).pipe(map(it => it[0]));
|
|
105
|
-
}
|
|
105
|
+
).pipe(map(it => (it.length ? (it[0] as T) : defaultValue)));
|
|
106
106
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
const setter = (value: T) => {
|
|
108
|
+
this.worker.enqueue(() =>
|
|
109
|
+
this.descriptor.measurement.save(this.descriptor.id, [value])
|
|
110
|
+
);
|
|
111
|
+
};
|
|
111
112
|
|
|
112
|
-
|
|
113
|
+
return [query$, setter];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
useOptimizer(path: string): any {
|
|
117
|
+
return 0;
|
|
113
118
|
}
|
|
114
119
|
|
|
115
120
|
async subscribe(instrument: Array<InstrumentSelector>): Promise<void> {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { TradePatchEventHandler } from './store-trade.event';
|
|
1
2
|
import { timestamp } from '../../common/datetime';
|
|
2
3
|
import { InstrumentSelector } from '../../domain';
|
|
4
|
+
import { State } from '../store.state';
|
|
3
5
|
import { StoreEvent } from './store.event';
|
|
4
6
|
|
|
5
7
|
export class CandleEvent implements StoreEvent {
|
|
@@ -16,3 +18,16 @@ export class CandleEvent implements StoreEvent {
|
|
|
16
18
|
readonly timestamp: timestamp
|
|
17
19
|
) {}
|
|
18
20
|
}
|
|
21
|
+
|
|
22
|
+
export function CandleEventHandler(event: CandleEvent, state: State) {
|
|
23
|
+
return TradePatchEventHandler(
|
|
24
|
+
{
|
|
25
|
+
type: 'trade-patch',
|
|
26
|
+
instrument: event.instrument,
|
|
27
|
+
quantity: event.volume,
|
|
28
|
+
rate: event.close,
|
|
29
|
+
timestamp: event.timestamp
|
|
30
|
+
},
|
|
31
|
+
state
|
|
32
|
+
);
|
|
33
|
+
}
|
package/src/store/store.ts
CHANGED
|
@@ -14,6 +14,8 @@ import {
|
|
|
14
14
|
BalanceTransactEventHandler,
|
|
15
15
|
BalanceUnfreezEvent,
|
|
16
16
|
BalanceUnfreezEventHandler,
|
|
17
|
+
CandleEvent,
|
|
18
|
+
CandleEventHandler,
|
|
17
19
|
InstrumentPatchEvent,
|
|
18
20
|
InstrumentPatchEventHandler,
|
|
19
21
|
InstrumentSubscriptionEvent,
|
|
@@ -222,4 +224,12 @@ export class Store extends Topic<StoreEvent, any> {
|
|
|
222
224
|
onTradePatch(event: TradePatchEvent) {
|
|
223
225
|
return TradePatchEventHandler(event, this.snapshot);
|
|
224
226
|
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* @see CandleEventHandler
|
|
230
|
+
*/
|
|
231
|
+
@handler(CandleEvent)
|
|
232
|
+
onCandle(event: CandleEvent) {
|
|
233
|
+
return CandleEventHandler(event, this.snapshot);
|
|
234
|
+
}
|
|
225
235
|
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { RingBuffer } from './ring-buffer';
|
|
2
|
-
export declare abstract class WindowIndicator<T> {
|
|
3
|
-
private _buffer;
|
|
4
|
-
get capacity(): number;
|
|
5
|
-
get size(): number;
|
|
6
|
-
get isCompleted(): boolean;
|
|
7
|
-
constructor(capacity: number);
|
|
8
|
-
abstract calculate(added: T, removed: T, buffer: RingBuffer<T>): any;
|
|
9
|
-
append(value: T): void;
|
|
10
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WindowIndicator = void 0;
|
|
4
|
-
const ring_buffer_1 = require("./ring-buffer");
|
|
5
|
-
class WindowIndicator {
|
|
6
|
-
constructor(capacity) {
|
|
7
|
-
this._buffer = new ring_buffer_1.RingBuffer(capacity);
|
|
8
|
-
}
|
|
9
|
-
get capacity() {
|
|
10
|
-
return this._buffer.capacity;
|
|
11
|
-
}
|
|
12
|
-
get size() {
|
|
13
|
-
return this._buffer.size;
|
|
14
|
-
}
|
|
15
|
-
get isCompleted() {
|
|
16
|
-
return this._buffer.isFull;
|
|
17
|
-
}
|
|
18
|
-
append(value) {
|
|
19
|
-
let removed = null;
|
|
20
|
-
if (this.isCompleted) {
|
|
21
|
-
removed = this._buffer.peek();
|
|
22
|
-
}
|
|
23
|
-
this._buffer.enqueue(value);
|
|
24
|
-
this.calculate(value, removed, this._buffer);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
exports.WindowIndicator = WindowIndicator;
|
|
28
|
-
//# sourceMappingURL=window-indicator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"window-indicator.js","sourceRoot":"","sources":["../../src/indicator/window-indicator.ts"],"names":[],"mappings":";;;AAAA,+CAA2C;AAE3C,MAAsB,eAAe;IAenC,YAAY,QAAgB;QAC1B,IAAI,CAAC,OAAO,GAAG,IAAI,wBAAU,CAAI,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAdD,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;IAC/B,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;IAQM,MAAM,CAAC,KAAQ;QACpB,IAAI,OAAO,GAAG,IAAI,CAAC;QAEnB,IAAI,IAAI,CAAC,WAAW,EAAE;YACpB,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;SAC/B;QAED,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAE5B,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;CACF;AAhCD,0CAgCC"}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { RingBuffer } from './ring-buffer';
|
|
2
|
-
|
|
3
|
-
export abstract class WindowIndicator<T> {
|
|
4
|
-
private _buffer: RingBuffer<T>;
|
|
5
|
-
|
|
6
|
-
get capacity(): number {
|
|
7
|
-
return this._buffer.capacity;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
get size(): number {
|
|
11
|
-
return this._buffer.size;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
get isCompleted(): boolean {
|
|
15
|
-
return this._buffer.isFull;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
constructor(capacity: number) {
|
|
19
|
-
this._buffer = new RingBuffer<T>(capacity);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
abstract calculate(added: T, removed: T, buffer: RingBuffer<T>);
|
|
23
|
-
|
|
24
|
-
public append(value: T) {
|
|
25
|
-
let removed = null;
|
|
26
|
-
|
|
27
|
-
if (this.isCompleted) {
|
|
28
|
-
removed = this._buffer.peek();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
this._buffer.enqueue(value);
|
|
32
|
-
|
|
33
|
-
this.calculate(value, removed, this._buffer);
|
|
34
|
-
}
|
|
35
|
-
}
|