binbot-charts 0.0.22 → 0.1.3
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.
|
@@ -5,7 +5,7 @@ require("core-js/modules/web.dom-collections.iterator.js");
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
-
exports.default =
|
|
8
|
+
exports.default = TVChartContainer;
|
|
9
9
|
|
|
10
10
|
var _react = _interopRequireWildcard(require("react"));
|
|
11
11
|
|
|
@@ -19,73 +19,47 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
|
|
|
19
19
|
|
|
20
20
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
21
21
|
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
function TVChartContainer(_ref) {
|
|
23
|
+
let {
|
|
24
|
+
apiKey,
|
|
25
|
+
symbol = "Binance:APE/USDT",
|
|
26
|
+
interval = "1D",
|
|
27
|
+
libraryPath = "/charting_library/",
|
|
28
|
+
timescaleMarks = [],
|
|
29
|
+
orderLines = [],
|
|
30
|
+
height = "calc(100vh - 80px)"
|
|
31
|
+
} = _ref;
|
|
32
|
+
const containerRef = (0, _react.useRef)(null);
|
|
33
|
+
(0, _react.useEffect)(() => {
|
|
34
34
|
const widgetOptions = {
|
|
35
|
-
symbol:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
library_path: this.props.libraryPath,
|
|
35
|
+
symbol: symbol,
|
|
36
|
+
datafeed: new _datafeed.default(apiKey, timescaleMarks),
|
|
37
|
+
interval: interval,
|
|
38
|
+
container: containerRef.current,
|
|
39
|
+
library_path: libraryPath,
|
|
41
40
|
locale: "en",
|
|
42
|
-
fullscreen:
|
|
43
|
-
autosize:
|
|
44
|
-
studies_overrides:
|
|
41
|
+
fullscreen: false,
|
|
42
|
+
autosize: true,
|
|
43
|
+
studies_overrides: {}
|
|
45
44
|
};
|
|
46
45
|
const tvWidget = new _charting_library.widget(widgetOptions);
|
|
47
|
-
this.tvWidget = tvWidget;
|
|
48
46
|
tvWidget.onChartReady(() => {
|
|
49
|
-
|
|
50
|
-
tvWidget.chart().createPositionLine().setText(element.text).setTooltip(element.tooltip)
|
|
51
|
-
// .setCloseTooltip("Close position")
|
|
52
|
-
// .setReverseTooltip("Reverse position")
|
|
53
|
-
.setQuantity(element.quantity).setQuantityBackgroundColor(element.color).setQuantityBorderColor(element.color) // .setExtendLeft(false)
|
|
54
|
-
.setLineStyle(0).setLineLength(25).setLineColor(element.color).setBodyBackgroundColor(element.color).setBodyBorderColor(element.color).setBodyTextColor(element.color).setPrice(element.price);
|
|
47
|
+
orderLines.forEach(element => {
|
|
48
|
+
tvWidget.chart().createPositionLine().setText(element.text).setTooltip(element.tooltip).setQuantity(element.quantity).setQuantityBackgroundColor(element.color).setQuantityBorderColor(element.color).setLineStyle(0).setLineLength(25).setLineColor(element.color).setBodyBorderColor(element.color).setBodyTextColor(element.color).setPrice(element.price);
|
|
55
49
|
});
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
componentWillUnmount() {
|
|
60
|
-
if (this.tvWidget !== null) {
|
|
61
|
-
this.tvWidget.remove();
|
|
62
|
-
this.tvWidget = null;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
50
|
+
}); // returned function will be called on component unmount
|
|
65
51
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
height: "calc(100vh - 80px)"
|
|
52
|
+
return () => {
|
|
53
|
+
if (this.tvWidget !== null) {
|
|
54
|
+
this.tvWidget.remove();
|
|
55
|
+
this.tvWidget = null;
|
|
71
56
|
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
interval: "D",
|
|
82
|
-
datafeedUrl: "https://demo_feed.tradingview.com",
|
|
83
|
-
libraryPath: "/charting_library/",
|
|
84
|
-
chartsStorageUrl: "https://saveload.tradingview.com",
|
|
85
|
-
chartsStorageApiVersion: "1.1",
|
|
86
|
-
clientId: "tradingview.com",
|
|
87
|
-
userId: "public_user_id",
|
|
88
|
-
fullscreen: false,
|
|
89
|
-
autosize: true,
|
|
90
|
-
studiesOverrides: {}
|
|
91
|
-
});
|
|
57
|
+
};
|
|
58
|
+
}, []);
|
|
59
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
60
|
+
ref: containerRef,
|
|
61
|
+
style: {
|
|
62
|
+
height: height
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
@@ -21,60 +21,40 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
21
21
|
|
|
22
22
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
23
23
|
|
|
24
|
-
const lastBarsCache = new Map();
|
|
25
24
|
const exchange = "Binance";
|
|
26
|
-
const
|
|
27
|
-
// trading_options: true,
|
|
28
|
-
supports_marks: true,
|
|
29
|
-
supports_time: true,
|
|
30
|
-
supports_timescale_marks: true,
|
|
31
|
-
supported_resolutions: ["1D", "1W", "1M"],
|
|
32
|
-
exchanges: [{
|
|
33
|
-
value: "Binance",
|
|
34
|
-
name: "Binance",
|
|
35
|
-
desc: "Binance"
|
|
36
|
-
}],
|
|
37
|
-
symbols_types: [{
|
|
38
|
-
name: "crypto",
|
|
39
|
-
value: "crypto"
|
|
40
|
-
}]
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
async function getAllSymbols() {
|
|
44
|
-
const data = await (0, _helpers.makeApiRequest)("data/v3/all/exchanges");
|
|
45
|
-
let allSymbols = [];
|
|
46
|
-
const pairs = data.Data[exchange].pairs;
|
|
47
|
-
|
|
48
|
-
for (const leftPairPart of Object.keys(pairs)) {
|
|
49
|
-
const symbols = pairs[leftPairPart].map(rightPairPart => {
|
|
50
|
-
const symbol = (0, _helpers.generateSymbol)(exchange, leftPairPart, rightPairPart);
|
|
51
|
-
return {
|
|
52
|
-
symbol: symbol.short,
|
|
53
|
-
full_name: symbol.full,
|
|
54
|
-
description: symbol.short,
|
|
55
|
-
exchange: exchange,
|
|
56
|
-
type: "crypto"
|
|
57
|
-
};
|
|
58
|
-
});
|
|
59
|
-
allSymbols = [...allSymbols, ...symbols];
|
|
60
|
-
}
|
|
25
|
+
const lastBarsCache = new Map();
|
|
61
26
|
|
|
62
|
-
|
|
63
|
-
|
|
27
|
+
const getConfigurationData = async () => {
|
|
28
|
+
return {
|
|
29
|
+
supports_marks: true,
|
|
30
|
+
supports_time: true,
|
|
31
|
+
supports_timescale_marks: true,
|
|
32
|
+
selected_resolution: "m",
|
|
33
|
+
exchanges: [{
|
|
34
|
+
value: "Binance",
|
|
35
|
+
name: "Binance",
|
|
36
|
+
desc: "Binance"
|
|
37
|
+
}],
|
|
38
|
+
symbols_types: [{
|
|
39
|
+
name: "crypto",
|
|
40
|
+
value: "crypto"
|
|
41
|
+
}]
|
|
42
|
+
};
|
|
43
|
+
};
|
|
64
44
|
|
|
65
45
|
class Datafeed {
|
|
66
|
-
constructor() {
|
|
67
|
-
let timescaleMarks = arguments.length >
|
|
68
|
-
let lineOrders = arguments.length >
|
|
46
|
+
constructor(apiKey) {
|
|
47
|
+
let timescaleMarks = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
48
|
+
let lineOrders = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
69
49
|
|
|
70
|
-
_defineProperty(this, "onReady", callback => {
|
|
71
|
-
|
|
72
|
-
|
|
50
|
+
_defineProperty(this, "onReady", async callback => {
|
|
51
|
+
this.configurationData = await getConfigurationData(this.apiKey);
|
|
52
|
+
callback(this.configurationData);
|
|
73
53
|
});
|
|
74
54
|
|
|
75
55
|
_defineProperty(this, "searchSymbols", async (userInput, exchange, symbolType, onResultReadyCallback) => {
|
|
76
56
|
console.log("[searchSymbols]: Method call");
|
|
77
|
-
const symbols = await getAllSymbols();
|
|
57
|
+
const symbols = await (0, _helpers.getAllSymbols)(exchange);
|
|
78
58
|
const newSymbols = symbols.filter(symbol => {
|
|
79
59
|
const isExchangeValid = exchange === "" || symbol.exchange === exchange;
|
|
80
60
|
const isFullSymbolContainsInput = symbol.full_name.toLowerCase().indexOf(userInput.toLowerCase()) !== -1;
|
|
@@ -84,8 +64,7 @@ class Datafeed {
|
|
|
84
64
|
});
|
|
85
65
|
|
|
86
66
|
_defineProperty(this, "resolveSymbol", async (symbolName, onSymbolResolvedCallback, onResolveErrorCallback) => {
|
|
87
|
-
|
|
88
|
-
const symbols = await getAllSymbols();
|
|
67
|
+
const symbols = await (0, _helpers.getAllSymbols)(exchange);
|
|
89
68
|
const symbolItem = symbols.find(_ref => {
|
|
90
69
|
let {
|
|
91
70
|
full_name
|
|
@@ -94,7 +73,6 @@ class Datafeed {
|
|
|
94
73
|
});
|
|
95
74
|
|
|
96
75
|
if (!symbolItem) {
|
|
97
|
-
console.log("[resolveSymbol]: Cannot resolve symbol", symbolName);
|
|
98
76
|
onResolveErrorCallback("cannot resolve symbol");
|
|
99
77
|
return;
|
|
100
78
|
}
|
|
@@ -112,11 +90,9 @@ class Datafeed {
|
|
|
112
90
|
has_intraday: true,
|
|
113
91
|
has_no_volume: false,
|
|
114
92
|
has_weekly_and_monthly: false,
|
|
115
|
-
supported_resolutions: ["1D", "1W", "1M"],
|
|
116
93
|
volume_precision: 4,
|
|
117
94
|
data_status: "streaming"
|
|
118
95
|
};
|
|
119
|
-
console.log("[resolveSymbol]: Symbol resolved", symbolName);
|
|
120
96
|
onSymbolResolvedCallback(symbolInfo);
|
|
121
97
|
});
|
|
122
98
|
|
|
@@ -176,24 +152,30 @@ class Datafeed {
|
|
|
176
152
|
});
|
|
177
153
|
|
|
178
154
|
_defineProperty(this, "subscribeBars", (symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => {
|
|
179
|
-
console.log(
|
|
155
|
+
console.log('[subscribeBars]: Method call with subscribeUID:', subscribeUID);
|
|
180
156
|
(0, _streaming.subscribeOnStream)(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback, lastBarsCache.get(symbolInfo.full_name));
|
|
181
157
|
});
|
|
182
158
|
|
|
183
159
|
_defineProperty(this, "unsubscribeBars", subscriberUID => {
|
|
184
|
-
console.log(
|
|
160
|
+
console.log('[unsubscribeBars]: Method call with subscriberUID:', subscriberUID);
|
|
185
161
|
(0, _streaming.unsubscribeFromStream)(subscriberUID);
|
|
186
162
|
});
|
|
187
163
|
|
|
188
164
|
this.timescaleMarks = timescaleMarks;
|
|
189
165
|
this.lineOrders = lineOrders;
|
|
166
|
+
this.apiKey = apiKey;
|
|
190
167
|
}
|
|
191
168
|
|
|
192
169
|
getTimescaleMarks(symbolInfo, from, to, onDataCallback, resolution) {
|
|
193
|
-
let timescaleMarks = [];
|
|
194
|
-
|
|
195
170
|
if (this.timescaleMarks.length > 0) {
|
|
196
|
-
timescaleMarks =
|
|
171
|
+
let timescaleMarks = [];
|
|
172
|
+
this.timescaleMarks.forEach(mark => {
|
|
173
|
+
let time = new Date(mark.time * 1000);
|
|
174
|
+
time.setHours(1, 0, 0, 0);
|
|
175
|
+
const roundFloor = time.getTime() / 1000;
|
|
176
|
+
mark.time = roundFloor;
|
|
177
|
+
timescaleMarks.push(mark);
|
|
178
|
+
});
|
|
197
179
|
onDataCallback(timescaleMarks);
|
|
198
180
|
}
|
|
199
181
|
}
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.generateSymbol = generateSymbol;
|
|
7
|
+
exports.getAllSymbols = getAllSymbols;
|
|
7
8
|
exports.makeApiRequest = makeApiRequest;
|
|
8
9
|
exports.parseFullSymbol = parseFullSymbol;
|
|
9
10
|
|
|
@@ -13,6 +14,8 @@ require("core-js/modules/es.regexp.exec.js");
|
|
|
13
14
|
|
|
14
15
|
require("core-js/modules/es.string.match.js");
|
|
15
16
|
|
|
17
|
+
require("core-js/modules/web.dom-collections.iterator.js");
|
|
18
|
+
|
|
16
19
|
// Make requests to CryptoCompare API
|
|
17
20
|
async function makeApiRequest(path) {
|
|
18
21
|
try {
|
|
@@ -44,4 +47,26 @@ function parseFullSymbol(fullSymbol) {
|
|
|
44
47
|
fromSymbol: match[2],
|
|
45
48
|
toSymbol: match[3]
|
|
46
49
|
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function getAllSymbols(exchange) {
|
|
53
|
+
const data = await makeApiRequest("data/v3/all/exchanges");
|
|
54
|
+
let allSymbols = [];
|
|
55
|
+
const pairs = data.Data[exchange].pairs;
|
|
56
|
+
|
|
57
|
+
for (const leftPairPart of Object.keys(pairs)) {
|
|
58
|
+
const symbols = pairs[leftPairPart].map(rightPairPart => {
|
|
59
|
+
const symbol = generateSymbol(exchange, leftPairPart, rightPairPart);
|
|
60
|
+
return {
|
|
61
|
+
symbol: symbol.short,
|
|
62
|
+
full_name: symbol.full,
|
|
63
|
+
description: symbol.short,
|
|
64
|
+
exchange: exchange,
|
|
65
|
+
type: "crypto"
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
allSymbols = [...allSymbols, ...symbols];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return allSymbols;
|
|
47
72
|
}
|
|
@@ -28,20 +28,20 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
28
28
|
|
|
29
29
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
30
30
|
|
|
31
|
-
const socket = (0, _socket.default)(
|
|
31
|
+
const socket = (0, _socket.default)('wss://streamer.cryptocompare.com');
|
|
32
32
|
const channelToSubscription = new Map();
|
|
33
|
-
socket.on(
|
|
34
|
-
console.log(
|
|
33
|
+
socket.on('connect', () => {
|
|
34
|
+
console.log('[socket] Connected');
|
|
35
35
|
});
|
|
36
|
-
socket.on(
|
|
37
|
-
console.log(
|
|
36
|
+
socket.on('disconnect', reason => {
|
|
37
|
+
console.log('[socket] Disconnected:', reason);
|
|
38
38
|
});
|
|
39
|
-
socket.on(
|
|
40
|
-
console.log(
|
|
39
|
+
socket.on('error', error => {
|
|
40
|
+
console.log('[socket] Error:', error);
|
|
41
41
|
});
|
|
42
|
-
socket.on(
|
|
43
|
-
console.log(
|
|
44
|
-
const [eventTypeStr, exchange, fromSymbol, toSymbol
|
|
42
|
+
socket.on('m', data => {
|
|
43
|
+
console.log('[socket] Message:', data);
|
|
44
|
+
const [eventTypeStr, exchange, fromSymbol, toSymbol,,, tradeTimeStr,, tradePriceStr] = data.split('~');
|
|
45
45
|
|
|
46
46
|
if (parseInt(eventTypeStr) !== 0) {
|
|
47
47
|
// skip all non-TRADE events
|
|
@@ -69,14 +69,14 @@ socket.on("m", data => {
|
|
|
69
69
|
low: tradePrice,
|
|
70
70
|
close: tradePrice
|
|
71
71
|
};
|
|
72
|
-
console.log(
|
|
72
|
+
console.log('[socket] Generate new bar', bar);
|
|
73
73
|
} else {
|
|
74
74
|
bar = _objectSpread(_objectSpread({}, lastDailyBar), {}, {
|
|
75
75
|
high: Math.max(lastDailyBar.high, tradePrice),
|
|
76
76
|
low: Math.min(lastDailyBar.low, tradePrice),
|
|
77
77
|
close: tradePrice
|
|
78
78
|
});
|
|
79
|
-
console.log(
|
|
79
|
+
console.log('[socket] Update the latest bar by price', tradePrice);
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
subscriptionItem.lastDailyBar = bar; // send data to every subscriber of that symbol
|
|
@@ -112,8 +112,8 @@ function subscribeOnStream(symbolInfo, resolution, onRealtimeCallback, subscribe
|
|
|
112
112
|
handlers: [handler]
|
|
113
113
|
};
|
|
114
114
|
channelToSubscription.set(channelString, subscriptionItem);
|
|
115
|
-
console.log(
|
|
116
|
-
socket.emit(
|
|
115
|
+
console.log('[subscribeBars]: Subscribe to streaming. Channel:', channelString);
|
|
116
|
+
socket.emit('SubAdd', {
|
|
117
117
|
subs: [channelString]
|
|
118
118
|
});
|
|
119
119
|
}
|
|
@@ -130,8 +130,8 @@ function unsubscribeFromStream(subscriberUID) {
|
|
|
130
130
|
|
|
131
131
|
if (subscriptionItem.handlers.length === 0) {
|
|
132
132
|
// unsubscribe from the channel, if it was the last handler
|
|
133
|
-
console.log(
|
|
134
|
-
socket.emit(
|
|
133
|
+
console.log('[unsubscribeBars]: Unsubscribe from streaming. Channel:', channelString);
|
|
134
|
+
socket.emit('SubRemove', {
|
|
135
135
|
subs: [channelString]
|
|
136
136
|
});
|
|
137
137
|
channelToSubscription.delete(channelString);
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
2
|
+
"version": "0.1.3",
|
|
3
3
|
"name": "binbot-charts",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"@babel/cli": "^7.18.10",
|
|
@@ -8,13 +8,14 @@
|
|
|
8
8
|
"@babel/preset-env": "^7.18.10",
|
|
9
9
|
"react": "^17.0.1",
|
|
10
10
|
"react-dom": "^17.0.1",
|
|
11
|
-
"react-scripts": "5.0.1",
|
|
12
|
-
"socket.io
|
|
11
|
+
"react-scripts": "^5.0.1",
|
|
12
|
+
"socket.io": "1.7.2",
|
|
13
|
+
"use-immer": "^0.7.0"
|
|
13
14
|
},
|
|
14
15
|
"scripts": {
|
|
15
16
|
"start": "react-scripts start",
|
|
16
17
|
"build": "rm -rf dist && NODE_ENV=production babel src/components/ -d dist/components && cp -r src/charting_library dist/charting_library",
|
|
17
|
-
"
|
|
18
|
+
"release": "yarn build && yarn publish"
|
|
18
19
|
},
|
|
19
20
|
"description": "Binbot charts is the default candlestick bars chart used in terminal.binbot.com to render bots graphically.",
|
|
20
21
|
"repository": {
|