dukascopy-node-plus 1.0.0 → 1.1.0
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/README.md +17 -1
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.js +198 -12
- package/dist/esm/{chunk-QOULS5Y3.js → chunk-D3M3SVMW.js} +184 -14
- package/dist/esm/chunk-DWZJECKF.js +6 -0
- package/dist/esm/chunk-KWYYNULA.js +184 -0
- package/dist/esm/cli/index.js +16 -6
- package/dist/esm/index.example.js +27 -0
- package/dist/esm/index.js +11 -34
- package/dist/index.d.mts +6803 -0
- package/dist/index.d.ts +6762 -6684
- package/dist/index.example.d.mts +2 -0
- package/dist/index.example.d.ts +2 -0
- package/dist/index.example.js +13865 -0
- package/dist/index.js +332 -12
- package/package.json +25 -29
|
@@ -3,7 +3,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
3
3
|
}) : x)(function(x) {
|
|
4
4
|
if (typeof require !== "undefined")
|
|
5
5
|
return require.apply(this, arguments);
|
|
6
|
-
throw
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
7
|
});
|
|
8
8
|
|
|
9
9
|
// src/utils/instrument-meta-data/generated/instrument-enum.ts
|
|
@@ -230,6 +230,9 @@ var Instrument = /* @__PURE__ */ ((Instrument2) => {
|
|
|
230
230
|
Instrument2["bbwiususd"] = "bbwiususd";
|
|
231
231
|
Instrument2["bbyususd"] = "bbyususd";
|
|
232
232
|
Instrument2["bciteur"] = "bciteur";
|
|
233
|
+
Instrument2["bchchf"] = "bchchf";
|
|
234
|
+
Instrument2["bcheur"] = "bcheur";
|
|
235
|
+
Instrument2["bchgbp"] = "bchgbp";
|
|
233
236
|
Instrument2["bchusd"] = "bchusd";
|
|
234
237
|
Instrument2["bdevgbgbx"] = "bdevgbgbx";
|
|
235
238
|
Instrument2["bdxususd"] = "bdxususd";
|
|
@@ -270,6 +273,9 @@ var Instrument = /* @__PURE__ */ ((Instrument2) => {
|
|
|
270
273
|
Instrument2["brxususd"] = "brxususd";
|
|
271
274
|
Instrument2["bsxususd"] = "bsxususd";
|
|
272
275
|
Instrument2["btgbgbx"] = "btgbgbx";
|
|
276
|
+
Instrument2["btcchf"] = "btcchf";
|
|
277
|
+
Instrument2["btceur"] = "btceur";
|
|
278
|
+
Instrument2["btcgbp"] = "btcgbp";
|
|
273
279
|
Instrument2["btcusd"] = "btcusd";
|
|
274
280
|
Instrument2["bundtreur"] = "bundtreur";
|
|
275
281
|
Instrument2["burlususd"] = "burlususd";
|
|
@@ -460,6 +466,9 @@ var Instrument = /* @__PURE__ */ ((Instrument2) => {
|
|
|
460
466
|
Instrument2["esususd"] = "esususd";
|
|
461
467
|
Instrument2["essususd"] = "essususd";
|
|
462
468
|
Instrument2["estcususd"] = "estcususd";
|
|
469
|
+
Instrument2["ethchf"] = "ethchf";
|
|
470
|
+
Instrument2["etheur"] = "etheur";
|
|
471
|
+
Instrument2["ethgbp"] = "ethgbp";
|
|
463
472
|
Instrument2["ethusd"] = "ethusd";
|
|
464
473
|
Instrument2["etnususd"] = "etnususd";
|
|
465
474
|
Instrument2["etsyususd"] = "etsyususd";
|
|
@@ -728,6 +737,9 @@ var Instrument = /* @__PURE__ */ ((Instrument2) => {
|
|
|
728
737
|
Instrument2["lsegbgbx"] = "lsegbgbx";
|
|
729
738
|
Instrument2["lsiususd"] = "lsiususd";
|
|
730
739
|
Instrument2["lstrususd"] = "lstrususd";
|
|
740
|
+
Instrument2["ltcchf"] = "ltcchf";
|
|
741
|
+
Instrument2["ltceur"] = "ltceur";
|
|
742
|
+
Instrument2["ltcgbp"] = "ltcgbp";
|
|
731
743
|
Instrument2["ltcusd"] = "ltcusd";
|
|
732
744
|
Instrument2["luluususd"] = "luluususd";
|
|
733
745
|
Instrument2["luvususd"] = "luvususd";
|
|
@@ -1231,6 +1243,9 @@ var Instrument = /* @__PURE__ */ ((Instrument2) => {
|
|
|
1231
1243
|
Instrument2["xlfususd"] = "xlfususd";
|
|
1232
1244
|
Instrument2["xliususd"] = "xliususd";
|
|
1233
1245
|
Instrument2["xlkususd"] = "xlkususd";
|
|
1246
|
+
Instrument2["xlmchf"] = "xlmchf";
|
|
1247
|
+
Instrument2["xlmeur"] = "xlmeur";
|
|
1248
|
+
Instrument2["xlmgbp"] = "xlmgbp";
|
|
1234
1249
|
Instrument2["xlmusd"] = "xlmusd";
|
|
1235
1250
|
Instrument2["xlnxususd"] = "xlnxususd";
|
|
1236
1251
|
Instrument2["xlpususd"] = "xlpususd";
|
|
@@ -1292,8 +1307,17 @@ var Format = /* @__PURE__ */ ((Format2) => {
|
|
|
1292
1307
|
|
|
1293
1308
|
// src/config/volume-unit.ts
|
|
1294
1309
|
var VolumeUnit = {
|
|
1310
|
+
/**
|
|
1311
|
+
* A single unit of a currency, commodity, or security.
|
|
1312
|
+
*/
|
|
1295
1313
|
units: "units",
|
|
1314
|
+
/**
|
|
1315
|
+
* A thousand units of a currency, commodity, or security.
|
|
1316
|
+
*/
|
|
1296
1317
|
thousands: "thousands",
|
|
1318
|
+
/**
|
|
1319
|
+
* A million units of a currency, commodity, or security.
|
|
1320
|
+
*/
|
|
1297
1321
|
millions: "millions"
|
|
1298
1322
|
};
|
|
1299
1323
|
|
|
@@ -3344,7 +3368,7 @@ var instrument_meta_data_default = {
|
|
|
3344
3368
|
batusd: {
|
|
3345
3369
|
name: "BAT/USD",
|
|
3346
3370
|
description: "Basic Attention Token vs US Dollar",
|
|
3347
|
-
decimalFactor:
|
|
3371
|
+
decimalFactor: 1e3,
|
|
3348
3372
|
startHourForTicks: "2019-08-05T00:00:02.214Z",
|
|
3349
3373
|
startDayForMinuteCandles: "2019-08-05T00:00:00.000Z",
|
|
3350
3374
|
startMonthForHourlyCandles: "2019-08-05T00:00:00.000Z",
|
|
@@ -3422,6 +3446,33 @@ var instrument_meta_data_default = {
|
|
|
3422
3446
|
startMonthForHourlyCandles: "2020-11-02T12:00:00.000Z",
|
|
3423
3447
|
startYearForDailyCandles: "2020-11-02T00:00:00.000Z"
|
|
3424
3448
|
},
|
|
3449
|
+
bchchf: {
|
|
3450
|
+
name: "BCH/CHF",
|
|
3451
|
+
description: "Bitcoin Cash vs Swiss Franc",
|
|
3452
|
+
decimalFactor: 10,
|
|
3453
|
+
startHourForTicks: "2023-03-14T14:52:58.644Z",
|
|
3454
|
+
startDayForMinuteCandles: "2023-03-14T14:52:00.000Z",
|
|
3455
|
+
startMonthForHourlyCandles: "2023-03-14T14:00:00.000Z",
|
|
3456
|
+
startYearForDailyCandles: "2023-03-14T00:00:00.000Z"
|
|
3457
|
+
},
|
|
3458
|
+
bcheur: {
|
|
3459
|
+
name: "BCH/EUR",
|
|
3460
|
+
description: "Bitcoin Cash vs Euro",
|
|
3461
|
+
decimalFactor: 10,
|
|
3462
|
+
startHourForTicks: "2023-03-14T14:53:02.753Z",
|
|
3463
|
+
startDayForMinuteCandles: "2023-03-14T14:53:00.000Z",
|
|
3464
|
+
startMonthForHourlyCandles: "2023-03-14T14:00:00.000Z",
|
|
3465
|
+
startYearForDailyCandles: "2023-03-14T00:00:00.000Z"
|
|
3466
|
+
},
|
|
3467
|
+
bchgbp: {
|
|
3468
|
+
name: "BCH/GBP",
|
|
3469
|
+
description: "Bitcoin Cash vs Pound Sterling",
|
|
3470
|
+
decimalFactor: 10,
|
|
3471
|
+
startHourForTicks: "2023-03-14T14:53:02.089Z",
|
|
3472
|
+
startDayForMinuteCandles: "2023-03-14T14:53:00.000Z",
|
|
3473
|
+
startMonthForHourlyCandles: "2023-03-14T14:00:00.000Z",
|
|
3474
|
+
startYearForDailyCandles: "2023-03-14T00:00:00.000Z"
|
|
3475
|
+
},
|
|
3425
3476
|
bchusd: {
|
|
3426
3477
|
name: "BCH/USD",
|
|
3427
3478
|
description: "Bitcoin Cash vs US dollar",
|
|
@@ -3782,6 +3833,33 @@ var instrument_meta_data_default = {
|
|
|
3782
3833
|
startMonthForHourlyCandles: "2011-01-04T08:00:00.000Z",
|
|
3783
3834
|
startYearForDailyCandles: "2011-01-04T00:00:00.000Z"
|
|
3784
3835
|
},
|
|
3836
|
+
btcchf: {
|
|
3837
|
+
name: "BTC/CHF",
|
|
3838
|
+
description: "Bitcoin vs Swiss Frank",
|
|
3839
|
+
decimalFactor: 10,
|
|
3840
|
+
startHourForTicks: "2023-03-14T14:53:06.990Z",
|
|
3841
|
+
startDayForMinuteCandles: "2023-03-14T14:53:00.000Z",
|
|
3842
|
+
startMonthForHourlyCandles: "2023-03-14T14:00:00.000Z",
|
|
3843
|
+
startYearForDailyCandles: "2023-03-14T00:00:00.000Z"
|
|
3844
|
+
},
|
|
3845
|
+
btceur: {
|
|
3846
|
+
name: "BTC/EUR",
|
|
3847
|
+
description: "Bitcoin vs Euro",
|
|
3848
|
+
decimalFactor: 10,
|
|
3849
|
+
startHourForTicks: "2018-05-15T10:25:32.340Z",
|
|
3850
|
+
startDayForMinuteCandles: "2018-05-15T10:24:00.000Z",
|
|
3851
|
+
startMonthForHourlyCandles: "2018-05-15T10:00:00.000Z",
|
|
3852
|
+
startYearForDailyCandles: "2018-05-15T00:00:00.000Z"
|
|
3853
|
+
},
|
|
3854
|
+
btcgbp: {
|
|
3855
|
+
name: "BTC/GBP",
|
|
3856
|
+
description: "Bitcoin vs Pound Sterling",
|
|
3857
|
+
decimalFactor: 10,
|
|
3858
|
+
startHourForTicks: "2023-03-14T15:03:45.307Z",
|
|
3859
|
+
startDayForMinuteCandles: "2023-03-14T15:03:00.000Z",
|
|
3860
|
+
startMonthForHourlyCandles: "2023-03-14T15:00:00.000Z",
|
|
3861
|
+
startYearForDailyCandles: "2023-03-14T00:00:00.000Z"
|
|
3862
|
+
},
|
|
3785
3863
|
btcusd: {
|
|
3786
3864
|
name: "BTC/USD",
|
|
3787
3865
|
description: "Bitcoin vs US Dollar",
|
|
@@ -5492,6 +5570,33 @@ var instrument_meta_data_default = {
|
|
|
5492
5570
|
startMonthForHourlyCandles: "2022-05-12T13:00:00.000Z",
|
|
5493
5571
|
startYearForDailyCandles: "2022-05-12T00:00:00.000Z"
|
|
5494
5572
|
},
|
|
5573
|
+
ethchf: {
|
|
5574
|
+
name: "ETH/CHF",
|
|
5575
|
+
description: "Ether vs Swiss Franc",
|
|
5576
|
+
decimalFactor: 10,
|
|
5577
|
+
startHourForTicks: "2023-03-14T14:53:03.726Z",
|
|
5578
|
+
startDayForMinuteCandles: "2023-03-14T14:53:00.000Z",
|
|
5579
|
+
startMonthForHourlyCandles: "2023-03-14T14:00:00.000Z",
|
|
5580
|
+
startYearForDailyCandles: "2023-03-14T00:00:00.000Z"
|
|
5581
|
+
},
|
|
5582
|
+
etheur: {
|
|
5583
|
+
name: "ETH/EUR",
|
|
5584
|
+
description: "Ether vs Euro",
|
|
5585
|
+
decimalFactor: 10,
|
|
5586
|
+
startHourForTicks: "2023-03-14T14:53:03.677Z",
|
|
5587
|
+
startDayForMinuteCandles: "2023-03-14T14:53:00.000Z",
|
|
5588
|
+
startMonthForHourlyCandles: "2023-03-14T14:00:00.000Z",
|
|
5589
|
+
startYearForDailyCandles: "2023-03-14T00:00:00.000Z"
|
|
5590
|
+
},
|
|
5591
|
+
ethgbp: {
|
|
5592
|
+
name: "ETH/GBP",
|
|
5593
|
+
description: "Ether vs Pound Sterling",
|
|
5594
|
+
decimalFactor: 10,
|
|
5595
|
+
startHourForTicks: "2023-03-14T14:53:03.676Z",
|
|
5596
|
+
startDayForMinuteCandles: "2023-03-14T14:53:00.000Z",
|
|
5597
|
+
startMonthForHourlyCandles: "2023-03-14T14:00:00.000Z",
|
|
5598
|
+
startYearForDailyCandles: "2023-03-14T00:00:00.000Z"
|
|
5599
|
+
},
|
|
5495
5600
|
ethusd: {
|
|
5496
5601
|
name: "ETH/USD",
|
|
5497
5602
|
description: "Ether vs US Dollar",
|
|
@@ -7904,6 +8009,33 @@ var instrument_meta_data_default = {
|
|
|
7904
8009
|
startMonthForHourlyCandles: "2022-05-13T13:00:00.000Z",
|
|
7905
8010
|
startYearForDailyCandles: "2022-05-13T00:00:00.000Z"
|
|
7906
8011
|
},
|
|
8012
|
+
ltcchf: {
|
|
8013
|
+
name: "LTC/CHF",
|
|
8014
|
+
description: "Litecoin vs Swiss Franc",
|
|
8015
|
+
decimalFactor: 10,
|
|
8016
|
+
startHourForTicks: "2023-03-14T14:52:50.061Z",
|
|
8017
|
+
startDayForMinuteCandles: "2023-03-14T14:52:00.000Z",
|
|
8018
|
+
startMonthForHourlyCandles: "2023-03-14T14:00:00.000Z",
|
|
8019
|
+
startYearForDailyCandles: "2023-03-14T00:00:00.000Z"
|
|
8020
|
+
},
|
|
8021
|
+
ltceur: {
|
|
8022
|
+
name: "LTC/EUR",
|
|
8023
|
+
description: "Litecoin vs Euro",
|
|
8024
|
+
decimalFactor: 10,
|
|
8025
|
+
startHourForTicks: "2023-03-14T14:55:12.375Z",
|
|
8026
|
+
startDayForMinuteCandles: "2023-03-14T14:55:00.000Z",
|
|
8027
|
+
startMonthForHourlyCandles: "2023-03-14T14:00:00.000Z",
|
|
8028
|
+
startYearForDailyCandles: "2023-03-14T00:00:00.000Z"
|
|
8029
|
+
},
|
|
8030
|
+
ltcgbp: {
|
|
8031
|
+
name: "LTC/GBP",
|
|
8032
|
+
description: "Pound Sterling",
|
|
8033
|
+
decimalFactor: 10,
|
|
8034
|
+
startHourForTicks: "2023-03-14T14:52:50.074Z",
|
|
8035
|
+
startDayForMinuteCandles: "2023-03-14T14:52:00.000Z",
|
|
8036
|
+
startMonthForHourlyCandles: "2023-03-14T14:00:00.000Z",
|
|
8037
|
+
startYearForDailyCandles: "2023-03-14T00:00:00.000Z"
|
|
8038
|
+
},
|
|
7907
8039
|
ltcusd: {
|
|
7908
8040
|
name: "LTC/USD",
|
|
7909
8041
|
description: "Litecoin vs US Dollar",
|
|
@@ -12431,6 +12563,33 @@ var instrument_meta_data_default = {
|
|
|
12431
12563
|
startMonthForHourlyCandles: "2017-11-15T16:00:00.000Z",
|
|
12432
12564
|
startYearForDailyCandles: "2017-11-15T00:00:00.000Z"
|
|
12433
12565
|
},
|
|
12566
|
+
xlmchf: {
|
|
12567
|
+
name: "XLM/CHF",
|
|
12568
|
+
description: "Stellar vs Swiss Franc",
|
|
12569
|
+
decimalFactor: 1e5,
|
|
12570
|
+
startHourForTicks: "2023-03-14T14:53:03.870Z",
|
|
12571
|
+
startDayForMinuteCandles: "2023-03-14T14:53:00.000Z",
|
|
12572
|
+
startMonthForHourlyCandles: "2023-03-14T14:00:00.000Z",
|
|
12573
|
+
startYearForDailyCandles: "2023-03-14T00:00:00.000Z"
|
|
12574
|
+
},
|
|
12575
|
+
xlmeur: {
|
|
12576
|
+
name: "XLM/EUR",
|
|
12577
|
+
description: "Stellar vs Euro",
|
|
12578
|
+
decimalFactor: 1e5,
|
|
12579
|
+
startHourForTicks: "2023-03-14T14:53:03.820Z",
|
|
12580
|
+
startDayForMinuteCandles: "2023-03-14T14:53:00.000Z",
|
|
12581
|
+
startMonthForHourlyCandles: "2023-03-14T14:00:00.000Z",
|
|
12582
|
+
startYearForDailyCandles: "2023-03-14T00:00:00.000Z"
|
|
12583
|
+
},
|
|
12584
|
+
xlmgbp: {
|
|
12585
|
+
name: "XLM/GBP",
|
|
12586
|
+
description: "Stellar vs Pound Sterling",
|
|
12587
|
+
decimalFactor: 1e5,
|
|
12588
|
+
startHourForTicks: "2023-03-14T14:53:03.821Z",
|
|
12589
|
+
startDayForMinuteCandles: "2023-03-14T14:53:00.000Z",
|
|
12590
|
+
startMonthForHourlyCandles: "2023-03-14T14:00:00.000Z",
|
|
12591
|
+
startYearForDailyCandles: "2023-03-14T00:00:00.000Z"
|
|
12592
|
+
},
|
|
12434
12593
|
xlmusd: {
|
|
12435
12594
|
name: "XLM/USD",
|
|
12436
12595
|
description: "Stellar vs US Dollar",
|
|
@@ -12704,7 +12863,7 @@ function normaliseDates({
|
|
|
12704
12863
|
minFromIsoDate = startYearForDailyCandles;
|
|
12705
12864
|
}
|
|
12706
12865
|
let minFromDate = new Date(minFromIsoDate);
|
|
12707
|
-
let maxToDate = new Date();
|
|
12866
|
+
let maxToDate = /* @__PURE__ */ new Date();
|
|
12708
12867
|
if (utcOffset) {
|
|
12709
12868
|
startDate.setUTCMinutes(startDate.getUTCMinutes() + utcOffset);
|
|
12710
12869
|
endDate.setUTCMinutes(endDate.getUTCMinutes() + utcOffset);
|
|
@@ -12726,7 +12885,7 @@ function getYMDH(date) {
|
|
|
12726
12885
|
}
|
|
12727
12886
|
function getStartOfUtc(date, period, offset = 0) {
|
|
12728
12887
|
const [year, month, day, hours] = getYMDH(date);
|
|
12729
|
-
let startOfUtc = new Date();
|
|
12888
|
+
let startOfUtc = /* @__PURE__ */ new Date();
|
|
12730
12889
|
if (period === "hour") {
|
|
12731
12890
|
startOfUtc = new Date(Date.UTC(year, month, day, hours + offset));
|
|
12732
12891
|
} else if (period === "day") {
|
|
@@ -12740,7 +12899,7 @@ function getStartOfUtc(date, period, offset = 0) {
|
|
|
12740
12899
|
}
|
|
12741
12900
|
function getIsCurrentObj(date) {
|
|
12742
12901
|
const [year, month, day, hours] = getYMDH(date);
|
|
12743
|
-
const [currentYear, currentMonth, currentDay, currentHours] = getYMDH(new Date());
|
|
12902
|
+
const [currentYear, currentMonth, currentDay, currentHours] = getYMDH(/* @__PURE__ */ new Date());
|
|
12744
12903
|
const isCurrentYear = year === currentYear;
|
|
12745
12904
|
const isCurrentMonth = isCurrentYear && month === currentMonth;
|
|
12746
12905
|
const isCurrentDay = isCurrentMonth && day === currentDay;
|
|
@@ -12902,7 +13061,7 @@ function getConstructor(instrument, priceType, endDate) {
|
|
|
12902
13061
|
};
|
|
12903
13062
|
}
|
|
12904
13063
|
function getDateLimit(startDate, endDate, timeframe) {
|
|
12905
|
-
const nowDate = new Date();
|
|
13064
|
+
const nowDate = /* @__PURE__ */ new Date();
|
|
12906
13065
|
const adjustedEndDate = endDate < nowDate ? endDate : nowDate;
|
|
12907
13066
|
let dateLimit = adjustedEndDate;
|
|
12908
13067
|
if (timeframe === "tick" /* tick */ || timeframe === "s1" /* s1 */ || timeframe === "m1" /* m1 */ || timeframe === "m5" /* m5 */ || timeframe === "m15" /* m15 */ || timeframe === "m30" /* m30 */) {
|
|
@@ -12937,6 +13096,16 @@ function generateUrls({
|
|
|
12937
13096
|
// src/buffer-fetcher/index.ts
|
|
12938
13097
|
import fetch, { Response } from "node-fetch";
|
|
12939
13098
|
var BufferFetcher = class {
|
|
13099
|
+
batchSize;
|
|
13100
|
+
pauseBetweenBatchesMs;
|
|
13101
|
+
onItemFetch;
|
|
13102
|
+
onBatchFetch;
|
|
13103
|
+
fetcherFn;
|
|
13104
|
+
retryCount;
|
|
13105
|
+
retryOnEmpty;
|
|
13106
|
+
pauseBetweenRetriesMs;
|
|
13107
|
+
failAfterRetryCount;
|
|
13108
|
+
cacheManager;
|
|
12940
13109
|
constructor({
|
|
12941
13110
|
batchSize = 10,
|
|
12942
13111
|
pauseBetweenBatchesMs = 1e3,
|
|
@@ -12981,6 +13150,9 @@ var BufferFetcher = class {
|
|
|
12981
13150
|
})
|
|
12982
13151
|
);
|
|
12983
13152
|
}
|
|
13153
|
+
/**
|
|
13154
|
+
* @experimental
|
|
13155
|
+
*/
|
|
12984
13156
|
async fetch_optimized(urls) {
|
|
12985
13157
|
const batches = splitArrayInChunks(urls, this.batchSize);
|
|
12986
13158
|
for (let i = 0, n = batches.length; i < n; i++) {
|
|
@@ -13038,7 +13210,6 @@ var BufferFetcher = class {
|
|
|
13038
13210
|
return bufferObjects;
|
|
13039
13211
|
}
|
|
13040
13212
|
async fetchBuffer(url) {
|
|
13041
|
-
var _a;
|
|
13042
13213
|
if (this.fetcherFn) {
|
|
13043
13214
|
return this.fetcherFn(url);
|
|
13044
13215
|
}
|
|
@@ -13058,7 +13229,7 @@ var BufferFetcher = class {
|
|
|
13058
13229
|
errorMsg = e instanceof Error ? e.message : JSON.stringify(e);
|
|
13059
13230
|
}
|
|
13060
13231
|
const isStatusOk = response.status === 200;
|
|
13061
|
-
const contentLength = Number(
|
|
13232
|
+
const contentLength = Number(response?.headers?.get("content-length") || 0);
|
|
13062
13233
|
const isResponseWithData = contentLength > 0;
|
|
13063
13234
|
isTrySuccess = isCallSuccess && isStatusOk;
|
|
13064
13235
|
if (this.retryOnEmpty) {
|
|
@@ -13153,7 +13324,7 @@ function getOHLC({
|
|
|
13153
13324
|
volumes
|
|
13154
13325
|
}) {
|
|
13155
13326
|
if (filterFlats) {
|
|
13156
|
-
input = input.filter((data) =>
|
|
13327
|
+
input = input.filter((data) => data?.[5] !== 0);
|
|
13157
13328
|
}
|
|
13158
13329
|
if (input.length === 0) {
|
|
13159
13330
|
return [];
|
|
@@ -13488,6 +13659,9 @@ import { resolve } from "path";
|
|
|
13488
13659
|
import { outputFile, remove, readFile, readdirSync, ensureDirSync } from "fs-extra";
|
|
13489
13660
|
var DEFAULT_CACHE_FOLDER = ".dukascopy-cache";
|
|
13490
13661
|
var CacheManager = class {
|
|
13662
|
+
cacheManifest;
|
|
13663
|
+
cacheFolderPath;
|
|
13664
|
+
cacheKeyFormatter;
|
|
13491
13665
|
constructor({
|
|
13492
13666
|
cacheFolderPath,
|
|
13493
13667
|
cacheKeyFormatter
|
|
@@ -13542,9 +13716,6 @@ function formatBytes(bytes, decimals = 2) {
|
|
|
13542
13716
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
|
|
13543
13717
|
}
|
|
13544
13718
|
|
|
13545
|
-
// package.json
|
|
13546
|
-
var version = "1.0.1";
|
|
13547
|
-
|
|
13548
13719
|
export {
|
|
13549
13720
|
__require,
|
|
13550
13721
|
Instrument,
|
|
@@ -13565,6 +13736,5 @@ export {
|
|
|
13565
13736
|
BufferFetcher,
|
|
13566
13737
|
processData,
|
|
13567
13738
|
CacheManager,
|
|
13568
|
-
formatBytes
|
|
13569
|
-
version
|
|
13739
|
+
formatBytes
|
|
13570
13740
|
};
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BufferFetcher,
|
|
3
|
+
CacheManager,
|
|
4
|
+
formatBytes,
|
|
5
|
+
generateUrls,
|
|
6
|
+
normaliseDates,
|
|
7
|
+
processData,
|
|
8
|
+
validateConfigNode
|
|
9
|
+
} from "./chunk-D3M3SVMW.js";
|
|
10
|
+
|
|
11
|
+
// src/output-formatter/index.ts
|
|
12
|
+
var candleHeaders = ["timestamp", "open", "high", "low", "close", "volume"];
|
|
13
|
+
var tickHeaders = ["timestamp", "askPrice", "bidPrice", "askVolume", "bidVolume"];
|
|
14
|
+
function formatOutput({
|
|
15
|
+
processedData,
|
|
16
|
+
format,
|
|
17
|
+
timeframe
|
|
18
|
+
}) {
|
|
19
|
+
if (processedData.length === 0) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
const bodyHeaders = timeframe === "tick" /* tick */ ? tickHeaders : candleHeaders;
|
|
23
|
+
if (format === "json" /* json */) {
|
|
24
|
+
const data = processedData.map((arr) => {
|
|
25
|
+
return arr.reduce((all, item, i) => {
|
|
26
|
+
const name = bodyHeaders[i];
|
|
27
|
+
all[name] = item;
|
|
28
|
+
return all;
|
|
29
|
+
}, {});
|
|
30
|
+
});
|
|
31
|
+
return data;
|
|
32
|
+
}
|
|
33
|
+
if (format === "csv" /* csv */) {
|
|
34
|
+
const csvHeaders = bodyHeaders.filter((_, i) => processedData[0][i] !== void 0);
|
|
35
|
+
const csv = [csvHeaders, ...processedData].map((arr) => arr.join(",")).join("\n");
|
|
36
|
+
return csv;
|
|
37
|
+
}
|
|
38
|
+
return processedData;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// src/getHistoricalRatesToStream.ts
|
|
42
|
+
import debug from "debug";
|
|
43
|
+
import { Readable, Transform } from "stream";
|
|
44
|
+
import { pipeline } from "stream/promises";
|
|
45
|
+
var DEBUG_NAMESPACE = "dukascopy-node";
|
|
46
|
+
async function getHistoricalRatesToStream(config) {
|
|
47
|
+
const stream = new Readable({
|
|
48
|
+
objectMode: true,
|
|
49
|
+
async read(_size) {
|
|
50
|
+
try {
|
|
51
|
+
const { input, isValid, validationErrors } = validateConfigNode(config);
|
|
52
|
+
debug(`${DEBUG_NAMESPACE}:config`)("%O", {
|
|
53
|
+
input,
|
|
54
|
+
isValid,
|
|
55
|
+
validationErrors
|
|
56
|
+
});
|
|
57
|
+
if (!isValid) {
|
|
58
|
+
this.emit("error", { validationErrors });
|
|
59
|
+
this.push(null);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const {
|
|
63
|
+
instrument,
|
|
64
|
+
dates: { from, to },
|
|
65
|
+
timeframe,
|
|
66
|
+
priceType,
|
|
67
|
+
volumes,
|
|
68
|
+
volumeUnits,
|
|
69
|
+
utcOffset,
|
|
70
|
+
ignoreFlats,
|
|
71
|
+
format,
|
|
72
|
+
batchSize,
|
|
73
|
+
pauseBetweenBatchesMs,
|
|
74
|
+
useCache,
|
|
75
|
+
cacheFolderPath,
|
|
76
|
+
retryCount,
|
|
77
|
+
pauseBetweenRetriesMs,
|
|
78
|
+
retryOnEmpty
|
|
79
|
+
} = input;
|
|
80
|
+
const [startDate, endDate] = normaliseDates({
|
|
81
|
+
instrument,
|
|
82
|
+
startDate: from,
|
|
83
|
+
endDate: to,
|
|
84
|
+
timeframe,
|
|
85
|
+
utcOffset
|
|
86
|
+
});
|
|
87
|
+
const [startDateMs, endDateMs] = [+startDate, +endDate];
|
|
88
|
+
const onItemFetch = process.env.DEBUG ? (url, buffer, isCacheHit) => {
|
|
89
|
+
debug(`${DEBUG_NAMESPACE}:fetcher`)(
|
|
90
|
+
url,
|
|
91
|
+
`| ${formatBytes(buffer.length)} |`,
|
|
92
|
+
`${isCacheHit ? "cache" : "network"}`
|
|
93
|
+
);
|
|
94
|
+
} : void 0;
|
|
95
|
+
const bufferFetcher = new BufferFetcher({
|
|
96
|
+
batchSize,
|
|
97
|
+
pauseBetweenBatchesMs,
|
|
98
|
+
cacheManager: useCache ? new CacheManager({ cacheFolderPath }) : void 0,
|
|
99
|
+
retryCount,
|
|
100
|
+
pauseBetweenRetriesMs,
|
|
101
|
+
onItemFetch,
|
|
102
|
+
retryOnEmpty
|
|
103
|
+
});
|
|
104
|
+
let firstLine = true;
|
|
105
|
+
let urlsProcessed = 0;
|
|
106
|
+
const urlsforFetchingData = generateUrls({
|
|
107
|
+
instrument: input.instrument,
|
|
108
|
+
timeframe: input.timeframe,
|
|
109
|
+
priceType: input.priceType,
|
|
110
|
+
startDate,
|
|
111
|
+
endDate
|
|
112
|
+
});
|
|
113
|
+
await pipeline(
|
|
114
|
+
Readable.from(urlsforFetchingData),
|
|
115
|
+
new Transform({
|
|
116
|
+
objectMode: true,
|
|
117
|
+
transform: async (url, _, callback) => {
|
|
118
|
+
const bufferObject = {
|
|
119
|
+
url,
|
|
120
|
+
buffer: await bufferFetcher.fetchBuffer(url),
|
|
121
|
+
isCacheHit: useCache
|
|
122
|
+
};
|
|
123
|
+
try {
|
|
124
|
+
const processedData = processData({
|
|
125
|
+
instrument: input.instrument,
|
|
126
|
+
requestedTimeframe: input.timeframe,
|
|
127
|
+
bufferObjects: [bufferObject],
|
|
128
|
+
priceType: input.priceType,
|
|
129
|
+
volumes: input.volumes,
|
|
130
|
+
volumeUnits: input.volumeUnits,
|
|
131
|
+
ignoreFlats: input.ignoreFlats
|
|
132
|
+
});
|
|
133
|
+
processedData.forEach((item) => {
|
|
134
|
+
const [timestamp] = item;
|
|
135
|
+
if (timestamp && timestamp >= startDateMs && timestamp < endDateMs) {
|
|
136
|
+
if (input.format === "array" /* array */) {
|
|
137
|
+
this.push(item);
|
|
138
|
+
} else {
|
|
139
|
+
const bodyHeaders = timeframe === "tick" /* tick */ ? tickHeaders : candleHeaders;
|
|
140
|
+
if (format === "json" /* json */) {
|
|
141
|
+
const data = item.reduce((all, item2, i) => {
|
|
142
|
+
const name = bodyHeaders[i];
|
|
143
|
+
all[name] = item2;
|
|
144
|
+
return all;
|
|
145
|
+
}, {});
|
|
146
|
+
this.push(data);
|
|
147
|
+
} else if (format === "csv" /* csv */) {
|
|
148
|
+
if (firstLine) {
|
|
149
|
+
const csvHeaders = bodyHeaders.join(",");
|
|
150
|
+
this.push(csvHeaders);
|
|
151
|
+
firstLine = false;
|
|
152
|
+
}
|
|
153
|
+
this.push(item.join(","));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
callback();
|
|
159
|
+
} catch (err) {
|
|
160
|
+
callback(err);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
).then(() => {
|
|
165
|
+
if (++urlsProcessed === urlsforFetchingData.length) {
|
|
166
|
+
this.push(null);
|
|
167
|
+
}
|
|
168
|
+
}).catch((err) => {
|
|
169
|
+
this.emit("error", err);
|
|
170
|
+
this.push(null);
|
|
171
|
+
});
|
|
172
|
+
} catch (err) {
|
|
173
|
+
this.emit("error", err);
|
|
174
|
+
this.push(null);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
return stream;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export {
|
|
182
|
+
formatOutput,
|
|
183
|
+
getHistoricalRatesToStream
|
|
184
|
+
};
|
package/dist/esm/cli/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
version
|
|
4
|
+
} from "../chunk-DWZJECKF.js";
|
|
2
5
|
import {
|
|
3
6
|
BufferFetcher,
|
|
4
7
|
CacheManager,
|
|
@@ -12,9 +15,8 @@ import {
|
|
|
12
15
|
normaliseDates,
|
|
13
16
|
processData,
|
|
14
17
|
schema,
|
|
15
|
-
validateConfig
|
|
16
|
-
|
|
17
|
-
} from "../chunk-QOULS5Y3.js";
|
|
18
|
+
validateConfig
|
|
19
|
+
} from "../chunk-D3M3SVMW.js";
|
|
18
20
|
|
|
19
21
|
// src/cli/cli.ts
|
|
20
22
|
import { resolve, join } from "path";
|
|
@@ -62,7 +64,7 @@ var commanderSchema = program.option("-d, --debug", "Output extra debugging", fa
|
|
|
62
64
|
function getConfigFromCliArgs(argv) {
|
|
63
65
|
const options = commanderSchema.parse(argv).opts();
|
|
64
66
|
if (options.dateTo === now) {
|
|
65
|
-
options.dateTo = new Date();
|
|
67
|
+
options.dateTo = /* @__PURE__ */ new Date();
|
|
66
68
|
}
|
|
67
69
|
const cliConfig = {
|
|
68
70
|
instrument: options.instrument,
|
|
@@ -167,8 +169,16 @@ import tz from "dayjs/plugin/timezone";
|
|
|
167
169
|
// src/stream-writer/index.ts
|
|
168
170
|
import fs from "fs";
|
|
169
171
|
var BatchStreamWriter = class {
|
|
172
|
+
fileWriteStream;
|
|
173
|
+
timeframe;
|
|
174
|
+
format;
|
|
175
|
+
isInline;
|
|
176
|
+
volumes;
|
|
177
|
+
isFileEmpty = true;
|
|
178
|
+
bodyHeaders;
|
|
179
|
+
startDateTs;
|
|
180
|
+
endDateTs;
|
|
170
181
|
constructor(options) {
|
|
171
|
-
this.isFileEmpty = true;
|
|
172
182
|
this.fileWriteStream = options.fileWriteStream;
|
|
173
183
|
this.timeframe = options.timeframe;
|
|
174
184
|
this.format = options.format;
|
|
@@ -445,7 +455,7 @@ async function run(argv) {
|
|
|
445
455
|
} else {
|
|
446
456
|
printErrors(
|
|
447
457
|
"Search config invalid:",
|
|
448
|
-
validationErrors.map((err) =>
|
|
458
|
+
validationErrors.map((err) => err?.message || "")
|
|
449
459
|
);
|
|
450
460
|
process.exit(0);
|
|
451
461
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getHistoricalRatesToStream
|
|
3
|
+
} from "./chunk-KWYYNULA.js";
|
|
4
|
+
import "./chunk-D3M3SVMW.js";
|
|
5
|
+
|
|
6
|
+
// src/index.example.ts
|
|
7
|
+
(async () => {
|
|
8
|
+
try {
|
|
9
|
+
const data = await getHistoricalRatesToStream({
|
|
10
|
+
instrument: "eurusd",
|
|
11
|
+
dates: {
|
|
12
|
+
from: /* @__PURE__ */ new Date("2021-02-01"),
|
|
13
|
+
to: /* @__PURE__ */ new Date("2021-03-01")
|
|
14
|
+
},
|
|
15
|
+
timeframe: "d1",
|
|
16
|
+
format: "csv"
|
|
17
|
+
});
|
|
18
|
+
data.on("data", (chunk) => {
|
|
19
|
+
console.log(chunk);
|
|
20
|
+
});
|
|
21
|
+
data.on("end", () => {
|
|
22
|
+
console.log("end");
|
|
23
|
+
});
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.log("error", error);
|
|
26
|
+
}
|
|
27
|
+
})();
|