dukascopy-node-plus 1.1.4 → 1.2.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/README.md +435 -23
- package/dist/cli/index.js +3529 -94
- package/dist/esm/chunk-5ZJB4AEL.js +154 -0
- package/dist/esm/{chunk-Z4O2KLFU.js → chunk-GDKYDWLQ.js} +5275 -52
- package/dist/esm/{chunk-KAQS2RYD.js → chunk-PVYCTSWT.js} +5 -7
- package/dist/esm/cli/index.js +36 -25
- package/dist/esm/index.example.nostream.js +5 -6
- package/dist/esm/index.example.stream.js +5 -5
- package/dist/esm/index.js +16 -13
- package/dist/index.d.ts +1823 -33
- package/dist/index.example.nostream.d.ts +0 -1
- package/dist/index.example.nostream.js +3480 -59
- package/dist/index.example.stream.d.ts +0 -1
- package/dist/index.example.stream.js +3539 -126
- package/dist/index.js +5675 -465
- package/package.json +82 -82
- package/dist/cli/index.d.mts +0 -1
- package/dist/esm/chunk-EN4CESUH.js +0 -164
- package/dist/esm/chunk-VHVSB2KI.js +0 -6
- package/dist/index.d.mts +0 -6818
- package/dist/index.example.nostream.d.mts +0 -2
- package/dist/index.example.stream.d.mts +0 -2
- /package/dist/esm/{chunk-476J4KQE.js → chunk-ASWACD3L.js} +0 -0
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
version
|
|
3
|
-
} from "./chunk-VHVSB2KI.js";
|
|
4
1
|
import {
|
|
5
2
|
formatOutput
|
|
6
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ASWACD3L.js";
|
|
7
4
|
import {
|
|
8
5
|
BufferFetcher,
|
|
9
6
|
CacheManager,
|
|
@@ -11,8 +8,9 @@ import {
|
|
|
11
8
|
generateUrls,
|
|
12
9
|
normaliseDates,
|
|
13
10
|
processData,
|
|
14
|
-
validateConfigNode
|
|
15
|
-
|
|
11
|
+
validateConfigNode,
|
|
12
|
+
version
|
|
13
|
+
} from "./chunk-GDKYDWLQ.js";
|
|
16
14
|
|
|
17
15
|
// src/getHistoricalRates.ts
|
|
18
16
|
import debug from "debug";
|
|
@@ -64,7 +62,7 @@ async function getHistoricalRates(config) {
|
|
|
64
62
|
endDate
|
|
65
63
|
});
|
|
66
64
|
debug(`${DEBUG_NAMESPACE}:urls`)(`Generated ${urls.length} urls`);
|
|
67
|
-
debug(`${DEBUG_NAMESPACE}:urls`)(
|
|
65
|
+
debug(`${DEBUG_NAMESPACE}:urls`)("%O", urls);
|
|
68
66
|
const onItemFetch = process.env.DEBUG ? (url, buffer, isCacheHit) => {
|
|
69
67
|
debug(`${DEBUG_NAMESPACE}:fetcher`)(
|
|
70
68
|
url,
|
package/dist/esm/cli/index.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
version
|
|
4
|
-
} from "../chunk-VHVSB2KI.js";
|
|
5
2
|
import {
|
|
6
3
|
BufferFetcher,
|
|
7
4
|
CacheManager,
|
|
8
5
|
VolumeUnit,
|
|
9
|
-
__require,
|
|
10
6
|
formatBytes,
|
|
11
7
|
generateUrls,
|
|
12
8
|
getDateTimeFormatOptions,
|
|
@@ -15,8 +11,9 @@ import {
|
|
|
15
11
|
normaliseDates,
|
|
16
12
|
processData,
|
|
17
13
|
schema,
|
|
18
|
-
validateConfig
|
|
19
|
-
|
|
14
|
+
validateConfig,
|
|
15
|
+
version
|
|
16
|
+
} from "../chunk-GDKYDWLQ.js";
|
|
20
17
|
|
|
21
18
|
// src/cli/cli.ts
|
|
22
19
|
import { resolve, join } from "path";
|
|
@@ -24,7 +21,7 @@ import os from "os";
|
|
|
24
21
|
|
|
25
22
|
// src/cli/progress.ts
|
|
26
23
|
import { Bar } from "cli-progress";
|
|
27
|
-
|
|
24
|
+
import chalk from "chalk";
|
|
28
25
|
var progressBar = new Bar({
|
|
29
26
|
format: "|" + chalk.green("{bar}") + "| {percentage}%",
|
|
30
27
|
barCompleteChar: "\u2588",
|
|
@@ -64,7 +61,7 @@ var commanderSchema = program.option("-d, --debug", "Output extra debugging", fa
|
|
|
64
61
|
function getConfigFromCliArgs(argv) {
|
|
65
62
|
const options = commanderSchema.parse(argv).opts();
|
|
66
63
|
if (options.dateTo === now) {
|
|
67
|
-
options.dateTo =
|
|
64
|
+
options.dateTo = new Date();
|
|
68
65
|
}
|
|
69
66
|
const cliConfig = {
|
|
70
67
|
instrument: options.instrument,
|
|
@@ -111,7 +108,7 @@ function getConfigFromCliArgs(argv) {
|
|
|
111
108
|
}
|
|
112
109
|
|
|
113
110
|
// src/cli/printer.ts
|
|
114
|
-
|
|
111
|
+
import chalk2 from "chalk";
|
|
115
112
|
var log = console.log;
|
|
116
113
|
function printSpacer() {
|
|
117
114
|
log();
|
|
@@ -360,7 +357,7 @@ async function run(argv) {
|
|
|
360
357
|
if (hasMinutes) {
|
|
361
358
|
cutoff = 16;
|
|
362
359
|
}
|
|
363
|
-
return date.toISOString().slice(0, cutoff);
|
|
360
|
+
return date.toISOString().slice(0, cutoff).replace(/:/g, "-");
|
|
364
361
|
}).join("-");
|
|
365
362
|
const fileName = customFileName ? `${customFileName}.${fileExtension}` : `${instrument}-${timeframe}${timeframe === "tick" ? "" : "-" + priceType}-${dateRangeStr}.${fileExtension}`;
|
|
366
363
|
const folderPath = resolve(process.cwd(), dir);
|
|
@@ -370,23 +367,31 @@ async function run(argv) {
|
|
|
370
367
|
}
|
|
371
368
|
const urls = generateUrls({ instrument, timeframe, priceType, startDate, endDate });
|
|
372
369
|
debug(`${DEBUG_NAMESPACE}:urls`)(`Generated ${urls.length} urls`);
|
|
373
|
-
debug(`${DEBUG_NAMESPACE}:urls`)(
|
|
370
|
+
debug(`${DEBUG_NAMESPACE}:urls`)("%O", urls);
|
|
374
371
|
let step = 0;
|
|
375
372
|
if (!isDebugActive) {
|
|
376
373
|
progressBar.start(urls.length, step);
|
|
377
374
|
}
|
|
378
375
|
await ensureDir(folderPath);
|
|
379
376
|
const fileWriteStream = createWriteStream(filePath, { flags: "w+" });
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
377
|
+
const streamFinishPromise = new Promise((resolve2, reject) => {
|
|
378
|
+
fileWriteStream.on("finish", async () => {
|
|
379
|
+
try {
|
|
380
|
+
const downloadEndTs = Date.now();
|
|
381
|
+
if (!isDebugActive) {
|
|
382
|
+
progressBar.stop();
|
|
383
|
+
}
|
|
384
|
+
const relativeFilePath = join(dir, fileName);
|
|
385
|
+
await ensureFile(filePath);
|
|
386
|
+
const { size } = await stat(filePath);
|
|
387
|
+
printSuccess(`\u221A File saved: ${chalk3.bold(relativeFilePath)} (${formatBytes(size)})`);
|
|
388
|
+
printGeneral(`Download time: ${formatTimeDuration(downloadEndTs - downloadStartTs)}`);
|
|
389
|
+
resolve2();
|
|
390
|
+
} catch (error) {
|
|
391
|
+
reject(error);
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
fileWriteStream.on("error", reject);
|
|
390
395
|
});
|
|
391
396
|
const batchStreamWriter = new BatchStreamWriter({
|
|
392
397
|
fileWriteStream,
|
|
@@ -451,18 +456,24 @@ async function run(argv) {
|
|
|
451
456
|
}
|
|
452
457
|
}
|
|
453
458
|
});
|
|
454
|
-
|
|
459
|
+
try {
|
|
460
|
+
await bufferFetcher.fetch_optimized(urls);
|
|
461
|
+
await streamFinishPromise;
|
|
462
|
+
} catch (fetchError) {
|
|
463
|
+
fileWriteStream.destroy();
|
|
464
|
+
throw fetchError;
|
|
465
|
+
}
|
|
455
466
|
} else {
|
|
456
467
|
printErrors(
|
|
457
468
|
"Search config invalid:",
|
|
458
|
-
validationErrors.map((err) => err
|
|
469
|
+
validationErrors.map((err) => (err == null ? void 0 : err.message) || "")
|
|
459
470
|
);
|
|
460
|
-
process.exit(
|
|
471
|
+
process.exit(1);
|
|
461
472
|
}
|
|
462
473
|
} catch (err) {
|
|
463
474
|
const errorMsg = err instanceof Error ? err.message : JSON.stringify(err);
|
|
464
475
|
printErrors("\nSomething went wrong:", errorMsg);
|
|
465
|
-
process.exit(
|
|
476
|
+
process.exit(1);
|
|
466
477
|
}
|
|
467
478
|
}
|
|
468
479
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getHistoricalRates
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-Z4O2KLFU.js";
|
|
3
|
+
} from "./chunk-PVYCTSWT.js";
|
|
4
|
+
import "./chunk-ASWACD3L.js";
|
|
5
|
+
import "./chunk-GDKYDWLQ.js";
|
|
7
6
|
|
|
8
7
|
// src/index.example.nostream.ts
|
|
9
8
|
var printMemory = () => {
|
|
@@ -23,8 +22,8 @@ var printMemory = () => {
|
|
|
23
22
|
const data = await getHistoricalRates({
|
|
24
23
|
instrument: "eurusd",
|
|
25
24
|
dates: {
|
|
26
|
-
from:
|
|
27
|
-
to:
|
|
25
|
+
from: new Date("2021-02-01"),
|
|
26
|
+
to: new Date("2021-06-03")
|
|
28
27
|
},
|
|
29
28
|
timeframe: "m1",
|
|
30
29
|
format: "csv"
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getHistoricalRatesToStream
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-5ZJB4AEL.js";
|
|
4
|
+
import "./chunk-ASWACD3L.js";
|
|
5
|
+
import "./chunk-GDKYDWLQ.js";
|
|
6
6
|
|
|
7
7
|
// src/index.example.stream.ts
|
|
8
8
|
var printMemory = () => {
|
|
@@ -22,8 +22,8 @@ var printMemory = () => {
|
|
|
22
22
|
const data = await getHistoricalRatesToStream({
|
|
23
23
|
instrument: "eurusd",
|
|
24
24
|
dates: {
|
|
25
|
-
from:
|
|
26
|
-
to:
|
|
25
|
+
from: new Date("2021-02-01"),
|
|
26
|
+
to: new Date("2021-06-03")
|
|
27
27
|
},
|
|
28
28
|
timeframe: "m1",
|
|
29
29
|
format: "csv"
|
package/dist/esm/index.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getHistoricalRatesToStream
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5ZJB4AEL.js";
|
|
4
4
|
import {
|
|
5
5
|
getHistoricRates,
|
|
6
6
|
getHistoricalRates
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-VHVSB2KI.js";
|
|
7
|
+
} from "./chunk-PVYCTSWT.js";
|
|
9
8
|
import {
|
|
10
9
|
formatOutput
|
|
11
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-ASWACD3L.js";
|
|
12
11
|
import {
|
|
13
12
|
BufferFetcher,
|
|
14
13
|
CacheManager,
|
|
15
14
|
Format,
|
|
16
15
|
Instrument,
|
|
16
|
+
InstrumentGroup,
|
|
17
17
|
Price,
|
|
18
18
|
Timeframe,
|
|
19
19
|
URL_ROOT,
|
|
@@ -25,13 +25,12 @@ import {
|
|
|
25
25
|
schema,
|
|
26
26
|
validateConfig,
|
|
27
27
|
validateConfigNode
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-GDKYDWLQ.js";
|
|
29
29
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
import { RuleDate, RuleBoolean, RuleNumber, RuleString, RuleObject } from "fastest-validator";
|
|
32
32
|
|
|
33
|
-
// src/
|
|
34
|
-
import fetch from "node-fetch";
|
|
33
|
+
// src/getRealTimeRates.ts
|
|
35
34
|
var timeframeMap = {
|
|
36
35
|
tick: "TICK",
|
|
37
36
|
s1: "1SEC",
|
|
@@ -44,20 +43,20 @@ var timeframeMap = {
|
|
|
44
43
|
d1: "1DAY",
|
|
45
44
|
mn1: "1MONTH"
|
|
46
45
|
};
|
|
47
|
-
async function
|
|
46
|
+
async function getRealTimeRates({
|
|
48
47
|
instrument,
|
|
49
48
|
priceType = "bid",
|
|
50
49
|
timeframe = "d1",
|
|
51
50
|
volumes = true,
|
|
52
51
|
format = "array",
|
|
53
52
|
dates,
|
|
54
|
-
|
|
53
|
+
last = 10
|
|
55
54
|
}) {
|
|
56
55
|
const mappedTimeframe = timeframeMap[timeframe];
|
|
57
56
|
const instrumentName = instrumentMetaData[instrument].name;
|
|
58
57
|
const offerSide = priceType === "bid" ? "B" : "A";
|
|
59
58
|
const timeDirection = "N";
|
|
60
|
-
const now =
|
|
59
|
+
const now = new Date();
|
|
61
60
|
let fromDate = now;
|
|
62
61
|
let toDate = now;
|
|
63
62
|
if (dates) {
|
|
@@ -65,7 +64,7 @@ async function getCurrentRates({
|
|
|
65
64
|
fromDate = typeof from === "string" || typeof from === "number" ? new Date(from) : from;
|
|
66
65
|
toDate = typeof to === "string" || typeof to === "number" ? new Date(to) : to;
|
|
67
66
|
} else {
|
|
68
|
-
fromDate = getTimeframeLimit(timeframe, now,
|
|
67
|
+
fromDate = getTimeframeLimit(timeframe, now, last || 10);
|
|
69
68
|
toDate = now;
|
|
70
69
|
}
|
|
71
70
|
let targetTimestamp = +toDate;
|
|
@@ -107,8 +106,8 @@ async function getCurrentRates({
|
|
|
107
106
|
shouldFetch = false;
|
|
108
107
|
}
|
|
109
108
|
}
|
|
110
|
-
const shouldSlice = !dates && (typeof
|
|
111
|
-
let filteredRates = shouldSlice ? rates.slice((
|
|
109
|
+
const shouldSlice = !dates && (typeof last === "undefined" || typeof last === "number");
|
|
110
|
+
let filteredRates = shouldSlice ? rates.slice((last || 10) * -1) : rates.filter(function(item) {
|
|
112
111
|
let key = item[0];
|
|
113
112
|
const isWithinBounds = item[0] >= +fromDate && item[0] < +toDate;
|
|
114
113
|
const isUnique = !this.has(key);
|
|
@@ -152,11 +151,13 @@ function getTimeframeLimit(timeframe, now, limit) {
|
|
|
152
151
|
};
|
|
153
152
|
return new Date(nowTimestamp - limit * bufferMultiplier * timeframeLimits[timeframe]);
|
|
154
153
|
}
|
|
154
|
+
var getCurrentRates = getRealTimeRates;
|
|
155
155
|
export {
|
|
156
156
|
BufferFetcher,
|
|
157
157
|
CacheManager,
|
|
158
158
|
Format,
|
|
159
159
|
Instrument,
|
|
160
|
+
InstrumentGroup,
|
|
160
161
|
instrumentMetaData as InstrumentMetaData,
|
|
161
162
|
Price,
|
|
162
163
|
RuleBoolean,
|
|
@@ -173,6 +174,8 @@ export {
|
|
|
173
174
|
getHistoricRates,
|
|
174
175
|
getHistoricalRates,
|
|
175
176
|
getHistoricalRatesToStream,
|
|
177
|
+
getRealTimeRates,
|
|
178
|
+
instrumentMetaData,
|
|
176
179
|
normaliseDates,
|
|
177
180
|
processData,
|
|
178
181
|
schema,
|