Skip to content

Commit 663a6c3

Browse files
committed
Support of volume-based built-in indicators
1 parent abbd941 commit 663a6c3

File tree

5 files changed

+67
-103
lines changed

5 files changed

+67
-103
lines changed

README.md

Lines changed: 4 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Get realtime market prices and indicator values from Tradingview !
33

44
## Features
5+
- [x] Premium features
56
- [x] Automatically backtest many strategies and try many settings in a very little time
67
- [x] Get drawings you made on your chart
78
- [x] Works with invite-only indicators
@@ -14,7 +15,7 @@ Get realtime market prices and indicator values from Tradingview !
1415
- [ ] Get Screener top values
1516
- [ ] Get Hotlists
1617
- [ ] Get Calendar
17-
- IF YOU WANT A FEATURE, ASK ME !!
18+
- IF YOU WANT A FEATURE, ASK ME !
1819

1920
## Possibilities
2021
- Trading bot
@@ -30,102 +31,9 @@ ___
3031
npm i @mathieuc/tradingview
3132
```
3233

33-
## Examples (./tests/)
34+
## Examples
35+
You can find all the examples and snippets in `./examples` folder.
3436

35-
```javascript
36-
/*
37-
./tests/prices.js
38-
Search for Bitcoin and Ethereum and get real time prices
39-
*/
40-
41-
const marketAPI = require('tradingview');
42-
43-
(async () => {
44-
const market = marketAPI();
45-
46-
market.on('logged', async () => {
47-
console.log('API LOGGED');
48-
49-
const searchBTC = (await market.search('bitcoin euro', 'crypto'))[0];
50-
console.log('Found Bitcoin / Euro:', searchBTC);
51-
market.subscribe(searchBTC.id);
52-
});
53-
54-
market.on('price', (data) => {
55-
console.log(data.symbol, '=>', data.price);
56-
});
57-
58-
const searchETH = (await market.search('ethereum euro', 'crypto'))[0];
59-
console.log('Found Ethereum / Euro:', searchETH);
60-
61-
setTimeout(() => {
62-
console.log('Subscribe to', searchETH.id);
63-
market.subscribe(searchETH.id);
64-
}, 10000);
65-
66-
setTimeout(() => {
67-
console.log('Unsubscribe from', searchETH.id);
68-
market.unsubscribe(searchETH.id);
69-
}, 20000);
70-
})();
71-
```
72-
73-
```javascript
74-
/*
75-
./tests/analysis.js
76-
Search for Bitcoin and get the Technical Analysis in all timeframes
77-
*/
78-
79-
const marketAPI = require('tradingview');
80-
81-
(async () => {
82-
const market = marketAPI(false);
83-
84-
const searchBTC = (await market.search('bitcoin euro', 'crypto'))[0];
85-
console.log('Found Bitcoin / Euro:', searchBTC);
86-
87-
const TA = await searchBTC.getTA();
88-
console.log('Full technical analysis for Bitcoin:', TA);
89-
90-
// You can also use this way: await market.getTA('crypto', 'BINANCE:BTCEUR');
91-
})();
92-
```
93-
94-
```javascript
95-
/*
96-
./tests/indicator.js
97-
Get indicator values
98-
*/
99-
100-
const marketAPI = require('tradingview');
101-
102-
const market = marketAPI(false); // 'false' for chart-only mode
103-
104-
market.on('logged', () => {
105-
market.initChart({
106-
symbol: 'COINBASE:BTCEUR',
107-
period: '240',
108-
range: 50,
109-
indicators: [
110-
{ name: 'ACCU_DISTRIB', id: 'STD;Accumulation_Distribution', version: '25' },
111-
{ name: 'CIPHER_A', id: 'PUB;vrOJcNRPULteowIsuP6iHn3GIxBJdXwT', version: '1.0' },
112-
{ name: 'CIPHER_B', id: 'PUB;uA35GeckoTA2EfgI63SD2WCSmca4njxp', version: '15.0' },
113-
// Color Changing moving average
114-
{ name: 'CCMA', id: 'PUB;5nawr3gCESvSHQfOhrLPqQqT4zM23w3X', version: '6.0' },
115-
],
116-
}, (periods) => {
117-
if (!periods[0].CIPHER_B) return;
118-
if (!periods[0].CCMA) return;
119-
120-
console.log('Last period:', {
121-
price: periods[0].$prices.close,
122-
moneyFlow: (periods[0].CIPHER_B.RSIMFIArea >= 0) ? 'POSITIVE' : 'NEGATIVE',
123-
VWAP: periods[0].CIPHER_B.VWAP,
124-
MA: (periods[0].CCMA.Plot <= periods[0].$prices.close) ? 'ABOVE' : 'UNDER',
125-
});
126-
});
127-
});
128-
```
12937
___
13038
## Problems
13139
If you have errors in console or unwanted behavior,

examples/BuiltInIndicator.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,28 @@ const client = new TradingView.Client({
1414
const chart = new client.Session.Chart();
1515
chart.setMarket('BINANCE:BTCEUR', {
1616
timeframe: '60',
17+
range: 1,
1718
});
1819

1920
const volumeProfile = new TradingView.BuiltInIndicator('VbPSessions@tv-volumebyprice-53');
2021

22+
/* Required for other volume-based built-in indicators */
23+
// volumeProfile.setOption('first_bar_time', 1639080000000);
24+
// volumeProfile.setOption('last_bar_time', 1639328400000);
25+
// volumeProfile.setOption('first_visible_bar_time', 1639080000000);
26+
// volumeProfile.setOption('last_visible_bar_time', 1639328400000);
27+
2128
const VOL = new chart.Study(volumeProfile);
2229
VOL.onUpdate(() => {
23-
console.log((VOL.graphic.horizlines));
30+
VOL.graphic.hists
31+
.filter((h) => h.lastBarTime === 0) // We only keep recent volume infos
32+
.sort((a, b) => b.priceHigh - a.priceHigh)
33+
.forEach((h) => {
34+
console.log(
35+
`~ ${Math.round((h.priceHigh + h.priceLow) / 2)} € :`,
36+
`${'_'.repeat(h.rate[0] / 3)}${'_'.repeat(h.rate[1] / 3)}`,
37+
);
38+
});
39+
2440
client.end();
2541
});

src/chart/graphicParser.js

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,38 @@
1818
* @prop {number} id Drawing ID
1919
*/
2020

21+
/**
22+
* @typedef {Object} GraphicHorizline
23+
* @prop {number} id Drawing ID
24+
* @prop {number} level Y position of the line
25+
* @prop {number} startIndex Start index of the line (`chart.periods[line.startIndex]`)
26+
* @prop {number} endIndex End index of the line (`chart.periods[line.endIndex]`)
27+
* @prop {boolean} extendRight Is the line extended to the right
28+
* @prop {boolean} extendLeft Is the line extended to the left
29+
*/
30+
31+
/**
32+
* @typedef {Object} GraphicPoint
33+
* @prop {number} index X position of the point
34+
* @prop {number} level Y position of the point
35+
*/
36+
37+
/**
38+
* @typedef {Object} GraphicPolygon
39+
* @prop {number} id Drawing ID
40+
* @prop {GraphicPoint[]} points List of polygon points
41+
*/
42+
43+
/**
44+
* @typedef {Object} GraphicHist
45+
* @prop {number} id Drawing ID
46+
* @prop {number} priceLow Low Y position
47+
* @prop {number} priceHigh High Y position
48+
* @prop {number} firstBarTime First X position
49+
* @prop {number} lastBarTime Last X position
50+
* @prop {number[]} rate List of values
51+
*/
52+
2153
/**
2254
* @typedef {Object} GraphicData List of drawings indexed by type
2355
* @prop {GraphicLabel[]} labels List of labels drawings
@@ -35,7 +67,7 @@
3567
* @returns {GraphicData}
3668
*/
3769
module.exports = function graphicParse(rawGraphic = {}, indexes = []) {
38-
// console.log(rawGraphic, indexes);
70+
// console.log('indexes', indexes);
3971
return {
4072
labels: Object.values(rawGraphic.dwglabels ?? {}).map((l) => ({
4173
...l,
@@ -55,14 +87,22 @@ module.exports = function graphicParse(rawGraphic = {}, indexes = []) {
5587

5688
horizlines: Object.values(rawGraphic.horizlines ?? {}).map((h) => ({
5789
...h,
90+
startIndex: indexes[h.startIndex],
91+
endIndex: indexes[h.endIndex],
5892
})),
5993

6094
polygons: Object.values(rawGraphic.polygons ?? {}).map((p) => ({
6195
...p,
96+
points: p.points.map((pt) => ({
97+
...pt,
98+
index: indexes[pt.index],
99+
})),
62100
})),
63101

64102
hists: Object.values(rawGraphic.hhists ?? {}).map((h) => ({
65103
...h,
104+
firstBarTime: indexes[h.firstBarTime],
105+
lastBarTime: indexes[h.lastBarTime],
66106
})),
67107

68108
raw: rawGraphic,

src/chart/study.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,12 +247,12 @@ module.exports = (chartSession) => class ChartStudy {
247247
Object.keys(this.#graphic).forEach((drawType) => {
248248
this.#graphic[drawType] = {};
249249
});
250-
} else this.#graphic[instruction.type] = {};
250+
} else delete this.#graphic[instruction.type];
251251
return;
252252
}
253253

254254
if (instruction.action === 'one') {
255-
this.#graphic[instruction.type][instruction.id] = {};
255+
delete this.#graphic[instruction.type][instruction.id];
256256
}
257257
// Can an 'instruction' contains other things ?
258258
});
@@ -269,7 +269,7 @@ module.exports = (chartSession) => class ChartStudy {
269269
});
270270
}
271271

272-
console.log('graphicsCmds', Object.keys(parsed.graphicsCmds));
272+
// console.log('graphicsCmds', Object.keys(parsed.graphicsCmds));
273273
// Can 'graphicsCmds' contains other things ?
274274

275275
changes.push('graphic');

src/miscRequests.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,8 @@ module.exports = {
328328
});
329329

330330
return new PineIndicator({
331-
pineId: indicID,
332-
pineVersion: version,
331+
pineId: data.result.metaInfo.scriptIdPart || indicID,
332+
pineVersion: data.result.metaInfo.pine.version || version,
333333
description: data.result.metaInfo.description,
334334
shortDescription: data.result.metaInfo.shortDescription,
335335
inputs,

0 commit comments

Comments
 (0)