dukascopy-node-plus 1.1.0 → 1.1.1

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/cli/index.js CHANGED
@@ -13883,7 +13883,7 @@ var import_utc = __toESM(require("dayjs/plugin/utc"));
13883
13883
  var import_timezone = __toESM(require("dayjs/plugin/timezone"));
13884
13884
 
13885
13885
  // package.json
13886
- var version = "1.1.0";
13886
+ var version = "1.1.1";
13887
13887
 
13888
13888
  // src/stream-writer/index.ts
13889
13889
  var import_fs = __toESM(require("fs"));
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "1.1.0";
2
+ var version = "1.1.1";
3
3
 
4
4
  export {
5
5
  version
@@ -0,0 +1,35 @@
1
+ // src/output-formatter/index.ts
2
+ var candleHeaders = ["timestamp", "open", "high", "low", "close", "volume"];
3
+ var tickHeaders = ["timestamp", "askPrice", "bidPrice", "askVolume", "bidVolume"];
4
+ function formatOutput({
5
+ processedData,
6
+ format,
7
+ timeframe
8
+ }) {
9
+ if (processedData.length === 0) {
10
+ return [];
11
+ }
12
+ const bodyHeaders = timeframe === "tick" /* tick */ ? tickHeaders : candleHeaders;
13
+ if (format === "json" /* json */) {
14
+ const data = processedData.map((arr) => {
15
+ return arr.reduce((all, item, i) => {
16
+ const name = bodyHeaders[i];
17
+ all[name] = item;
18
+ return all;
19
+ }, {});
20
+ });
21
+ return data;
22
+ }
23
+ if (format === "csv" /* csv */) {
24
+ const csvHeaders = bodyHeaders.filter((_, i) => processedData[0][i] !== void 0);
25
+ const csv = [csvHeaders, ...processedData].map((arr) => arr.join(",")).join("\n");
26
+ return csv;
27
+ }
28
+ return processedData;
29
+ }
30
+
31
+ export {
32
+ candleHeaders,
33
+ tickHeaders,
34
+ formatOutput
35
+ };
@@ -0,0 +1,155 @@
1
+ import {
2
+ candleHeaders,
3
+ tickHeaders
4
+ } from "./chunk-476J4KQE.js";
5
+ import {
6
+ BufferFetcher,
7
+ CacheManager,
8
+ formatBytes,
9
+ generateUrls,
10
+ normaliseDates,
11
+ processData,
12
+ validateConfigNode
13
+ } from "./chunk-D3M3SVMW.js";
14
+
15
+ // src/getHistoricalRatesToStream.ts
16
+ import debug from "debug";
17
+ import { Readable, Transform } from "stream";
18
+ import { pipeline } from "stream/promises";
19
+ var DEBUG_NAMESPACE = "dukascopy-node";
20
+ function getHistoricalRatesToStream(config) {
21
+ const stream = new Readable({
22
+ objectMode: true,
23
+ async read(_size) {
24
+ }
25
+ });
26
+ try {
27
+ const { input, isValid, validationErrors } = validateConfigNode(config);
28
+ debug(`${DEBUG_NAMESPACE}:config`)("%O", {
29
+ input,
30
+ isValid,
31
+ validationErrors
32
+ });
33
+ if (!isValid) {
34
+ stream.emit("error", { validationErrors });
35
+ stream.push(null);
36
+ return stream;
37
+ }
38
+ const {
39
+ instrument,
40
+ dates: { from, to },
41
+ timeframe,
42
+ priceType,
43
+ volumes,
44
+ volumeUnits,
45
+ utcOffset,
46
+ ignoreFlats,
47
+ format,
48
+ batchSize,
49
+ pauseBetweenBatchesMs,
50
+ useCache,
51
+ cacheFolderPath,
52
+ retryCount,
53
+ pauseBetweenRetriesMs,
54
+ retryOnEmpty
55
+ } = input;
56
+ const [startDate, endDate] = normaliseDates({
57
+ instrument,
58
+ startDate: from,
59
+ endDate: to,
60
+ timeframe,
61
+ utcOffset
62
+ });
63
+ const [startDateMs, endDateMs] = [+startDate, +endDate];
64
+ const onItemFetch = process.env.DEBUG ? (url, buffer, isCacheHit) => {
65
+ debug(`${DEBUG_NAMESPACE}:fetcher`)(
66
+ url,
67
+ `| ${formatBytes(buffer.length)} |`,
68
+ `${isCacheHit ? "cache" : "network"}`
69
+ );
70
+ } : void 0;
71
+ const bufferFetcher = new BufferFetcher({
72
+ batchSize,
73
+ pauseBetweenBatchesMs,
74
+ cacheManager: useCache ? new CacheManager({ cacheFolderPath }) : void 0,
75
+ retryCount,
76
+ pauseBetweenRetriesMs,
77
+ onItemFetch,
78
+ retryOnEmpty
79
+ });
80
+ const bodyHeaders = timeframe === "tick" /* tick */ ? tickHeaders : candleHeaders;
81
+ let firstLine = true;
82
+ let urlsProcessed = 0;
83
+ const urlsforFetchingData = generateUrls({
84
+ instrument: input.instrument,
85
+ timeframe: input.timeframe,
86
+ priceType: input.priceType,
87
+ startDate,
88
+ endDate
89
+ });
90
+ pipeline(
91
+ Readable.from(urlsforFetchingData),
92
+ new Transform({
93
+ objectMode: true,
94
+ transform: async (url, _, callback) => {
95
+ const bufferObject = {
96
+ url,
97
+ buffer: await bufferFetcher.fetchBuffer(url),
98
+ isCacheHit: useCache
99
+ };
100
+ try {
101
+ const processedData = processData({
102
+ instrument: input.instrument,
103
+ requestedTimeframe: input.timeframe,
104
+ bufferObjects: [bufferObject],
105
+ priceType: input.priceType,
106
+ volumes: input.volumes,
107
+ volumeUnits: input.volumeUnits,
108
+ ignoreFlats: input.ignoreFlats
109
+ });
110
+ processedData.forEach((item) => {
111
+ const [timestamp] = item;
112
+ if (timestamp && timestamp >= startDateMs && timestamp < endDateMs) {
113
+ if (input.format === "array" /* array */) {
114
+ stream.push(item);
115
+ } else if (format === "json" /* json */) {
116
+ const data = item.reduce((all, item2, i) => {
117
+ const name = bodyHeaders[i];
118
+ all[name] = item2;
119
+ return all;
120
+ }, {});
121
+ stream.push(data);
122
+ } else if (format === "csv" /* csv */) {
123
+ if (firstLine) {
124
+ const csvHeaders = bodyHeaders.join(",");
125
+ stream.push(csvHeaders);
126
+ firstLine = false;
127
+ }
128
+ stream.push(`
129
+ ${item.join(",")}`);
130
+ }
131
+ }
132
+ });
133
+ if (++urlsProcessed === urlsforFetchingData.length) {
134
+ stream.push(null);
135
+ }
136
+ callback();
137
+ } catch (err) {
138
+ callback(err);
139
+ }
140
+ }
141
+ })
142
+ ).catch((err) => {
143
+ stream.emit("error", err);
144
+ stream.push(null);
145
+ });
146
+ } catch (err) {
147
+ stream.emit("error", err);
148
+ stream.push(null);
149
+ }
150
+ return stream;
151
+ }
152
+
153
+ export {
154
+ getHistoricalRatesToStream
155
+ };
@@ -0,0 +1,113 @@
1
+ import {
2
+ version
3
+ } from "./chunk-3Q3J6T4N.js";
4
+ import {
5
+ formatOutput
6
+ } from "./chunk-476J4KQE.js";
7
+ import {
8
+ BufferFetcher,
9
+ CacheManager,
10
+ formatBytes,
11
+ generateUrls,
12
+ normaliseDates,
13
+ processData,
14
+ validateConfigNode
15
+ } from "./chunk-D3M3SVMW.js";
16
+
17
+ // src/getHistoricalRates.ts
18
+ import debug from "debug";
19
+ import os from "os";
20
+ var DEBUG_NAMESPACE = "dukascopy-node";
21
+ async function getHistoricalRates(config) {
22
+ debug(`${DEBUG_NAMESPACE}:version`)(version);
23
+ debug(`${DEBUG_NAMESPACE}:nodejs`)(process.version);
24
+ debug(`${DEBUG_NAMESPACE}:os`)(`${os.type()}, ${os.release()} (${os.platform()})`);
25
+ const { input, isValid, validationErrors } = validateConfigNode(config);
26
+ debug(`${DEBUG_NAMESPACE}:config`)("%O", {
27
+ input,
28
+ isValid,
29
+ validationErrors
30
+ });
31
+ if (!isValid) {
32
+ throw { validationErrors };
33
+ }
34
+ const {
35
+ instrument,
36
+ dates: { from, to },
37
+ timeframe,
38
+ priceType,
39
+ volumes,
40
+ volumeUnits,
41
+ utcOffset,
42
+ ignoreFlats,
43
+ format,
44
+ batchSize,
45
+ pauseBetweenBatchesMs,
46
+ useCache,
47
+ cacheFolderPath,
48
+ retryCount,
49
+ pauseBetweenRetriesMs,
50
+ retryOnEmpty
51
+ } = input;
52
+ const [startDate, endDate] = normaliseDates({
53
+ instrument,
54
+ startDate: from,
55
+ endDate: to,
56
+ timeframe,
57
+ utcOffset
58
+ });
59
+ const urls = generateUrls({
60
+ instrument,
61
+ timeframe,
62
+ priceType,
63
+ startDate,
64
+ endDate
65
+ });
66
+ debug(`${DEBUG_NAMESPACE}:urls`)(`Generated ${urls.length} urls`);
67
+ debug(`${DEBUG_NAMESPACE}:urls`)(`%O`, urls);
68
+ const onItemFetch = process.env.DEBUG ? (url, buffer, isCacheHit) => {
69
+ debug(`${DEBUG_NAMESPACE}:fetcher`)(
70
+ url,
71
+ `| ${formatBytes(buffer.length)} |`,
72
+ `${isCacheHit ? "cache" : "network"}`
73
+ );
74
+ } : void 0;
75
+ const bufferFetcher = new BufferFetcher({
76
+ batchSize,
77
+ pauseBetweenBatchesMs,
78
+ cacheManager: useCache ? new CacheManager({ cacheFolderPath }) : void 0,
79
+ retryCount,
80
+ pauseBetweenRetriesMs,
81
+ onItemFetch,
82
+ retryOnEmpty
83
+ });
84
+ const bufferredData = await bufferFetcher.fetch(urls);
85
+ const processedData = processData({
86
+ instrument,
87
+ requestedTimeframe: timeframe,
88
+ bufferObjects: bufferredData,
89
+ priceType,
90
+ volumes,
91
+ volumeUnits,
92
+ ignoreFlats
93
+ });
94
+ const [startDateMs, endDateMs] = [+startDate, +endDate];
95
+ const filteredData = processedData.filter(
96
+ ([timestamp]) => timestamp && timestamp >= startDateMs && timestamp < endDateMs
97
+ );
98
+ debug(`${DEBUG_NAMESPACE}:data`)(
99
+ `Generated ${filteredData.length} ${timeframe === "tick" /* tick */ ? "ticks" : "OHLC candles"}`
100
+ );
101
+ const formattedData = formatOutput({
102
+ processedData: filteredData,
103
+ format,
104
+ timeframe
105
+ });
106
+ return formattedData;
107
+ }
108
+ var getHistoricRates = getHistoricalRates;
109
+
110
+ export {
111
+ getHistoricalRates,
112
+ getHistoricRates
113
+ };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  version
4
- } from "../chunk-DWZJECKF.js";
4
+ } from "../chunk-3Q3J6T4N.js";
5
5
  import {
6
6
  BufferFetcher,
7
7
  CacheManager,
@@ -0,0 +1,37 @@
1
+ import {
2
+ getHistoricalRates
3
+ } from "./chunk-YLYLH52F.js";
4
+ import "./chunk-3Q3J6T4N.js";
5
+ import "./chunk-476J4KQE.js";
6
+ import "./chunk-D3M3SVMW.js";
7
+
8
+ // src/index.example.nostream.ts
9
+ var printMemory = () => {
10
+ const formatMemoryUsage = (data) => `${Math.round(data / 1024 / 1024 * 100) / 100} MB`;
11
+ const memoryData = process.memoryUsage();
12
+ const memoryUsage = {
13
+ rss: `${formatMemoryUsage(memoryData.rss)} -> Resident Set Size - total memory allocated for the process execution`,
14
+ heapTotal: `${formatMemoryUsage(memoryData.heapTotal)} -> total size of the allocated heap`,
15
+ heapUsed: `${formatMemoryUsage(memoryData.heapUsed)} -> actual memory used during the execution`,
16
+ external: `${formatMemoryUsage(memoryData.external)} -> V8 external memory`
17
+ };
18
+ console.log(memoryUsage);
19
+ };
20
+ (async () => {
21
+ try {
22
+ printMemory();
23
+ const data = await getHistoricalRates({
24
+ instrument: "eurusd",
25
+ dates: {
26
+ from: /* @__PURE__ */ new Date("2021-02-01"),
27
+ to: /* @__PURE__ */ new Date("2021-02-03")
28
+ },
29
+ timeframe: "m1",
30
+ format: "csv"
31
+ });
32
+ process.stdout.write(data);
33
+ printMemory();
34
+ } catch (error) {
35
+ console.log("error", error);
36
+ }
37
+ })();
@@ -0,0 +1,40 @@
1
+ import {
2
+ getHistoricalRatesToStream
3
+ } from "./chunk-VHUFHYTL.js";
4
+ import "./chunk-476J4KQE.js";
5
+ import "./chunk-D3M3SVMW.js";
6
+
7
+ // src/index.example.stream.ts
8
+ var printMemory = () => {
9
+ const formatMemoryUsage = (data) => `${Math.round(data / 1024 / 1024 * 100) / 100} MB`;
10
+ const memoryData = process.memoryUsage();
11
+ const memoryUsage = {
12
+ rss: `${formatMemoryUsage(memoryData.rss)} -> Resident Set Size - total memory allocated for the process execution`,
13
+ heapTotal: `${formatMemoryUsage(memoryData.heapTotal)} -> total size of the allocated heap`,
14
+ heapUsed: `${formatMemoryUsage(memoryData.heapUsed)} -> actual memory used during the execution`,
15
+ external: `${formatMemoryUsage(memoryData.external)} -> V8 external memory`
16
+ };
17
+ console.log(memoryUsage);
18
+ };
19
+ (async () => {
20
+ try {
21
+ printMemory();
22
+ const data = await getHistoricalRatesToStream({
23
+ instrument: "eurusd",
24
+ dates: {
25
+ from: /* @__PURE__ */ new Date("2021-02-01"),
26
+ to: /* @__PURE__ */ new Date("2021-02-03")
27
+ },
28
+ timeframe: "m1",
29
+ format: "csv"
30
+ });
31
+ data.on("data", (_chunk) => {
32
+ process.stdout.write(_chunk);
33
+ });
34
+ data.on("end", () => {
35
+ printMemory();
36
+ });
37
+ } catch (error) {
38
+ console.log("error", error);
39
+ }
40
+ })();
package/dist/esm/index.js CHANGED
@@ -1,10 +1,14 @@
1
1
  import {
2
- version
3
- } from "./chunk-DWZJECKF.js";
4
- import {
5
- formatOutput,
6
2
  getHistoricalRatesToStream
7
- } from "./chunk-KWYYNULA.js";
3
+ } from "./chunk-VHUFHYTL.js";
4
+ import {
5
+ getHistoricRates,
6
+ getHistoricalRates
7
+ } from "./chunk-YLYLH52F.js";
8
+ import "./chunk-3Q3J6T4N.js";
9
+ import {
10
+ formatOutput
11
+ } from "./chunk-476J4KQE.js";
8
12
  import {
9
13
  BufferFetcher,
10
14
  CacheManager,
@@ -14,7 +18,6 @@ import {
14
18
  Timeframe,
15
19
  URL_ROOT,
16
20
  defaultConfig,
17
- formatBytes,
18
21
  generateUrls,
19
22
  instrumentMetaData,
20
23
  normaliseDates,
@@ -27,99 +30,6 @@ import {
27
30
  // src/index.ts
28
31
  import { RuleDate, RuleBoolean, RuleNumber, RuleString, RuleObject } from "fastest-validator";
29
32
 
30
- // src/getHistoricalRates.ts
31
- import debug from "debug";
32
- import os from "os";
33
- var DEBUG_NAMESPACE = "dukascopy-node";
34
- async function getHistoricalRates(config) {
35
- debug(`${DEBUG_NAMESPACE}:version`)(version);
36
- debug(`${DEBUG_NAMESPACE}:nodejs`)(process.version);
37
- debug(`${DEBUG_NAMESPACE}:os`)(`${os.type()}, ${os.release()} (${os.platform()})`);
38
- const { input, isValid, validationErrors } = validateConfigNode(config);
39
- debug(`${DEBUG_NAMESPACE}:config`)("%O", {
40
- input,
41
- isValid,
42
- validationErrors
43
- });
44
- if (!isValid) {
45
- throw { validationErrors };
46
- }
47
- const {
48
- instrument,
49
- dates: { from, to },
50
- timeframe,
51
- priceType,
52
- volumes,
53
- volumeUnits,
54
- utcOffset,
55
- ignoreFlats,
56
- format,
57
- batchSize,
58
- pauseBetweenBatchesMs,
59
- useCache,
60
- cacheFolderPath,
61
- retryCount,
62
- pauseBetweenRetriesMs,
63
- retryOnEmpty
64
- } = input;
65
- const [startDate, endDate] = normaliseDates({
66
- instrument,
67
- startDate: from,
68
- endDate: to,
69
- timeframe,
70
- utcOffset
71
- });
72
- const urls = generateUrls({
73
- instrument,
74
- timeframe,
75
- priceType,
76
- startDate,
77
- endDate
78
- });
79
- debug(`${DEBUG_NAMESPACE}:urls`)(`Generated ${urls.length} urls`);
80
- debug(`${DEBUG_NAMESPACE}:urls`)(`%O`, urls);
81
- const onItemFetch = process.env.DEBUG ? (url, buffer, isCacheHit) => {
82
- debug(`${DEBUG_NAMESPACE}:fetcher`)(
83
- url,
84
- `| ${formatBytes(buffer.length)} |`,
85
- `${isCacheHit ? "cache" : "network"}`
86
- );
87
- } : void 0;
88
- const bufferFetcher = new BufferFetcher({
89
- batchSize,
90
- pauseBetweenBatchesMs,
91
- cacheManager: useCache ? new CacheManager({ cacheFolderPath }) : void 0,
92
- retryCount,
93
- pauseBetweenRetriesMs,
94
- onItemFetch,
95
- retryOnEmpty
96
- });
97
- const bufferredData = await bufferFetcher.fetch(urls);
98
- const processedData = processData({
99
- instrument,
100
- requestedTimeframe: timeframe,
101
- bufferObjects: bufferredData,
102
- priceType,
103
- volumes,
104
- volumeUnits,
105
- ignoreFlats
106
- });
107
- const [startDateMs, endDateMs] = [+startDate, +endDate];
108
- const filteredData = processedData.filter(
109
- ([timestamp]) => timestamp && timestamp >= startDateMs && timestamp < endDateMs
110
- );
111
- debug(`${DEBUG_NAMESPACE}:data`)(
112
- `Generated ${filteredData.length} ${timeframe === "tick" /* tick */ ? "ticks" : "OHLC candles"}`
113
- );
114
- const formattedData = formatOutput({
115
- processedData: filteredData,
116
- format,
117
- timeframe
118
- });
119
- return formattedData;
120
- }
121
- var getHistoricRates = getHistoricalRates;
122
-
123
33
  // src/getCurrentRates.ts
124
34
  import fetch from "node-fetch";
125
35
  var timeframeMap = {
package/dist/index.d.mts CHANGED
@@ -6798,6 +6798,6 @@ declare function getCurrentRates(config: CurrentRatesConfigJsonItem): Promise<Js
6798
6798
  declare function getCurrentRates(config: CurrentRatesConfigJsonTickItem): Promise<JsonItemTick[]>;
6799
6799
  declare function getCurrentRates(config: CurrentRatesConfigCsv): Promise<string>;
6800
6800
 
6801
- declare function getHistoricalRatesToStream(config: Config): Promise<Readable>;
6801
+ declare function getHistoricalRatesToStream(config: Config): Readable;
6802
6802
 
6803
6803
  export { type ArrayItem, type ArrayTickItem, BufferFetcher, CacheManager, type Config, type ConfigValidationError, type CurrentRatesConfig, type CurrentRatesConfigArrayItem, type CurrentRatesConfigArrayTickItem, type CurrentRatesConfigCsv, type CurrentRatesConfigJsonItem, type CurrentRatesConfigJsonTickItem, type DefaultConfig, Format, type FormatType, type InputSchema, Instrument, instrumentMetaData as InstrumentMetaData, type InstrumentType, type JsonItem, type JsonItemTick, type Output, Price, type PriceType, type SanitizedConfig, Timeframe, type TimeframeType, URL_ROOT, type ValidateConfigOutput, defaultConfig, formatOutput, generateUrls, getCurrentRates, getHistoricRates, getHistoricalRates, getHistoricalRatesToStream, normaliseDates, processData, schema, validateConfig, validateConfigNode };
package/dist/index.d.ts CHANGED
@@ -6798,6 +6798,6 @@ declare function getCurrentRates(config: CurrentRatesConfigJsonItem): Promise<Js
6798
6798
  declare function getCurrentRates(config: CurrentRatesConfigJsonTickItem): Promise<JsonItemTick[]>;
6799
6799
  declare function getCurrentRates(config: CurrentRatesConfigCsv): Promise<string>;
6800
6800
 
6801
- declare function getHistoricalRatesToStream(config: Config): Promise<Readable>;
6801
+ declare function getHistoricalRatesToStream(config: Config): Readable;
6802
6802
 
6803
6803
  export { type ArrayItem, type ArrayTickItem, BufferFetcher, CacheManager, type Config, type ConfigValidationError, type CurrentRatesConfig, type CurrentRatesConfigArrayItem, type CurrentRatesConfigArrayTickItem, type CurrentRatesConfigCsv, type CurrentRatesConfigJsonItem, type CurrentRatesConfigJsonTickItem, type DefaultConfig, Format, type FormatType, type InputSchema, Instrument, instrumentMetaData as InstrumentMetaData, type InstrumentType, type JsonItem, type JsonItemTick, type Output, Price, type PriceType, type SanitizedConfig, Timeframe, type TimeframeType, URL_ROOT, type ValidateConfigOutput, defaultConfig, formatOutput, generateUrls, getCurrentRates, getHistoricRates, getHistoricalRates, getHistoricalRatesToStream, normaliseDates, processData, schema, validateConfig, validateConfigNode };