@backtest-kit/pinets 0.0.1 → 0.0.2
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/build/index.cjs +146 -0
- package/build/index.mjs +148 -3
- package/package.json +1 -1
- package/types.d.ts +30 -15
package/build/index.cjs
CHANGED
|
@@ -99,6 +99,9 @@ const cacheServices$1 = {
|
|
|
99
99
|
const connectionServices$1 = {
|
|
100
100
|
pineConnectionService: Symbol("pineConnectionService"),
|
|
101
101
|
};
|
|
102
|
+
const markdownServices$1 = {
|
|
103
|
+
pineMarkdownService: Symbol("pineMarkdownService"),
|
|
104
|
+
};
|
|
102
105
|
const TYPES = {
|
|
103
106
|
...baseServices,
|
|
104
107
|
...providerServices$1,
|
|
@@ -106,6 +109,7 @@ const TYPES = {
|
|
|
106
109
|
...dataServices$1,
|
|
107
110
|
...cacheServices$1,
|
|
108
111
|
...connectionServices$1,
|
|
112
|
+
...markdownServices$1,
|
|
109
113
|
};
|
|
110
114
|
|
|
111
115
|
const MS_PER_MINUTE = 60000;
|
|
@@ -438,6 +442,128 @@ class PineConnectionService {
|
|
|
438
442
|
}
|
|
439
443
|
}
|
|
440
444
|
|
|
445
|
+
const DEFAULT_FORMAT = (v) => v !== null ? Number(v).toFixed(4) : "N/A";
|
|
446
|
+
function isUnsafe(value) {
|
|
447
|
+
if (value === null)
|
|
448
|
+
return true;
|
|
449
|
+
if (typeof value !== "number")
|
|
450
|
+
return true;
|
|
451
|
+
if (isNaN(value))
|
|
452
|
+
return true;
|
|
453
|
+
if (!isFinite(value))
|
|
454
|
+
return true;
|
|
455
|
+
return false;
|
|
456
|
+
}
|
|
457
|
+
function extractRowAtIndex(plots, keys, index) {
|
|
458
|
+
let time = null;
|
|
459
|
+
for (const key of keys) {
|
|
460
|
+
const plotData = plots[key]?.data;
|
|
461
|
+
if (plotData && plotData[index]) {
|
|
462
|
+
time = plotData[index].time;
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if (time === null)
|
|
467
|
+
return null;
|
|
468
|
+
const row = { time };
|
|
469
|
+
for (const key of keys) {
|
|
470
|
+
const plotData = plots[key]?.data;
|
|
471
|
+
if (plotData && plotData[index]) {
|
|
472
|
+
const value = plotData[index].value;
|
|
473
|
+
row[key] = isUnsafe(value) ? null : value;
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
row[key] = null;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
return row;
|
|
480
|
+
}
|
|
481
|
+
function isRowWarmedUp(row, keys) {
|
|
482
|
+
for (const key of keys) {
|
|
483
|
+
if (!row[key]) {
|
|
484
|
+
return false;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
return true;
|
|
488
|
+
}
|
|
489
|
+
function generateMarkdownTable(rows, keys, signalId) {
|
|
490
|
+
let markdown = "";
|
|
491
|
+
markdown += `# PineScript Technical Analysis Dump\n\n`;
|
|
492
|
+
markdown += `**Signal ID**: ${String(signalId)}\n\n`;
|
|
493
|
+
const header = `| Timestamp | ${keys.join(" | ")} |\n`;
|
|
494
|
+
const separator = `| --- | ${keys.map(() => "---").join(" | ")} |\n`;
|
|
495
|
+
markdown += header;
|
|
496
|
+
markdown += separator;
|
|
497
|
+
for (const row of rows) {
|
|
498
|
+
const timestamp = new Date(row.time).toISOString();
|
|
499
|
+
const cells = keys.map((key) => DEFAULT_FORMAT(row[key]));
|
|
500
|
+
markdown += `| ${timestamp} | ${cells.join(" | ")} |\n`;
|
|
501
|
+
}
|
|
502
|
+
return markdown;
|
|
503
|
+
}
|
|
504
|
+
class PineMarkdownService {
|
|
505
|
+
constructor() {
|
|
506
|
+
this.loggerService = inject(TYPES.loggerService);
|
|
507
|
+
this.getData = (plots) => {
|
|
508
|
+
this.loggerService.log("pineMarkdownService getReport", {
|
|
509
|
+
plotCount: Object.keys(plots).length,
|
|
510
|
+
});
|
|
511
|
+
const keys = Object.keys(plots);
|
|
512
|
+
if (keys.length === 0) {
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
const firstPlot = plots[keys[0]];
|
|
516
|
+
const dataLength = firstPlot?.data?.length ?? 0;
|
|
517
|
+
if (dataLength === 0) {
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
const rows = [];
|
|
521
|
+
let warmupComplete = false;
|
|
522
|
+
for (let i = 0; i < dataLength; i++) {
|
|
523
|
+
const row = extractRowAtIndex(plots, keys, i);
|
|
524
|
+
if (!row)
|
|
525
|
+
continue;
|
|
526
|
+
if (!warmupComplete) {
|
|
527
|
+
if (isRowWarmedUp(row, keys)) {
|
|
528
|
+
warmupComplete = true;
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
rows.push(row);
|
|
535
|
+
}
|
|
536
|
+
return rows;
|
|
537
|
+
};
|
|
538
|
+
this.getReport = (signalId, plots) => {
|
|
539
|
+
this.loggerService.log("pineMarkdownService getReport", {
|
|
540
|
+
signalId,
|
|
541
|
+
plotCount: Object.keys(plots).length,
|
|
542
|
+
});
|
|
543
|
+
const rows = this.getData(plots);
|
|
544
|
+
const keys = Object.keys(plots);
|
|
545
|
+
return generateMarkdownTable(rows, keys, signalId);
|
|
546
|
+
};
|
|
547
|
+
this.dump = async (signalId, plots, taName, outputDir = `./dump/ta/${taName}`) => {
|
|
548
|
+
this.loggerService.log("pineMarkdownService dumpSignal", {
|
|
549
|
+
signalId,
|
|
550
|
+
plotCount: Object.keys(plots).length,
|
|
551
|
+
outputDir,
|
|
552
|
+
});
|
|
553
|
+
const content = this.getReport(signalId, plots);
|
|
554
|
+
await backtestKit.Markdown.writeData(taName, content, {
|
|
555
|
+
path: outputDir,
|
|
556
|
+
file: `${String(signalId)}.md`,
|
|
557
|
+
symbol: "",
|
|
558
|
+
signalId: String(signalId),
|
|
559
|
+
strategyName: "",
|
|
560
|
+
exchangeName: "",
|
|
561
|
+
frameName: "",
|
|
562
|
+
});
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
441
567
|
{
|
|
442
568
|
provide(TYPES.loggerService, () => new LoggerService());
|
|
443
569
|
}
|
|
@@ -457,6 +583,9 @@ class PineConnectionService {
|
|
|
457
583
|
{
|
|
458
584
|
provide(TYPES.pineConnectionService, () => new PineConnectionService());
|
|
459
585
|
}
|
|
586
|
+
{
|
|
587
|
+
provide(TYPES.pineMarkdownService, () => new PineMarkdownService());
|
|
588
|
+
}
|
|
460
589
|
|
|
461
590
|
const commonServices = {
|
|
462
591
|
loggerService: inject(TYPES.loggerService),
|
|
@@ -477,6 +606,9 @@ const cacheServices = {
|
|
|
477
606
|
const connectionServices = {
|
|
478
607
|
pineConnectionService: inject(TYPES.pineConnectionService),
|
|
479
608
|
};
|
|
609
|
+
const markdownServices = {
|
|
610
|
+
pineMarkdownService: inject(TYPES.pineMarkdownService),
|
|
611
|
+
};
|
|
480
612
|
const pine = {
|
|
481
613
|
...commonServices,
|
|
482
614
|
...providerServices,
|
|
@@ -484,6 +616,7 @@ const pine = {
|
|
|
484
616
|
...dataServices,
|
|
485
617
|
...cacheServices,
|
|
486
618
|
...connectionServices,
|
|
619
|
+
...markdownServices,
|
|
487
620
|
};
|
|
488
621
|
init();
|
|
489
622
|
|
|
@@ -548,6 +681,7 @@ const SIGNAL_SCHEMA = {
|
|
|
548
681
|
function toSignalDto(data) {
|
|
549
682
|
if (data.position === 1) {
|
|
550
683
|
return {
|
|
684
|
+
id: functoolsKit.randomString(),
|
|
551
685
|
position: "long",
|
|
552
686
|
priceOpen: data.priceOpen,
|
|
553
687
|
priceTakeProfit: data.priceTakeProfit,
|
|
@@ -557,6 +691,7 @@ function toSignalDto(data) {
|
|
|
557
691
|
}
|
|
558
692
|
if (data.position === -1) {
|
|
559
693
|
return {
|
|
694
|
+
id: functoolsKit.randomString(),
|
|
560
695
|
position: "short",
|
|
561
696
|
priceOpen: data.priceOpen,
|
|
562
697
|
priceTakeProfit: data.priceTakeProfit,
|
|
@@ -578,9 +713,20 @@ async function getSignal(source, { symbol, timeframe, limit }) {
|
|
|
578
713
|
return toSignalDto(data);
|
|
579
714
|
}
|
|
580
715
|
|
|
716
|
+
const DUMP_SIGNAL_METHOD_NAME = "dump.dumpSignal";
|
|
717
|
+
async function dumpPineData(signalId, plots, taName, outputDir = "./dump/ta") {
|
|
718
|
+
pine.loggerService.log(DUMP_SIGNAL_METHOD_NAME, {
|
|
719
|
+
signalId,
|
|
720
|
+
plotCount: Object.keys(plots).length,
|
|
721
|
+
outputDir,
|
|
722
|
+
});
|
|
723
|
+
return await pine.pineMarkdownService.dump(signalId, plots, taName, outputDir);
|
|
724
|
+
}
|
|
725
|
+
|
|
581
726
|
exports.AXIS_SYMBOL = AXIS_SYMBOL;
|
|
582
727
|
exports.Code = Code;
|
|
583
728
|
exports.File = File;
|
|
729
|
+
exports.dumpPineData = dumpPineData;
|
|
584
730
|
exports.getSignal = getSignal;
|
|
585
731
|
exports.lib = pine;
|
|
586
732
|
exports.run = run;
|
package/build/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { join } from 'path';
|
|
2
|
-
import { getDate, getRawCandles } from 'backtest-kit';
|
|
2
|
+
import { getDate, getRawCandles, Markdown } from 'backtest-kit';
|
|
3
3
|
import { createActivator } from 'di-kit';
|
|
4
|
-
import { singleshot, memoize } from 'functools-kit';
|
|
4
|
+
import { singleshot, memoize, randomString } from 'functools-kit';
|
|
5
5
|
import fs from 'fs/promises';
|
|
6
6
|
import { createRequire } from 'module';
|
|
7
7
|
|
|
@@ -96,6 +96,9 @@ const cacheServices$1 = {
|
|
|
96
96
|
const connectionServices$1 = {
|
|
97
97
|
pineConnectionService: Symbol("pineConnectionService"),
|
|
98
98
|
};
|
|
99
|
+
const markdownServices$1 = {
|
|
100
|
+
pineMarkdownService: Symbol("pineMarkdownService"),
|
|
101
|
+
};
|
|
99
102
|
const TYPES = {
|
|
100
103
|
...baseServices,
|
|
101
104
|
...providerServices$1,
|
|
@@ -103,6 +106,7 @@ const TYPES = {
|
|
|
103
106
|
...dataServices$1,
|
|
104
107
|
...cacheServices$1,
|
|
105
108
|
...connectionServices$1,
|
|
109
|
+
...markdownServices$1,
|
|
106
110
|
};
|
|
107
111
|
|
|
108
112
|
const MS_PER_MINUTE = 60000;
|
|
@@ -435,6 +439,128 @@ class PineConnectionService {
|
|
|
435
439
|
}
|
|
436
440
|
}
|
|
437
441
|
|
|
442
|
+
const DEFAULT_FORMAT = (v) => v !== null ? Number(v).toFixed(4) : "N/A";
|
|
443
|
+
function isUnsafe(value) {
|
|
444
|
+
if (value === null)
|
|
445
|
+
return true;
|
|
446
|
+
if (typeof value !== "number")
|
|
447
|
+
return true;
|
|
448
|
+
if (isNaN(value))
|
|
449
|
+
return true;
|
|
450
|
+
if (!isFinite(value))
|
|
451
|
+
return true;
|
|
452
|
+
return false;
|
|
453
|
+
}
|
|
454
|
+
function extractRowAtIndex(plots, keys, index) {
|
|
455
|
+
let time = null;
|
|
456
|
+
for (const key of keys) {
|
|
457
|
+
const plotData = plots[key]?.data;
|
|
458
|
+
if (plotData && plotData[index]) {
|
|
459
|
+
time = plotData[index].time;
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
if (time === null)
|
|
464
|
+
return null;
|
|
465
|
+
const row = { time };
|
|
466
|
+
for (const key of keys) {
|
|
467
|
+
const plotData = plots[key]?.data;
|
|
468
|
+
if (plotData && plotData[index]) {
|
|
469
|
+
const value = plotData[index].value;
|
|
470
|
+
row[key] = isUnsafe(value) ? null : value;
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
row[key] = null;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
return row;
|
|
477
|
+
}
|
|
478
|
+
function isRowWarmedUp(row, keys) {
|
|
479
|
+
for (const key of keys) {
|
|
480
|
+
if (!row[key]) {
|
|
481
|
+
return false;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return true;
|
|
485
|
+
}
|
|
486
|
+
function generateMarkdownTable(rows, keys, signalId) {
|
|
487
|
+
let markdown = "";
|
|
488
|
+
markdown += `# PineScript Technical Analysis Dump\n\n`;
|
|
489
|
+
markdown += `**Signal ID**: ${String(signalId)}\n\n`;
|
|
490
|
+
const header = `| Timestamp | ${keys.join(" | ")} |\n`;
|
|
491
|
+
const separator = `| --- | ${keys.map(() => "---").join(" | ")} |\n`;
|
|
492
|
+
markdown += header;
|
|
493
|
+
markdown += separator;
|
|
494
|
+
for (const row of rows) {
|
|
495
|
+
const timestamp = new Date(row.time).toISOString();
|
|
496
|
+
const cells = keys.map((key) => DEFAULT_FORMAT(row[key]));
|
|
497
|
+
markdown += `| ${timestamp} | ${cells.join(" | ")} |\n`;
|
|
498
|
+
}
|
|
499
|
+
return markdown;
|
|
500
|
+
}
|
|
501
|
+
class PineMarkdownService {
|
|
502
|
+
constructor() {
|
|
503
|
+
this.loggerService = inject(TYPES.loggerService);
|
|
504
|
+
this.getData = (plots) => {
|
|
505
|
+
this.loggerService.log("pineMarkdownService getReport", {
|
|
506
|
+
plotCount: Object.keys(plots).length,
|
|
507
|
+
});
|
|
508
|
+
const keys = Object.keys(plots);
|
|
509
|
+
if (keys.length === 0) {
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
const firstPlot = plots[keys[0]];
|
|
513
|
+
const dataLength = firstPlot?.data?.length ?? 0;
|
|
514
|
+
if (dataLength === 0) {
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
const rows = [];
|
|
518
|
+
let warmupComplete = false;
|
|
519
|
+
for (let i = 0; i < dataLength; i++) {
|
|
520
|
+
const row = extractRowAtIndex(plots, keys, i);
|
|
521
|
+
if (!row)
|
|
522
|
+
continue;
|
|
523
|
+
if (!warmupComplete) {
|
|
524
|
+
if (isRowWarmedUp(row, keys)) {
|
|
525
|
+
warmupComplete = true;
|
|
526
|
+
}
|
|
527
|
+
else {
|
|
528
|
+
continue;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
rows.push(row);
|
|
532
|
+
}
|
|
533
|
+
return rows;
|
|
534
|
+
};
|
|
535
|
+
this.getReport = (signalId, plots) => {
|
|
536
|
+
this.loggerService.log("pineMarkdownService getReport", {
|
|
537
|
+
signalId,
|
|
538
|
+
plotCount: Object.keys(plots).length,
|
|
539
|
+
});
|
|
540
|
+
const rows = this.getData(plots);
|
|
541
|
+
const keys = Object.keys(plots);
|
|
542
|
+
return generateMarkdownTable(rows, keys, signalId);
|
|
543
|
+
};
|
|
544
|
+
this.dump = async (signalId, plots, taName, outputDir = `./dump/ta/${taName}`) => {
|
|
545
|
+
this.loggerService.log("pineMarkdownService dumpSignal", {
|
|
546
|
+
signalId,
|
|
547
|
+
plotCount: Object.keys(plots).length,
|
|
548
|
+
outputDir,
|
|
549
|
+
});
|
|
550
|
+
const content = this.getReport(signalId, plots);
|
|
551
|
+
await Markdown.writeData(taName, content, {
|
|
552
|
+
path: outputDir,
|
|
553
|
+
file: `${String(signalId)}.md`,
|
|
554
|
+
symbol: "",
|
|
555
|
+
signalId: String(signalId),
|
|
556
|
+
strategyName: "",
|
|
557
|
+
exchangeName: "",
|
|
558
|
+
frameName: "",
|
|
559
|
+
});
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
438
564
|
{
|
|
439
565
|
provide(TYPES.loggerService, () => new LoggerService());
|
|
440
566
|
}
|
|
@@ -454,6 +580,9 @@ class PineConnectionService {
|
|
|
454
580
|
{
|
|
455
581
|
provide(TYPES.pineConnectionService, () => new PineConnectionService());
|
|
456
582
|
}
|
|
583
|
+
{
|
|
584
|
+
provide(TYPES.pineMarkdownService, () => new PineMarkdownService());
|
|
585
|
+
}
|
|
457
586
|
|
|
458
587
|
const commonServices = {
|
|
459
588
|
loggerService: inject(TYPES.loggerService),
|
|
@@ -474,6 +603,9 @@ const cacheServices = {
|
|
|
474
603
|
const connectionServices = {
|
|
475
604
|
pineConnectionService: inject(TYPES.pineConnectionService),
|
|
476
605
|
};
|
|
606
|
+
const markdownServices = {
|
|
607
|
+
pineMarkdownService: inject(TYPES.pineMarkdownService),
|
|
608
|
+
};
|
|
477
609
|
const pine = {
|
|
478
610
|
...commonServices,
|
|
479
611
|
...providerServices,
|
|
@@ -481,6 +613,7 @@ const pine = {
|
|
|
481
613
|
...dataServices,
|
|
482
614
|
...cacheServices,
|
|
483
615
|
...connectionServices,
|
|
616
|
+
...markdownServices,
|
|
484
617
|
};
|
|
485
618
|
init();
|
|
486
619
|
|
|
@@ -545,6 +678,7 @@ const SIGNAL_SCHEMA = {
|
|
|
545
678
|
function toSignalDto(data) {
|
|
546
679
|
if (data.position === 1) {
|
|
547
680
|
return {
|
|
681
|
+
id: randomString(),
|
|
548
682
|
position: "long",
|
|
549
683
|
priceOpen: data.priceOpen,
|
|
550
684
|
priceTakeProfit: data.priceTakeProfit,
|
|
@@ -554,6 +688,7 @@ function toSignalDto(data) {
|
|
|
554
688
|
}
|
|
555
689
|
if (data.position === -1) {
|
|
556
690
|
return {
|
|
691
|
+
id: randomString(),
|
|
557
692
|
position: "short",
|
|
558
693
|
priceOpen: data.priceOpen,
|
|
559
694
|
priceTakeProfit: data.priceTakeProfit,
|
|
@@ -575,4 +710,14 @@ async function getSignal(source, { symbol, timeframe, limit }) {
|
|
|
575
710
|
return toSignalDto(data);
|
|
576
711
|
}
|
|
577
712
|
|
|
578
|
-
|
|
713
|
+
const DUMP_SIGNAL_METHOD_NAME = "dump.dumpSignal";
|
|
714
|
+
async function dumpPineData(signalId, plots, taName, outputDir = "./dump/ta") {
|
|
715
|
+
pine.loggerService.log(DUMP_SIGNAL_METHOD_NAME, {
|
|
716
|
+
signalId,
|
|
717
|
+
plotCount: Object.keys(plots).length,
|
|
718
|
+
outputDir,
|
|
719
|
+
});
|
|
720
|
+
return await pine.pineMarkdownService.dump(signalId, plots, taName, outputDir);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
export { AXIS_SYMBOL, Code, File, dumpPineData, getSignal, pine as lib, run, setLogger, usePine };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backtest-kit/pinets",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Run TradingView Pine Script strategies in Node.js self hosted environment. Execute existing Pine Script indicators and generate trading signals with 1:1 syntax compatibility via PineTS runtime.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Petr Tripolsky",
|
package/types.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { TPineCtor as TPineCtor$1 } from 'src/interface/Pine.interface';
|
|
2
1
|
import { CandleInterval, ISignalDto } from 'backtest-kit';
|
|
3
2
|
|
|
4
3
|
declare class Code {
|
|
@@ -18,8 +17,6 @@ declare class File {
|
|
|
18
17
|
static isFile: (value: unknown) => value is File;
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
declare function usePine<T = TPineCtor$1>(ctor: T): void;
|
|
22
|
-
|
|
23
20
|
type PlotData = {
|
|
24
21
|
time: number;
|
|
25
22
|
value: number;
|
|
@@ -32,6 +29,19 @@ type PlotRecord = {
|
|
|
32
29
|
plots: PlotModel;
|
|
33
30
|
};
|
|
34
31
|
|
|
32
|
+
interface IProvider {
|
|
33
|
+
getMarketData(tickerId: string, timeframe: string, limit?: number, sDate?: number, eDate?: number): Promise<any>;
|
|
34
|
+
getSymbolInfo(tickerId: string): Promise<any>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
type TPineCtor = (source: IProvider, tickerId: string, timeframe: string, limit: number) => IPine;
|
|
38
|
+
interface IPine {
|
|
39
|
+
ready(): Promise<void>;
|
|
40
|
+
run(code: string): Promise<PlotRecord>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
declare function usePine<T = TPineCtor>(ctor: T): void;
|
|
44
|
+
|
|
35
45
|
type PlotExtractConfig<T = number> = {
|
|
36
46
|
plot: string;
|
|
37
47
|
barsBack?: number;
|
|
@@ -72,6 +82,9 @@ interface IParams {
|
|
|
72
82
|
}
|
|
73
83
|
declare function getSignal(source: File | Code, { symbol, timeframe, limit }: IParams): Promise<ISignalDto | null>;
|
|
74
84
|
|
|
85
|
+
type ResultId$1 = string | number;
|
|
86
|
+
declare function dumpPineData(signalId: ResultId$1, plots: PlotModel, taName: string, outputDir?: string): Promise<void>;
|
|
87
|
+
|
|
75
88
|
interface CandleModel {
|
|
76
89
|
openTime: number;
|
|
77
90
|
open: number;
|
|
@@ -91,17 +104,6 @@ interface SymbolInfoModel {
|
|
|
91
104
|
timezone: string;
|
|
92
105
|
}
|
|
93
106
|
|
|
94
|
-
interface IProvider {
|
|
95
|
-
getMarketData(tickerId: string, timeframe: string, limit?: number, sDate?: number, eDate?: number): Promise<any>;
|
|
96
|
-
getSymbolInfo(tickerId: string): Promise<any>;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
type TPineCtor = (source: IProvider, tickerId: string, timeframe: string, limit: number) => IPine;
|
|
100
|
-
interface IPine {
|
|
101
|
-
ready(): Promise<void>;
|
|
102
|
-
run(code: string): Promise<PlotRecord>;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
107
|
declare const AXIS_SYMBOL = "_AXIS";
|
|
106
108
|
declare class AxisProviderService implements IProvider {
|
|
107
109
|
private readonly loggerService;
|
|
@@ -146,7 +148,20 @@ declare class PineCacheService {
|
|
|
146
148
|
clear: (path?: string, baseDir?: string) => Promise<void>;
|
|
147
149
|
}
|
|
148
150
|
|
|
151
|
+
type ResultId = string | number;
|
|
152
|
+
interface IPlotRow {
|
|
153
|
+
time: number;
|
|
154
|
+
[key: string]: number | null;
|
|
155
|
+
}
|
|
156
|
+
declare class PineMarkdownService {
|
|
157
|
+
private readonly loggerService;
|
|
158
|
+
getData: (plots: PlotModel) => IPlotRow[];
|
|
159
|
+
getReport: (signalId: ResultId, plots: PlotModel) => string;
|
|
160
|
+
dump: (signalId: ResultId, plots: PlotModel, taName: string, outputDir?: string) => Promise<void>;
|
|
161
|
+
}
|
|
162
|
+
|
|
149
163
|
declare const pine: {
|
|
164
|
+
pineMarkdownService: PineMarkdownService;
|
|
150
165
|
pineConnectionService: PineConnectionService;
|
|
151
166
|
pineCacheService: PineCacheService;
|
|
152
167
|
pineDataService: PineDataService;
|
|
@@ -156,4 +171,4 @@ declare const pine: {
|
|
|
156
171
|
loggerService: LoggerService;
|
|
157
172
|
};
|
|
158
173
|
|
|
159
|
-
export { AXIS_SYMBOL, type CandleModel, Code, File, type ILogger, type IPine, type IProvider, type PlotExtractConfig, type PlotMapping, type PlotModel, type PlotRecord, type SymbolInfoModel, type TPineCtor, getSignal, pine as lib, run, setLogger, usePine };
|
|
174
|
+
export { AXIS_SYMBOL, type CandleModel, Code, File, type ILogger, type IPine, type IProvider, type PlotExtractConfig, type PlotMapping, type PlotModel, type PlotRecord, type SymbolInfoModel, type TPineCtor, dumpPineData, getSignal, pine as lib, run, setLogger, usePine };
|