binbot-charts 0.1.7 → 0.2.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.
|
@@ -0,0 +1,83 @@
|
|
|
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
|
+
symbol_search_request_delay: 1000,
|
|
46
|
+
overrides: {
|
|
47
|
+
volumePaneSize: "small",
|
|
48
|
+
"mainSeriesProperties.barStyle.dontDrawOpen": false
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const tvWidget = new _charting_library.widget(widgetOptions);
|
|
52
|
+
tvWidget.onChartReady(() => {
|
|
53
|
+
if (orderLines.length > 0) {
|
|
54
|
+
orderLines.forEach(order => {
|
|
55
|
+
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);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}); // returned function will be called on component unmount
|
|
59
|
+
|
|
60
|
+
return () => {
|
|
61
|
+
if (this.tvWidget !== null) {
|
|
62
|
+
this.tvWidget.remove();
|
|
63
|
+
this.tvWidget = null;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}, []);
|
|
67
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
68
|
+
ref: containerRef,
|
|
69
|
+
style: {
|
|
70
|
+
height: height
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
TVChartContainer.propTypes = {
|
|
76
|
+
apiKey: _propTypes.default.string,
|
|
77
|
+
symbol: _propTypes.default.string,
|
|
78
|
+
interval: _propTypes.default.string,
|
|
79
|
+
libraryPath: _propTypes.default.string,
|
|
80
|
+
timescaleMarks: _propTypes.default.array,
|
|
81
|
+
orderLines: _propTypes.default.array,
|
|
82
|
+
height: _propTypes.default.string
|
|
83
|
+
};
|
|
@@ -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,45 @@ 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
|
-
|
|
57
|
-
|
|
58
|
-
const newSymbols = symbols.filter(symbol => {
|
|
59
|
-
const isExchangeValid = exchange === "" || symbol.exchange === exchange;
|
|
60
|
-
const isFullSymbolContainsInput = symbol.full_name.toLowerCase().indexOf(userInput.toLowerCase()) !== -1;
|
|
61
|
-
return isExchangeValid && isFullSymbolContainsInput;
|
|
62
|
-
});
|
|
63
|
-
onResultReadyCallback(newSymbols);
|
|
48
|
+
const symbols = await (0, _helpers.getAllSymbols)(userInput);
|
|
49
|
+
onResultReadyCallback(symbols);
|
|
64
50
|
});
|
|
65
51
|
|
|
66
52
|
_defineProperty(this, "resolveSymbol", async (symbolName, onSymbolResolvedCallback, onResolveErrorCallback) => {
|
|
67
|
-
|
|
68
|
-
const symbolItem = symbols.find(_ref => {
|
|
69
|
-
let {
|
|
70
|
-
full_name
|
|
71
|
-
} = _ref;
|
|
72
|
-
return full_name === symbolName;
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
if (!symbolItem) {
|
|
53
|
+
if (!symbolName) {
|
|
76
54
|
onResolveErrorCallback("cannot resolve symbol");
|
|
77
55
|
return;
|
|
78
56
|
}
|
|
79
57
|
|
|
80
58
|
const symbolInfo = {
|
|
81
|
-
ticker:
|
|
82
|
-
name:
|
|
83
|
-
|
|
84
|
-
|
|
59
|
+
ticker: symbolName,
|
|
60
|
+
name: symbolName,
|
|
61
|
+
ticker: symbolName,
|
|
62
|
+
description: symbolName,
|
|
63
|
+
type: "crypto",
|
|
85
64
|
session: "24x7",
|
|
86
65
|
timezone: "Etc/UTC",
|
|
87
|
-
exchange:
|
|
88
|
-
minmov:
|
|
89
|
-
pricescale:
|
|
66
|
+
exchange: "Binance",
|
|
67
|
+
minmov: 100,
|
|
68
|
+
pricescale: 100000,
|
|
90
69
|
has_intraday: true,
|
|
91
70
|
has_no_volume: false,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
71
|
+
volume: "hundreds",
|
|
72
|
+
has_weekly_and_monthly: true,
|
|
73
|
+
volume_precision: 9,
|
|
74
|
+
data_status: "streaming",
|
|
75
|
+
resolution: "1h"
|
|
95
76
|
};
|
|
96
77
|
onSymbolResolvedCallback(symbolInfo);
|
|
97
78
|
});
|
|
@@ -103,20 +84,19 @@ class Datafeed {
|
|
|
103
84
|
firstDataRequest
|
|
104
85
|
} = periodParams;
|
|
105
86
|
console.log("[getBars]: Method call");
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
limit: 2000
|
|
87
|
+
let urlParameters = {
|
|
88
|
+
symbol: symbolInfo.name,
|
|
89
|
+
interval: this.interval,
|
|
90
|
+
startTime: from * 1000,
|
|
91
|
+
endTime: to * 1000,
|
|
92
|
+
limit: 600
|
|
113
93
|
};
|
|
114
94
|
const query = Object.keys(urlParameters).map(name => "".concat(name, "=").concat(encodeURIComponent(urlParameters[name]))).join("&");
|
|
115
95
|
|
|
116
96
|
try {
|
|
117
|
-
const data = await (0, _helpers.makeApiRequest)("
|
|
97
|
+
const data = await (0, _helpers.makeApiRequest)("api/v3/uiKlines?".concat(query));
|
|
118
98
|
|
|
119
|
-
if (data.Response && data.Response === "Error" || data.
|
|
99
|
+
if (data.Response && data.Response === "Error" || data.length === 0) {
|
|
120
100
|
// "noData" should be set if there is no data in the requested period.
|
|
121
101
|
onHistoryCallback([], {
|
|
122
102
|
noData: true
|
|
@@ -125,23 +105,18 @@ class Datafeed {
|
|
|
125
105
|
}
|
|
126
106
|
|
|
127
107
|
let bars = [];
|
|
128
|
-
data.
|
|
129
|
-
if (bar
|
|
108
|
+
data.forEach(bar => {
|
|
109
|
+
if (bar[0] >= from * 1000 && bar[0] < to * 1000) {
|
|
130
110
|
bars = [...bars, {
|
|
131
|
-
time: bar
|
|
132
|
-
low: bar
|
|
133
|
-
high: bar
|
|
134
|
-
open: bar
|
|
135
|
-
close: bar
|
|
111
|
+
time: bar[0],
|
|
112
|
+
low: bar[3],
|
|
113
|
+
high: bar[2],
|
|
114
|
+
open: bar[1],
|
|
115
|
+
close: bar[4],
|
|
116
|
+
volume: bar[5]
|
|
136
117
|
}];
|
|
137
118
|
}
|
|
138
119
|
});
|
|
139
|
-
|
|
140
|
-
if (firstDataRequest) {
|
|
141
|
-
lastBarsCache.set(symbolInfo.full_name, _objectSpread({}, bars[bars.length - 1]));
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
console.log("[getBars]: returned ".concat(bars.length, " bar(s)"));
|
|
145
120
|
onHistoryCallback(bars, {
|
|
146
121
|
noData: false
|
|
147
122
|
});
|
|
@@ -152,18 +127,17 @@ class Datafeed {
|
|
|
152
127
|
});
|
|
153
128
|
|
|
154
129
|
_defineProperty(this, "subscribeBars", (symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => {
|
|
155
|
-
|
|
156
|
-
(0, _streaming.subscribeOnStream)(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback, lastBarsCache.get(symbolInfo.full_name));
|
|
130
|
+
(0, _streaming.subscribeOnStream)(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback, this.interval);
|
|
157
131
|
});
|
|
158
132
|
|
|
159
133
|
_defineProperty(this, "unsubscribeBars", subscriberUID => {
|
|
160
|
-
console.log('[unsubscribeBars]: Method call with subscriberUID:', subscriberUID);
|
|
161
134
|
(0, _streaming.unsubscribeFromStream)(subscriberUID);
|
|
162
135
|
});
|
|
163
136
|
|
|
164
137
|
this.timescaleMarks = timescaleMarks;
|
|
165
138
|
this.lineOrders = lineOrders;
|
|
166
|
-
this.
|
|
139
|
+
this.streaming = null;
|
|
140
|
+
this.interval = interval;
|
|
167
141
|
}
|
|
168
142
|
|
|
169
143
|
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;
|
|
@@ -14,15 +15,13 @@ require("core-js/modules/es.regexp.exec.js");
|
|
|
14
15
|
|
|
15
16
|
require("core-js/modules/es.string.match.js");
|
|
16
17
|
|
|
17
|
-
require("core-js/modules/web.dom-collections.iterator.js");
|
|
18
|
-
|
|
19
18
|
// Make requests to CryptoCompare API
|
|
20
19
|
async function makeApiRequest(path) {
|
|
21
20
|
try {
|
|
22
|
-
const response = await fetch("https://
|
|
21
|
+
const response = await fetch("https://api.binance.com/".concat(path));
|
|
23
22
|
return response.json();
|
|
24
23
|
} catch (error) {
|
|
25
|
-
throw new Error("
|
|
24
|
+
throw new Error("Binance request error: ".concat(error.status));
|
|
26
25
|
}
|
|
27
26
|
} // Generate a symbol ID from a pair of the coins
|
|
28
27
|
|
|
@@ -49,24 +48,32 @@ function parseFullSymbol(fullSymbol) {
|
|
|
49
48
|
};
|
|
50
49
|
}
|
|
51
50
|
|
|
52
|
-
async function getAllSymbols(
|
|
53
|
-
|
|
54
|
-
let allSymbols = [];
|
|
55
|
-
const pairs = data.Data[exchange].pairs;
|
|
51
|
+
async function getAllSymbols(symbol) {
|
|
52
|
+
let newSymbols = [];
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
54
|
+
try {
|
|
55
|
+
const data = await makeApiRequest("api/v3/exchangeInfo?symbol=".concat(symbol.toUpperCase()));
|
|
56
|
+
data.symbols.forEach(item => {
|
|
57
|
+
if (item.status === "TRADING") {
|
|
58
|
+
newSymbols.push({
|
|
59
|
+
symbol: item.symbol,
|
|
60
|
+
full_name: "".concat(item.baseAsset, "/").concat(item.quoteAsset),
|
|
61
|
+
description: "Precision: ".concat(item.quoteAssetPrecision),
|
|
62
|
+
exchange: "Binance",
|
|
63
|
+
ticker: item.symbol,
|
|
64
|
+
type: "crypto"
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
67
|
});
|
|
68
|
-
|
|
68
|
+
} catch (e) {
|
|
69
|
+
return newSymbols;
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
return
|
|
72
|
+
return newSymbols;
|
|
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,65 @@ 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"));
|
|
22
|
-
|
|
23
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
+
const channelToSubscription = new Map();
|
|
14
|
+
const socket = new WebSocket("wss://stream.binance.com:9443/ws");
|
|
24
15
|
|
|
25
|
-
|
|
16
|
+
socket.onopen = event => {
|
|
17
|
+
console.log("[socket] Connected", event);
|
|
18
|
+
};
|
|
26
19
|
|
|
27
|
-
|
|
20
|
+
socket.onclose = reason => {
|
|
21
|
+
console.log("[socket] Disconnected:", reason);
|
|
22
|
+
};
|
|
28
23
|
|
|
29
|
-
|
|
24
|
+
socket.onerror = error => {
|
|
25
|
+
console.log("[socket] Error:", error);
|
|
26
|
+
};
|
|
30
27
|
|
|
31
|
-
|
|
32
|
-
const
|
|
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('~');
|
|
28
|
+
socket.onmessage = e => {
|
|
29
|
+
const data = JSON.parse(e.data);
|
|
45
30
|
|
|
46
|
-
if (
|
|
31
|
+
if (data.e == undefined) {
|
|
47
32
|
// skip all non-TRADE events
|
|
48
33
|
return;
|
|
49
34
|
}
|
|
50
35
|
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
36
|
+
const {
|
|
37
|
+
s: symbol,
|
|
38
|
+
t: startTime,
|
|
39
|
+
T: closeTime,
|
|
40
|
+
i: interval,
|
|
41
|
+
o: open,
|
|
42
|
+
c: close,
|
|
43
|
+
h: high,
|
|
44
|
+
l: low,
|
|
45
|
+
v: volume,
|
|
46
|
+
n: trades,
|
|
47
|
+
q: quoteVolume
|
|
48
|
+
} = data.k;
|
|
49
|
+
const channelString = "".concat(symbol.toLowerCase(), "@kline_").concat(interval);
|
|
54
50
|
const subscriptionItem = channelToSubscription.get(channelString);
|
|
55
51
|
|
|
56
52
|
if (subscriptionItem === undefined) {
|
|
57
53
|
return;
|
|
58
54
|
}
|
|
59
55
|
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
high: tradePrice,
|
|
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
|
|
56
|
+
const bar = {
|
|
57
|
+
time: startTime,
|
|
58
|
+
open: open,
|
|
59
|
+
high: high,
|
|
60
|
+
low: low,
|
|
61
|
+
close: close,
|
|
62
|
+
volume: volume
|
|
63
|
+
}; // send data to every subscriber of that symbol
|
|
83
64
|
|
|
84
65
|
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
|
-
}
|
|
66
|
+
};
|
|
92
67
|
|
|
93
|
-
function subscribeOnStream(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback,
|
|
94
|
-
const
|
|
95
|
-
const channelString = "0~".concat(parsedSymbol.exchange, "~").concat(parsedSymbol.fromSymbol, "~").concat(parsedSymbol.toSymbol);
|
|
68
|
+
function subscribeOnStream(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback, interval) {
|
|
69
|
+
const channelString = "".concat(symbolInfo.name.toLowerCase(), "@kline_").concat(interval);
|
|
96
70
|
const handler = {
|
|
97
71
|
id: subscribeUID,
|
|
98
72
|
callback: onRealtimeCallback
|
|
@@ -108,14 +82,15 @@ function subscribeOnStream(symbolInfo, resolution, onRealtimeCallback, subscribe
|
|
|
108
82
|
subscriptionItem = {
|
|
109
83
|
subscribeUID,
|
|
110
84
|
resolution,
|
|
111
|
-
lastDailyBar,
|
|
112
85
|
handlers: [handler]
|
|
113
86
|
};
|
|
87
|
+
const subRequest = {
|
|
88
|
+
method: "SUBSCRIBE",
|
|
89
|
+
params: [channelString],
|
|
90
|
+
id: 1
|
|
91
|
+
};
|
|
114
92
|
channelToSubscription.set(channelString, subscriptionItem);
|
|
115
|
-
|
|
116
|
-
socket.emit('SubAdd', {
|
|
117
|
-
subs: [channelString]
|
|
118
|
-
});
|
|
93
|
+
socket.send(JSON.stringify(subRequest));
|
|
119
94
|
}
|
|
120
95
|
|
|
121
96
|
function unsubscribeFromStream(subscriberUID) {
|
|
@@ -130,10 +105,13 @@ function unsubscribeFromStream(subscriberUID) {
|
|
|
130
105
|
|
|
131
106
|
if (subscriptionItem.handlers.length === 0) {
|
|
132
107
|
// unsubscribe from the channel, if it was the last handler
|
|
133
|
-
console.log(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
108
|
+
console.log("[unsubscribeBars]: Unsubscribe from streaming. Channel:", channelString);
|
|
109
|
+
const subRequest = {
|
|
110
|
+
method: "UNSUBSCRIBE",
|
|
111
|
+
params: [channelString],
|
|
112
|
+
id: 1
|
|
113
|
+
};
|
|
114
|
+
socket.send(JSON.stringify(subRequest));
|
|
137
115
|
channelToSubscription.delete(channelString);
|
|
138
116
|
break;
|
|
139
117
|
}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.1
|
|
2
|
+
"version": "0.2.1",
|
|
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.",
|