hft-js 0.1.2 → 0.1.4
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/lib/bar.d.ts +1 -0
- package/lib/bar.js +26 -0
- package/lib/bar.js.map +1 -1
- package/lib/broker.d.ts +16 -0
- package/lib/broker.js +6 -0
- package/lib/broker.js.map +1 -1
- package/lib/index.test.js +1 -1
- package/lib/index.test.js.map +1 -1
- package/lib/interfaces.d.ts +7 -4
- package/lib/trader.d.ts +18 -0
- package/lib/trader.js +115 -60
- package/lib/trader.js.map +1 -1
- package/lib/typedef.d.ts +1 -1
- package/package.json +1 -1
- package/src/bar.ts +24 -0
- package/src/broker.ts +8 -0
- package/src/index.test.ts +1 -1
- package/src/interfaces.ts +11 -3
- package/src/trader.ts +139 -60
- package/src/typedef.ts +1 -1
package/src/trader.ts
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
OffsetType,
|
|
21
21
|
OrderData,
|
|
22
22
|
OrderFlag,
|
|
23
|
+
OrderStatistic,
|
|
23
24
|
OrderStatus,
|
|
24
25
|
PositionData,
|
|
25
26
|
PositionDetail,
|
|
@@ -54,6 +55,7 @@ type CommissionRateQuery = {
|
|
|
54
55
|
};
|
|
55
56
|
|
|
56
57
|
type PositionInfo = Writeable<PositionData>;
|
|
58
|
+
type OrderStat = Writeable<OrderStatistic>;
|
|
57
59
|
|
|
58
60
|
export class Trader extends CTPProvider implements ITraderProvider {
|
|
59
61
|
private traderApi?: ctp.Trader;
|
|
@@ -74,6 +76,7 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
74
76
|
private readonly commRates: Map<string, ctp.InstrumentCommissionRateField>;
|
|
75
77
|
private readonly placeOrders: Map<number, IPlaceOrderResultReceiver>;
|
|
76
78
|
private readonly cancelOrders: Map<number, ICancelOrderResultReceiver>;
|
|
79
|
+
private readonly orderStatistics: Map<string, OrderStat>;
|
|
77
80
|
private readonly marginRatesQueue: Denque<MarginRateQuery>;
|
|
78
81
|
private readonly commRatesQueue: Denque<CommissionRateQuery>;
|
|
79
82
|
private readonly accountsQueue: Denque<ITradingAccountsReceiver>;
|
|
@@ -102,6 +105,7 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
102
105
|
this.commRates = new Map();
|
|
103
106
|
this.placeOrders = new Map();
|
|
104
107
|
this.cancelOrders = new Map();
|
|
108
|
+
this.orderStatistics = new Map();
|
|
105
109
|
this.marginRatesQueue = new Denque();
|
|
106
110
|
this.commRatesQueue = new Denque();
|
|
107
111
|
this.accountsQueue = new Denque();
|
|
@@ -151,6 +155,7 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
151
155
|
if (this.tradingDay !== tradingDay) {
|
|
152
156
|
this.marginRates.clear();
|
|
153
157
|
this.commRates.clear();
|
|
158
|
+
this.orderStatistics.clear();
|
|
154
159
|
this.tradingDay = tradingDay;
|
|
155
160
|
}
|
|
156
161
|
|
|
@@ -349,12 +354,28 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
349
354
|
orderData.volume,
|
|
350
355
|
);
|
|
351
356
|
}
|
|
357
|
+
|
|
358
|
+
const statistic = this._ensureOrderStatistic(symbol);
|
|
359
|
+
|
|
360
|
+
statistic.entrusts += 1;
|
|
352
361
|
}
|
|
353
362
|
|
|
354
363
|
this.receivers.forEach((receiver) => receiver.onEntrust(orderData));
|
|
355
364
|
}
|
|
356
365
|
break;
|
|
357
366
|
|
|
367
|
+
case "filled":
|
|
368
|
+
{
|
|
369
|
+
const symbol = this._toSymbol(order.InstrumentID);
|
|
370
|
+
|
|
371
|
+
if (symbol) {
|
|
372
|
+
const statistic = this._ensureOrderStatistic(symbol);
|
|
373
|
+
|
|
374
|
+
statistic.filleds += 1;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
break;
|
|
378
|
+
|
|
358
379
|
case "canceled":
|
|
359
380
|
{
|
|
360
381
|
const orderData = this._toOrderData(order);
|
|
@@ -376,6 +397,10 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
376
397
|
orderData.volume,
|
|
377
398
|
);
|
|
378
399
|
}
|
|
400
|
+
|
|
401
|
+
const statistic = this._ensureOrderStatistic(symbol);
|
|
402
|
+
|
|
403
|
+
statistic.cancels += 1;
|
|
379
404
|
}
|
|
380
405
|
|
|
381
406
|
this.receivers.forEach((receiver) => receiver.onCancel(orderData));
|
|
@@ -385,6 +410,14 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
385
410
|
case "rejected":
|
|
386
411
|
{
|
|
387
412
|
const orderData = this._toOrderData(order);
|
|
413
|
+
const symbol = this._toSymbol(order.InstrumentID);
|
|
414
|
+
|
|
415
|
+
if (symbol) {
|
|
416
|
+
const statistic = this._ensureOrderStatistic(symbol);
|
|
417
|
+
|
|
418
|
+
statistic.rejects += 1;
|
|
419
|
+
}
|
|
420
|
+
|
|
388
421
|
this.receivers.forEach((receiver) => receiver.onReject(orderData));
|
|
389
422
|
}
|
|
390
423
|
break;
|
|
@@ -534,6 +567,7 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
534
567
|
if (options.isLast) {
|
|
535
568
|
const positionDetails = this.positionDetails.map(
|
|
536
569
|
this._toPositionDetail,
|
|
570
|
+
this,
|
|
537
571
|
);
|
|
538
572
|
const receivers = this.positionDetailsQueue.toArray();
|
|
539
573
|
|
|
@@ -615,6 +649,28 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
615
649
|
return this.tradingDay;
|
|
616
650
|
}
|
|
617
651
|
|
|
652
|
+
getOrderStatistics() {
|
|
653
|
+
const statistics = Array.from(this.orderStatistics.values());
|
|
654
|
+
return statistics.map((stat) => Object.freeze({ ...stat }));
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
getOrderStatistic(symbol: string) {
|
|
658
|
+
const statistic = this.orderStatistics.get(symbol);
|
|
659
|
+
|
|
660
|
+
if (!statistic) {
|
|
661
|
+
return Object.freeze({
|
|
662
|
+
symbol: symbol,
|
|
663
|
+
places: 0,
|
|
664
|
+
entrusts: 0,
|
|
665
|
+
filleds: 0,
|
|
666
|
+
cancels: 0,
|
|
667
|
+
rejects: 0,
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
return Object.freeze({ ...statistic });
|
|
672
|
+
}
|
|
673
|
+
|
|
618
674
|
queryCommissionRate(symbol: string, receiver: ICommissionRateReceiver) {
|
|
619
675
|
const [instrumentId] = parseSymbol(symbol);
|
|
620
676
|
const commRate = this.commRates.get(instrumentId);
|
|
@@ -850,6 +906,10 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
850
906
|
return;
|
|
851
907
|
}
|
|
852
908
|
|
|
909
|
+
const statistic = this._ensureOrderStatistic(symbol);
|
|
910
|
+
|
|
911
|
+
statistic.places += 1;
|
|
912
|
+
|
|
853
913
|
this.placeOrders.set(requestId, receiver);
|
|
854
914
|
|
|
855
915
|
const receiptId = `${this.frontId}:${this.sessionId}:${orderRef}`;
|
|
@@ -1018,7 +1078,7 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
1018
1078
|
}
|
|
1019
1079
|
}
|
|
1020
1080
|
|
|
1021
|
-
private _ensurePositionInfo(symbol: string) {
|
|
1081
|
+
private _ensurePositionInfo(symbol: string): PositionInfo {
|
|
1022
1082
|
let position = this.positions.get(symbol);
|
|
1023
1083
|
|
|
1024
1084
|
if (!position) {
|
|
@@ -1041,6 +1101,25 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
1041
1101
|
return position;
|
|
1042
1102
|
}
|
|
1043
1103
|
|
|
1104
|
+
private _ensureOrderStatistic(symbol: string): OrderStat {
|
|
1105
|
+
let statistic = this.orderStatistics.get(symbol);
|
|
1106
|
+
|
|
1107
|
+
if (!statistic) {
|
|
1108
|
+
statistic = {
|
|
1109
|
+
symbol: symbol,
|
|
1110
|
+
places: 0,
|
|
1111
|
+
entrusts: 0,
|
|
1112
|
+
filleds: 0,
|
|
1113
|
+
cancels: 0,
|
|
1114
|
+
rejects: 0,
|
|
1115
|
+
};
|
|
1116
|
+
|
|
1117
|
+
this.orderStatistics.set(symbol, statistic);
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
return statistic;
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1044
1123
|
private _calcPosition(
|
|
1045
1124
|
symbol: string,
|
|
1046
1125
|
side: SideType,
|
|
@@ -1055,7 +1134,7 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
1055
1134
|
case "long":
|
|
1056
1135
|
position.today.long.position += volume;
|
|
1057
1136
|
|
|
1058
|
-
if (position.pending.long
|
|
1137
|
+
if (position.pending.long >= volume) {
|
|
1059
1138
|
position.pending.long -= volume;
|
|
1060
1139
|
} else {
|
|
1061
1140
|
position.pending.long = 0;
|
|
@@ -1065,7 +1144,7 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
1065
1144
|
case "short":
|
|
1066
1145
|
position.today.short.position += volume;
|
|
1067
1146
|
|
|
1068
|
-
if (position.pending.short
|
|
1147
|
+
if (position.pending.short >= volume) {
|
|
1069
1148
|
position.pending.short -= volume;
|
|
1070
1149
|
} else {
|
|
1071
1150
|
position.pending.short = 0;
|
|
@@ -1077,65 +1156,65 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
1077
1156
|
case "close":
|
|
1078
1157
|
switch (side) {
|
|
1079
1158
|
case "long":
|
|
1080
|
-
if (position.history.
|
|
1081
|
-
position.history.
|
|
1159
|
+
if (position.history.short.position >= volume) {
|
|
1160
|
+
position.history.short.position -= volume;
|
|
1082
1161
|
} else {
|
|
1083
|
-
const rest = volume - position.history.
|
|
1084
|
-
position.history.
|
|
1162
|
+
const rest = volume - position.history.short.position;
|
|
1163
|
+
position.history.short.position -=
|
|
1164
|
+
position.history.short.position;
|
|
1085
1165
|
|
|
1086
1166
|
if (rest > 0) {
|
|
1087
|
-
if (position.today.
|
|
1088
|
-
position.today.
|
|
1167
|
+
if (position.today.short.position >= rest) {
|
|
1168
|
+
position.today.short.position -= rest;
|
|
1089
1169
|
} else {
|
|
1090
|
-
position.today.
|
|
1170
|
+
position.today.short.position = 0;
|
|
1091
1171
|
}
|
|
1092
1172
|
}
|
|
1093
1173
|
}
|
|
1094
1174
|
|
|
1095
|
-
if (position.history.
|
|
1096
|
-
position.history.
|
|
1175
|
+
if (position.history.short.frozen >= volume) {
|
|
1176
|
+
position.history.short.frozen -= volume;
|
|
1097
1177
|
} else {
|
|
1098
|
-
const rest = volume - position.history.
|
|
1099
|
-
position.history.
|
|
1178
|
+
const rest = volume - position.history.short.frozen;
|
|
1179
|
+
position.history.short.frozen -= position.history.short.frozen;
|
|
1100
1180
|
|
|
1101
1181
|
if (rest > 0) {
|
|
1102
|
-
if (position.today.
|
|
1103
|
-
position.today.
|
|
1182
|
+
if (position.today.short.frozen >= rest) {
|
|
1183
|
+
position.today.short.frozen -= rest;
|
|
1104
1184
|
} else {
|
|
1105
|
-
position.today.
|
|
1185
|
+
position.today.short.frozen = 0;
|
|
1106
1186
|
}
|
|
1107
1187
|
}
|
|
1108
1188
|
}
|
|
1109
1189
|
break;
|
|
1110
1190
|
|
|
1111
1191
|
case "short":
|
|
1112
|
-
if (position.history.
|
|
1113
|
-
position.history.
|
|
1192
|
+
if (position.history.long.position >= volume) {
|
|
1193
|
+
position.history.long.position -= volume;
|
|
1114
1194
|
} else {
|
|
1115
|
-
const rest = volume - position.history.
|
|
1116
|
-
position.history.
|
|
1117
|
-
position.history.short.position;
|
|
1195
|
+
const rest = volume - position.history.long.position;
|
|
1196
|
+
position.history.long.position -= position.history.long.position;
|
|
1118
1197
|
|
|
1119
1198
|
if (rest > 0) {
|
|
1120
|
-
if (position.today.
|
|
1121
|
-
position.today.
|
|
1199
|
+
if (position.today.long.position >= rest) {
|
|
1200
|
+
position.today.long.position -= rest;
|
|
1122
1201
|
} else {
|
|
1123
|
-
position.today.
|
|
1202
|
+
position.today.long.position = 0;
|
|
1124
1203
|
}
|
|
1125
1204
|
}
|
|
1126
1205
|
}
|
|
1127
1206
|
|
|
1128
|
-
if (position.history.
|
|
1129
|
-
position.history.
|
|
1207
|
+
if (position.history.long.frozen >= volume) {
|
|
1208
|
+
position.history.long.frozen -= volume;
|
|
1130
1209
|
} else {
|
|
1131
|
-
const rest = volume - position.history.
|
|
1132
|
-
position.history.
|
|
1210
|
+
const rest = volume - position.history.long.frozen;
|
|
1211
|
+
position.history.long.frozen -= position.history.long.frozen;
|
|
1133
1212
|
|
|
1134
1213
|
if (rest > 0) {
|
|
1135
|
-
if (position.today.
|
|
1136
|
-
position.today.
|
|
1214
|
+
if (position.today.long.frozen >= rest) {
|
|
1215
|
+
position.today.long.frozen -= rest;
|
|
1137
1216
|
} else {
|
|
1138
|
-
position.today.
|
|
1217
|
+
position.today.long.frozen = 0;
|
|
1139
1218
|
}
|
|
1140
1219
|
}
|
|
1141
1220
|
}
|
|
@@ -1146,30 +1225,30 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
1146
1225
|
case "close-today":
|
|
1147
1226
|
switch (side) {
|
|
1148
1227
|
case "long":
|
|
1149
|
-
if (position.today.
|
|
1150
|
-
position.today.
|
|
1228
|
+
if (position.today.short.position >= volume) {
|
|
1229
|
+
position.today.short.position -= volume;
|
|
1151
1230
|
} else {
|
|
1152
|
-
position.today.
|
|
1231
|
+
position.today.short.position = 0;
|
|
1153
1232
|
}
|
|
1154
1233
|
|
|
1155
|
-
if (position.today.
|
|
1156
|
-
position.today.
|
|
1234
|
+
if (position.today.short.frozen >= volume) {
|
|
1235
|
+
position.today.short.frozen -= volume;
|
|
1157
1236
|
} else {
|
|
1158
|
-
position.today.
|
|
1237
|
+
position.today.short.frozen = 0;
|
|
1159
1238
|
}
|
|
1160
1239
|
break;
|
|
1161
1240
|
|
|
1162
1241
|
case "short":
|
|
1163
|
-
if (position.today.
|
|
1164
|
-
position.today.
|
|
1242
|
+
if (position.today.long.position >= volume) {
|
|
1243
|
+
position.today.long.position -= volume;
|
|
1165
1244
|
} else {
|
|
1166
|
-
position.today.
|
|
1245
|
+
position.today.long.position = 0;
|
|
1167
1246
|
}
|
|
1168
1247
|
|
|
1169
|
-
if (position.today.
|
|
1170
|
-
position.today.
|
|
1248
|
+
if (position.today.long.frozen >= volume) {
|
|
1249
|
+
position.today.long.frozen -= volume;
|
|
1171
1250
|
} else {
|
|
1172
|
-
position.today.
|
|
1251
|
+
position.today.long.frozen = 0;
|
|
1173
1252
|
}
|
|
1174
1253
|
break;
|
|
1175
1254
|
}
|
|
@@ -1243,11 +1322,11 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
1243
1322
|
case "close":
|
|
1244
1323
|
switch (side) {
|
|
1245
1324
|
case "long":
|
|
1246
|
-
position.history.
|
|
1325
|
+
position.history.short.frozen += volume;
|
|
1247
1326
|
break;
|
|
1248
1327
|
|
|
1249
1328
|
case "short":
|
|
1250
|
-
position.history.
|
|
1329
|
+
position.history.long.frozen += volume;
|
|
1251
1330
|
break;
|
|
1252
1331
|
}
|
|
1253
1332
|
break;
|
|
@@ -1255,11 +1334,11 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
1255
1334
|
case "close-today":
|
|
1256
1335
|
switch (side) {
|
|
1257
1336
|
case "long":
|
|
1258
|
-
position.today.
|
|
1337
|
+
position.today.short.frozen += volume;
|
|
1259
1338
|
break;
|
|
1260
1339
|
|
|
1261
1340
|
case "short":
|
|
1262
|
-
position.today.
|
|
1341
|
+
position.today.long.frozen += volume;
|
|
1263
1342
|
break;
|
|
1264
1343
|
}
|
|
1265
1344
|
break;
|
|
@@ -1282,19 +1361,19 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
1282
1361
|
case "close":
|
|
1283
1362
|
switch (side) {
|
|
1284
1363
|
case "long":
|
|
1285
|
-
if (position.history.
|
|
1286
|
-
position.history.
|
|
1364
|
+
if (position.history.short.frozen >= volume) {
|
|
1365
|
+
position.history.short.frozen -= volume;
|
|
1287
1366
|
} else {
|
|
1288
|
-
position.history.
|
|
1367
|
+
position.history.short.frozen = 0;
|
|
1289
1368
|
}
|
|
1290
1369
|
|
|
1291
1370
|
break;
|
|
1292
1371
|
|
|
1293
1372
|
case "short":
|
|
1294
|
-
if (position.history.
|
|
1295
|
-
position.history.
|
|
1373
|
+
if (position.history.long.frozen >= volume) {
|
|
1374
|
+
position.history.long.frozen -= volume;
|
|
1296
1375
|
} else {
|
|
1297
|
-
position.history.
|
|
1376
|
+
position.history.long.frozen = 0;
|
|
1298
1377
|
}
|
|
1299
1378
|
break;
|
|
1300
1379
|
}
|
|
@@ -1303,18 +1382,18 @@ export class Trader extends CTPProvider implements ITraderProvider {
|
|
|
1303
1382
|
case "close-today":
|
|
1304
1383
|
switch (side) {
|
|
1305
1384
|
case "long":
|
|
1306
|
-
if (position.today.
|
|
1307
|
-
position.today.
|
|
1385
|
+
if (position.today.short.frozen >= volume) {
|
|
1386
|
+
position.today.short.frozen -= volume;
|
|
1308
1387
|
} else {
|
|
1309
|
-
position.today.
|
|
1388
|
+
position.today.short.frozen = 0;
|
|
1310
1389
|
}
|
|
1311
1390
|
break;
|
|
1312
1391
|
|
|
1313
1392
|
case "short":
|
|
1314
|
-
if (position.today.
|
|
1315
|
-
position.today.
|
|
1393
|
+
if (position.today.long.frozen >= volume) {
|
|
1394
|
+
position.today.long.frozen -= volume;
|
|
1316
1395
|
} else {
|
|
1317
|
-
position.today.
|
|
1396
|
+
position.today.long.frozen = 0;
|
|
1318
1397
|
}
|
|
1319
1398
|
break;
|
|
1320
1399
|
}
|