binbot-charts 0.1.6 → 0.2.0
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.
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
require("core-js/modules/web.dom-collections.iterator.js");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = TVChartContainer;
|
|
9
|
+
|
|
10
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
11
|
+
|
|
12
|
+
var _charting_library = require("../charting_library");
|
|
13
|
+
|
|
14
|
+
var _datafeed = _interopRequireDefault(require("./datafeed"));
|
|
15
|
+
|
|
16
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
17
|
+
|
|
18
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
|
+
|
|
20
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
21
|
+
|
|
22
|
+
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; }
|
|
23
|
+
|
|
24
|
+
function TVChartContainer(_ref) {
|
|
25
|
+
let {
|
|
26
|
+
symbol = "APEUSDT",
|
|
27
|
+
interval = "1h",
|
|
28
|
+
libraryPath = "/charting_library/",
|
|
29
|
+
timescaleMarks = [],
|
|
30
|
+
orderLines = [],
|
|
31
|
+
height = "calc(100vh - 80px)"
|
|
32
|
+
} = _ref;
|
|
33
|
+
const containerRef = (0, _react.useRef)(null);
|
|
34
|
+
(0, _react.useEffect)(() => {
|
|
35
|
+
const widgetOptions = {
|
|
36
|
+
symbol: symbol,
|
|
37
|
+
datafeed: new _datafeed.default(timescaleMarks),
|
|
38
|
+
interval: interval,
|
|
39
|
+
container: containerRef.current,
|
|
40
|
+
library_path: libraryPath,
|
|
41
|
+
locale: "en",
|
|
42
|
+
fullscreen: false,
|
|
43
|
+
autosize: true,
|
|
44
|
+
studies_overrides: {},
|
|
45
|
+
overrides: {
|
|
46
|
+
volumePaneSize: "small",
|
|
47
|
+
"mainSeriesProperties.barStyle.dontDrawOpen": false
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const tvWidget = new _charting_library.widget(widgetOptions);
|
|
51
|
+
tvWidget.onChartReady(() => {
|
|
52
|
+
if (orderLines.length > 0) {
|
|
53
|
+
orderLines.forEach(order => {
|
|
54
|
+
tvWidget.chart().createPositionLine().setText(order.text).setTooltip(order.tooltip).setQuantity(order.quantity).setQuantityBackgroundColor(order.color).setQuantityBorderColor(order.color).setLineStyle(0).setLineLength(25).setLineColor(order.color).setBodyBorderColor(order.color).setBodyTextColor(order.color).setPrice(order.price);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}); // returned function will be called on component unmount
|
|
58
|
+
|
|
59
|
+
return () => {
|
|
60
|
+
if (this.tvWidget !== null) {
|
|
61
|
+
this.tvWidget.remove();
|
|
62
|
+
this.tvWidget = null;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}, []);
|
|
66
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
67
|
+
ref: containerRef,
|
|
68
|
+
style: {
|
|
69
|
+
height: height
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
TVChartContainer.propTypes = {
|
|
75
|
+
apiKey: _propTypes.default.string,
|
|
76
|
+
symbol: _propTypes.default.string,
|
|
77
|
+
interval: _propTypes.default.string,
|
|
78
|
+
libraryPath: _propTypes.default.string,
|
|
79
|
+
timescaleMarks: _propTypes.default.array,
|
|
80
|
+
orderLines: _propTypes.default.array,
|
|
81
|
+
height: _propTypes.default.string
|
|
82
|
+
};
|
|
@@ -5,31 +5,22 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
-
require("core-js/modules/web.dom-collections.iterator.js");
|
|
9
|
-
|
|
10
8
|
require("core-js/modules/es.promise.js");
|
|
11
9
|
|
|
12
|
-
require("core-js/modules/
|
|
10
|
+
require("core-js/modules/web.dom-collections.iterator.js");
|
|
13
11
|
|
|
14
12
|
var _helpers = require("./helpers.js");
|
|
15
13
|
|
|
16
14
|
var _streaming = require("./streaming.js");
|
|
17
15
|
|
|
18
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
19
|
-
|
|
20
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
21
|
-
|
|
22
16
|
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
17
|
|
|
24
|
-
const exchange = "Binance";
|
|
25
|
-
const lastBarsCache = new Map();
|
|
26
|
-
|
|
27
18
|
const getConfigurationData = async () => {
|
|
28
19
|
return {
|
|
29
20
|
supports_marks: true,
|
|
30
21
|
supports_time: true,
|
|
31
22
|
supports_timescale_marks: true,
|
|
32
|
-
|
|
23
|
+
supported_resolutions: ["1s", "1m", "3m", "5m", "15m", "30m", "1h", "2h", "4h", "6h", "8h", "12h", "1d", "3d", "1w", "1M"],
|
|
33
24
|
exchanges: [{
|
|
34
25
|
value: "Binance",
|
|
35
26
|
name: "Binance",
|
|
@@ -43,55 +34,57 @@ const getConfigurationData = async () => {
|
|
|
43
34
|
};
|
|
44
35
|
|
|
45
36
|
class Datafeed {
|
|
46
|
-
constructor(
|
|
47
|
-
let timescaleMarks = arguments.length >
|
|
48
|
-
let lineOrders = arguments.length >
|
|
37
|
+
constructor() {
|
|
38
|
+
let timescaleMarks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
39
|
+
let lineOrders = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
40
|
+
let interval = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "1h";
|
|
49
41
|
|
|
50
42
|
_defineProperty(this, "onReady", async callback => {
|
|
51
|
-
this.configurationData = await getConfigurationData(
|
|
43
|
+
this.configurationData = await getConfigurationData();
|
|
52
44
|
callback(this.configurationData);
|
|
53
45
|
});
|
|
54
46
|
|
|
55
47
|
_defineProperty(this, "searchSymbols", async (userInput, exchange, symbolType, onResultReadyCallback) => {
|
|
56
|
-
console.log("[searchSymbols]: Method call");
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
48
|
+
console.log("[searchSymbols]: Method call"); // const symbols = await getAllSymbols(exchange);
|
|
49
|
+
// const newSymbols = symbols.filter((symbol) => {
|
|
50
|
+
// const isExchangeValid = exchange === "" || symbol.exchange === exchange;
|
|
51
|
+
// if (symbol.replace("/", "") === userInput) {
|
|
52
|
+
// }
|
|
53
|
+
// const isFullSymbolContainsInput =
|
|
54
|
+
// symbol.full_name.toLowerCase().indexOf(userInput.toLowerCase()) !== -1;
|
|
55
|
+
// return isExchangeValid && isFullSymbolContainsInput;
|
|
56
|
+
// });
|
|
57
|
+
|
|
63
58
|
onResultReadyCallback(newSymbols);
|
|
64
59
|
});
|
|
65
60
|
|
|
66
61
|
_defineProperty(this, "resolveSymbol", async (symbolName, onSymbolResolvedCallback, onResolveErrorCallback) => {
|
|
67
|
-
const symbols = await
|
|
68
|
-
const symbolItem = symbols.find(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (!symbolItem) {
|
|
76
|
-
onResolveErrorCallback("cannot resolve symbol");
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
|
|
62
|
+
// const symbols = await getAllSymbols(exchange);
|
|
63
|
+
// const symbolItem = symbols.find(
|
|
64
|
+
// ({ full_name }) => full_name === symbolName
|
|
65
|
+
// );
|
|
66
|
+
// if (!symbolItem) {
|
|
67
|
+
// onResolveErrorCallback("cannot resolve symbol");
|
|
68
|
+
// return;
|
|
69
|
+
// }
|
|
80
70
|
const symbolInfo = {
|
|
81
|
-
ticker:
|
|
82
|
-
name:
|
|
83
|
-
|
|
84
|
-
|
|
71
|
+
ticker: symbolName,
|
|
72
|
+
name: symbolName,
|
|
73
|
+
ticker: symbolName,
|
|
74
|
+
description: symbolName,
|
|
75
|
+
type: "crypto",
|
|
85
76
|
session: "24x7",
|
|
86
77
|
timezone: "Etc/UTC",
|
|
87
|
-
exchange:
|
|
88
|
-
minmov:
|
|
89
|
-
pricescale:
|
|
78
|
+
exchange: "Binance",
|
|
79
|
+
minmov: 100,
|
|
80
|
+
pricescale: 100000,
|
|
90
81
|
has_intraday: true,
|
|
91
82
|
has_no_volume: false,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
83
|
+
volume: "hundreds",
|
|
84
|
+
has_weekly_and_monthly: true,
|
|
85
|
+
volume_precision: 9,
|
|
86
|
+
data_status: "streaming",
|
|
87
|
+
resolution: "1h"
|
|
95
88
|
};
|
|
96
89
|
onSymbolResolvedCallback(symbolInfo);
|
|
97
90
|
});
|
|
@@ -103,20 +96,19 @@ class Datafeed {
|
|
|
103
96
|
firstDataRequest
|
|
104
97
|
} = periodParams;
|
|
105
98
|
console.log("[getBars]: Method call");
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
limit: 2000
|
|
99
|
+
let urlParameters = {
|
|
100
|
+
symbol: symbolInfo.name,
|
|
101
|
+
interval: this.interval,
|
|
102
|
+
startTime: from * 1000,
|
|
103
|
+
endTime: to * 1000,
|
|
104
|
+
limit: 600
|
|
113
105
|
};
|
|
114
106
|
const query = Object.keys(urlParameters).map(name => "".concat(name, "=").concat(encodeURIComponent(urlParameters[name]))).join("&");
|
|
115
107
|
|
|
116
108
|
try {
|
|
117
|
-
const data = await (0, _helpers.makeApiRequest)("
|
|
109
|
+
const data = await (0, _helpers.makeApiRequest)("api/v3/uiKlines?".concat(query));
|
|
118
110
|
|
|
119
|
-
if (data.Response && data.Response === "Error" || data.
|
|
111
|
+
if (data.Response && data.Response === "Error" || data.length === 0) {
|
|
120
112
|
// "noData" should be set if there is no data in the requested period.
|
|
121
113
|
onHistoryCallback([], {
|
|
122
114
|
noData: true
|
|
@@ -125,22 +117,18 @@ class Datafeed {
|
|
|
125
117
|
}
|
|
126
118
|
|
|
127
119
|
let bars = [];
|
|
128
|
-
data.
|
|
129
|
-
if (bar
|
|
120
|
+
data.forEach(bar => {
|
|
121
|
+
if (bar[0] >= from * 1000 && bar[0] < to * 1000) {
|
|
130
122
|
bars = [...bars, {
|
|
131
|
-
time: bar
|
|
132
|
-
low: bar
|
|
133
|
-
high: bar
|
|
134
|
-
open: bar
|
|
135
|
-
close: bar
|
|
123
|
+
time: bar[0],
|
|
124
|
+
low: bar[3],
|
|
125
|
+
high: bar[2],
|
|
126
|
+
open: bar[1],
|
|
127
|
+
close: bar[4],
|
|
128
|
+
volume: bar[5]
|
|
136
129
|
}];
|
|
137
130
|
}
|
|
138
131
|
});
|
|
139
|
-
|
|
140
|
-
if (firstDataRequest) {
|
|
141
|
-
lastBarsCache.set(symbolInfo.full_name, _objectSpread({}, bars[bars.length - 1]));
|
|
142
|
-
}
|
|
143
|
-
|
|
144
132
|
console.log("[getBars]: returned ".concat(bars.length, " bar(s)"));
|
|
145
133
|
onHistoryCallback(bars, {
|
|
146
134
|
noData: false
|
|
@@ -153,17 +141,18 @@ class Datafeed {
|
|
|
153
141
|
|
|
154
142
|
_defineProperty(this, "subscribeBars", (symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => {
|
|
155
143
|
console.log('[subscribeBars]: Method call with subscribeUID:', subscribeUID);
|
|
156
|
-
(0, _streaming.subscribeOnStream)(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback,
|
|
144
|
+
(0, _streaming.subscribeOnStream)(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback, this.interval);
|
|
157
145
|
});
|
|
158
146
|
|
|
159
147
|
_defineProperty(this, "unsubscribeBars", subscriberUID => {
|
|
160
|
-
console.log(
|
|
148
|
+
console.log("[unsubscribeBars]: Method call with subscriberUID:", subscriberUID);
|
|
161
149
|
(0, _streaming.unsubscribeFromStream)(subscriberUID);
|
|
162
150
|
});
|
|
163
151
|
|
|
164
152
|
this.timescaleMarks = timescaleMarks;
|
|
165
153
|
this.lineOrders = lineOrders;
|
|
166
|
-
this.
|
|
154
|
+
this.streaming = null;
|
|
155
|
+
this.interval = interval;
|
|
167
156
|
}
|
|
168
157
|
|
|
169
158
|
getTimescaleMarks(symbolInfo, from, to, onDataCallback, resolution) {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.default = getNextDailyBarTime;
|
|
6
7
|
exports.generateSymbol = generateSymbol;
|
|
7
8
|
exports.getAllSymbols = getAllSymbols;
|
|
8
9
|
exports.makeApiRequest = makeApiRequest;
|
|
@@ -19,10 +20,10 @@ require("core-js/modules/web.dom-collections.iterator.js");
|
|
|
19
20
|
// Make requests to CryptoCompare API
|
|
20
21
|
async function makeApiRequest(path) {
|
|
21
22
|
try {
|
|
22
|
-
const response = await fetch("https://
|
|
23
|
+
const response = await fetch("https://api.binance.com/".concat(path));
|
|
23
24
|
return response.json();
|
|
24
25
|
} catch (error) {
|
|
25
|
-
throw new Error("
|
|
26
|
+
throw new Error("Binance request error: ".concat(error.status));
|
|
26
27
|
}
|
|
27
28
|
} // Generate a symbol ID from a pair of the coins
|
|
28
29
|
|
|
@@ -69,4 +70,10 @@ async function getAllSymbols(exchange) {
|
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
return allSymbols;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function getNextDailyBarTime(barTime) {
|
|
76
|
+
const date = new Date(barTime * 1000);
|
|
77
|
+
date.setDate(date.getDate() + 1);
|
|
78
|
+
return date.getTime() / 1000;
|
|
72
79
|
}
|
package/dist/components/index.js
CHANGED
|
@@ -12,6 +12,4 @@ Object.defineProperty(exports, "TVChartContainer", {
|
|
|
12
12
|
|
|
13
13
|
var _TVChartContainer = _interopRequireDefault(require("./TVChartContainer"));
|
|
14
14
|
|
|
15
|
-
var _chartingLibraryInterfaces = require("./charting-library-interfaces");
|
|
16
|
-
|
|
17
15
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -8,91 +8,67 @@ exports.unsubscribeFromStream = unsubscribeFromStream;
|
|
|
8
8
|
|
|
9
9
|
require("core-js/modules/web.dom-collections.iterator.js");
|
|
10
10
|
|
|
11
|
-
require("core-js/modules/es.
|
|
11
|
+
require("core-js/modules/es.json.stringify.js");
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
require("core-js/modules/es.parse-int.js");
|
|
16
|
-
|
|
17
|
-
require("core-js/modules/es.parse-float.js");
|
|
18
|
-
|
|
19
|
-
var _helpers = require("./helpers.js");
|
|
20
|
-
|
|
21
|
-
var _socket = _interopRequireDefault(require("socket.io-client"));
|
|
13
|
+
const channelToSubscription = new Map();
|
|
14
|
+
const socket = new WebSocket("wss://stream.binance.com:9443/ws");
|
|
22
15
|
|
|
23
|
-
|
|
16
|
+
socket.onopen = event => {
|
|
17
|
+
console.log("[socket] Connected", event);
|
|
18
|
+
};
|
|
24
19
|
|
|
25
|
-
|
|
20
|
+
socket.onclose = reason => {
|
|
21
|
+
console.log("[socket] Disconnected:", reason);
|
|
22
|
+
};
|
|
26
23
|
|
|
27
|
-
|
|
24
|
+
socket.onerror = error => {
|
|
25
|
+
console.log("[socket] Error:", error);
|
|
26
|
+
};
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
socket.onmessage = e => {
|
|
29
|
+
console.log("[socket] Message:", JSON.parse(e.data));
|
|
30
|
+
const data = JSON.parse(e.data);
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
const channelToSubscription = new Map();
|
|
33
|
-
socket.on('connect', () => {
|
|
34
|
-
console.log('[socket] Connected');
|
|
35
|
-
});
|
|
36
|
-
socket.on('disconnect', reason => {
|
|
37
|
-
console.log('[socket] Disconnected:', reason);
|
|
38
|
-
});
|
|
39
|
-
socket.on('error', error => {
|
|
40
|
-
console.log('[socket] Error:', error);
|
|
41
|
-
});
|
|
42
|
-
socket.on('m', data => {
|
|
43
|
-
console.log('[socket] Message:', data);
|
|
44
|
-
const [eventTypeStr, exchange, fromSymbol, toSymbol,,, tradeTimeStr,, tradePriceStr] = data.split('~');
|
|
45
|
-
|
|
46
|
-
if (parseInt(eventTypeStr) !== 0) {
|
|
32
|
+
if (data.e == undefined) {
|
|
47
33
|
// skip all non-TRADE events
|
|
48
34
|
return;
|
|
49
35
|
}
|
|
50
36
|
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
37
|
+
const {
|
|
38
|
+
s: symbol,
|
|
39
|
+
t: startTime,
|
|
40
|
+
T: closeTime,
|
|
41
|
+
i: interval,
|
|
42
|
+
o: open,
|
|
43
|
+
c: close,
|
|
44
|
+
h: high,
|
|
45
|
+
l: low,
|
|
46
|
+
v: volume,
|
|
47
|
+
n: trades,
|
|
48
|
+
q: quoteVolume
|
|
49
|
+
} = data.k;
|
|
50
|
+
const channelString = "".concat(symbol.toLowerCase(), "@kline_").concat(interval);
|
|
54
51
|
const subscriptionItem = channelToSubscription.get(channelString);
|
|
55
52
|
|
|
56
53
|
if (subscriptionItem === undefined) {
|
|
57
54
|
return;
|
|
58
55
|
}
|
|
59
56
|
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
low: tradePrice,
|
|
70
|
-
close: tradePrice
|
|
71
|
-
};
|
|
72
|
-
console.log('[socket] Generate new bar', bar);
|
|
73
|
-
} else {
|
|
74
|
-
bar = _objectSpread(_objectSpread({}, lastDailyBar), {}, {
|
|
75
|
-
high: Math.max(lastDailyBar.high, tradePrice),
|
|
76
|
-
low: Math.min(lastDailyBar.low, tradePrice),
|
|
77
|
-
close: tradePrice
|
|
78
|
-
});
|
|
79
|
-
console.log('[socket] Update the latest bar by price', tradePrice);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
subscriptionItem.lastDailyBar = bar; // send data to every subscriber of that symbol
|
|
57
|
+
const bar = {
|
|
58
|
+
time: startTime,
|
|
59
|
+
open: open,
|
|
60
|
+
high: high,
|
|
61
|
+
low: low,
|
|
62
|
+
close: close,
|
|
63
|
+
volume: volume
|
|
64
|
+
};
|
|
65
|
+
console.log("[socket] Generate new bar", bar); // send data to every subscriber of that symbol
|
|
83
66
|
|
|
84
67
|
subscriptionItem.handlers.forEach(handler => handler.callback(bar));
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function getNextDailyBarTime(barTime) {
|
|
88
|
-
const date = new Date(barTime * 1000);
|
|
89
|
-
date.setDate(date.getDate() + 1);
|
|
90
|
-
return date.getTime() / 1000;
|
|
91
|
-
}
|
|
68
|
+
};
|
|
92
69
|
|
|
93
|
-
function subscribeOnStream(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback,
|
|
94
|
-
const
|
|
95
|
-
const channelString = "0~".concat(parsedSymbol.exchange, "~").concat(parsedSymbol.fromSymbol, "~").concat(parsedSymbol.toSymbol);
|
|
70
|
+
function subscribeOnStream(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback, interval) {
|
|
71
|
+
const channelString = "".concat(symbolInfo.name.toLowerCase(), "@kline_").concat(interval);
|
|
96
72
|
const handler = {
|
|
97
73
|
id: subscribeUID,
|
|
98
74
|
callback: onRealtimeCallback
|
|
@@ -108,14 +84,16 @@ function subscribeOnStream(symbolInfo, resolution, onRealtimeCallback, subscribe
|
|
|
108
84
|
subscriptionItem = {
|
|
109
85
|
subscribeUID,
|
|
110
86
|
resolution,
|
|
111
|
-
lastDailyBar,
|
|
112
87
|
handlers: [handler]
|
|
113
88
|
};
|
|
89
|
+
const subRequest = {
|
|
90
|
+
method: "SUBSCRIBE",
|
|
91
|
+
params: [channelString],
|
|
92
|
+
id: 1
|
|
93
|
+
};
|
|
114
94
|
channelToSubscription.set(channelString, subscriptionItem);
|
|
115
|
-
console.log(
|
|
116
|
-
socket.
|
|
117
|
-
subs: [channelString]
|
|
118
|
-
});
|
|
95
|
+
console.log("[subscribeBars]: Subscribe to streaming. Channel:", channelString);
|
|
96
|
+
socket.send(JSON.stringify(subRequest));
|
|
119
97
|
}
|
|
120
98
|
|
|
121
99
|
function unsubscribeFromStream(subscriberUID) {
|
|
@@ -130,10 +108,13 @@ function unsubscribeFromStream(subscriberUID) {
|
|
|
130
108
|
|
|
131
109
|
if (subscriptionItem.handlers.length === 0) {
|
|
132
110
|
// unsubscribe from the channel, if it was the last handler
|
|
133
|
-
console.log(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
111
|
+
console.log("[unsubscribeBars]: Unsubscribe from streaming. Channel:", channelString);
|
|
112
|
+
const subRequest = {
|
|
113
|
+
method: "UNSUBSCRIBE",
|
|
114
|
+
params: [channelString],
|
|
115
|
+
id: 1
|
|
116
|
+
};
|
|
117
|
+
socket.send(JSON.stringify(subRequest));
|
|
137
118
|
channelToSubscription.delete(channelString);
|
|
138
119
|
break;
|
|
139
120
|
}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
2
|
+
"version": "0.2.0",
|
|
3
3
|
"name": "binbot-charts",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"@babel/cli": "^7.18.10",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
17
|
"start": "react-scripts start",
|
|
18
|
-
"build": "rm -rf dist && NODE_ENV=production babel -d dist/components src/components --extensions \".ts,.js\" && cp -r src/charting_library dist/charting_library",
|
|
18
|
+
"build": "rm -rf dist && NODE_ENV=production babel -d dist/components src/components --extensions \".ts,.js,.jsx\" && cp -r src/charting_library dist/charting_library",
|
|
19
19
|
"release": "yarn build && yarn publish"
|
|
20
20
|
},
|
|
21
21
|
"description": "Binbot charts is the default candlestick bars chart used in terminal.binbot.com to render bots graphically.",
|