binbot-charts 0.1.8 → 0.2.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.
@@ -9,14 +9,12 @@ exports.default = TVChartContainer;
9
9
 
10
10
  var _react = _interopRequireWildcard(require("react"));
11
11
 
12
- var _charting_library = require("../charting_library/charting_library");
12
+ var _charting_library = require("../charting_library");
13
13
 
14
14
  var _datafeed = _interopRequireDefault(require("./datafeed"));
15
15
 
16
16
  var _propTypes = _interopRequireDefault(require("prop-types"));
17
17
 
18
- var _chartingLibraryInterfaces = require("./charting-library-interfaces");
19
-
20
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
19
 
22
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); }
@@ -25,9 +23,8 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
25
23
 
26
24
  function TVChartContainer(_ref) {
27
25
  let {
28
- apiKey,
29
- symbol = "Binance:APE/USDT",
30
- interval = "1D",
26
+ symbol = "APEUSDT",
27
+ interval = "1h",
31
28
  libraryPath = "/charting_library/",
32
29
  timescaleMarks = [],
33
30
  orderLines = [],
@@ -37,21 +34,28 @@ function TVChartContainer(_ref) {
37
34
  (0, _react.useEffect)(() => {
38
35
  const widgetOptions = {
39
36
  symbol: symbol,
40
- datafeed: new _datafeed.default(apiKey, timescaleMarks),
37
+ datafeed: new _datafeed.default(timescaleMarks),
41
38
  interval: interval,
42
39
  container: containerRef.current,
43
40
  library_path: libraryPath,
44
41
  locale: "en",
45
42
  fullscreen: false,
46
43
  autosize: true,
47
- studies_overrides: {}
44
+ studies_overrides: {},
45
+ symbol_search_request_delay: 1000,
46
+ overrides: {
47
+ volumePaneSize: "small",
48
+ "mainSeriesProperties.barStyle.dontDrawOpen": false
49
+ }
48
50
  };
49
51
  const tvWidget = new _charting_library.widget(widgetOptions);
50
52
  tvWidget.onChartReady(() => {
51
- orderLines.forEach(order => {
52
- 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);
53
- });
54
- }); // returned function will be called on component unmount
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
55
59
 
56
60
  return () => {
57
61
  if (this.tvWidget !== null) {
@@ -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/es.symbol.description.js");
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
- selected_resolution: "m",
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(apiKey) {
47
- let timescaleMarks = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
48
- let lineOrders = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
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(this.apiKey);
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 symbols = await (0, _helpers.getAllSymbols)(exchange);
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
- const symbols = await (0, _helpers.getAllSymbols)(exchange);
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: symbolItem.full_name,
82
- name: symbolItem.symbol,
83
- description: symbolItem.description,
84
- type: symbolItem.type,
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: symbolItem.exchange,
88
- minmov: 1,
89
- pricescale: 100,
66
+ exchange: "Binance",
67
+ minmov: 100,
68
+ pricescale: 100000,
90
69
  has_intraday: true,
91
70
  has_no_volume: false,
92
- has_weekly_and_monthly: false,
93
- volume_precision: 4,
94
- data_status: "streaming"
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
  });
@@ -102,21 +83,19 @@ class Datafeed {
102
83
  to,
103
84
  firstDataRequest
104
85
  } = periodParams;
105
- console.log("[getBars]: Method call");
106
- const parsedSymbol = (0, _helpers.parseFullSymbol)(symbolInfo.full_name);
107
- const urlParameters = {
108
- e: parsedSymbol.exchange,
109
- fsym: parsedSymbol.fromSymbol,
110
- tsym: parsedSymbol.toSymbol,
111
- toTs: to,
112
- limit: 2000
86
+ let urlParameters = {
87
+ symbol: symbolInfo.name,
88
+ interval: this.interval,
89
+ startTime: from * 1000,
90
+ endTime: to * 1000,
91
+ limit: 600
113
92
  };
114
93
  const query = Object.keys(urlParameters).map(name => "".concat(name, "=").concat(encodeURIComponent(urlParameters[name]))).join("&");
115
94
 
116
95
  try {
117
- const data = await (0, _helpers.makeApiRequest)("data/histoday?".concat(query));
96
+ const data = await (0, _helpers.makeApiRequest)("api/v3/uiKlines?".concat(query));
118
97
 
119
- if (data.Response && data.Response === "Error" || data.Data.length === 0) {
98
+ if (data.Response && data.Response === "Error" || data.length === 0) {
120
99
  // "noData" should be set if there is no data in the requested period.
121
100
  onHistoryCallback([], {
122
101
  noData: true
@@ -125,23 +104,18 @@ class Datafeed {
125
104
  }
126
105
 
127
106
  let bars = [];
128
- data.Data.forEach(bar => {
129
- if (bar.time >= from && bar.time < to) {
107
+ data.forEach(bar => {
108
+ if (bar[0] >= from * 1000 && bar[0] < to * 1000) {
130
109
  bars = [...bars, {
131
- time: bar.time * 1000,
132
- low: bar.low,
133
- high: bar.high,
134
- open: bar.open,
135
- close: bar.close
110
+ time: bar[0],
111
+ low: bar[3],
112
+ high: bar[2],
113
+ open: bar[1],
114
+ close: bar[4],
115
+ volume: bar[5]
136
116
  }];
137
117
  }
138
118
  });
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
119
  onHistoryCallback(bars, {
146
120
  noData: false
147
121
  });
@@ -152,18 +126,17 @@ class Datafeed {
152
126
  });
153
127
 
154
128
  _defineProperty(this, "subscribeBars", (symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => {
155
- console.log('[subscribeBars]: Method call with subscribeUID:', subscribeUID);
156
- (0, _streaming.subscribeOnStream)(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback, lastBarsCache.get(symbolInfo.full_name));
129
+ (0, _streaming.subscribeOnStream)(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback, this.interval);
157
130
  });
158
131
 
159
132
  _defineProperty(this, "unsubscribeBars", subscriberUID => {
160
- console.log('[unsubscribeBars]: Method call with subscriberUID:', subscriberUID);
161
133
  (0, _streaming.unsubscribeFromStream)(subscriberUID);
162
134
  });
163
135
 
164
136
  this.timescaleMarks = timescaleMarks;
165
137
  this.lineOrders = lineOrders;
166
- this.apiKey = apiKey;
138
+ this.streaming = null;
139
+ this.interval = interval;
167
140
  }
168
141
 
169
142
  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://min-api.cryptocompare.com/".concat(path));
21
+ const response = await fetch("https://api.binance.com/".concat(path));
23
22
  return response.json();
24
23
  } catch (error) {
25
- throw new Error("CryptoCompare request error: ".concat(error.status));
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(exchange) {
53
- const data = await makeApiRequest("data/v3/all/exchanges");
54
- let allSymbols = [];
55
- const pairs = data.Data[exchange].pairs;
51
+ async function getAllSymbols(symbol) {
52
+ let newSymbols = [];
56
53
 
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
- };
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
- allSymbols = [...allSymbols, ...symbols];
68
+ } catch (e) {
69
+ return newSymbols;
69
70
  }
70
71
 
71
- return allSymbols;
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
  }
@@ -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.regexp.exec.js");
11
+ require("core-js/modules/es.json.stringify.js");
12
12
 
13
- require("core-js/modules/es.string.split.js");
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
- 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; }
16
+ socket.onopen = event => {
17
+ console.log("[socket] Connected", event);
18
+ };
26
19
 
27
- 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; }
20
+ socket.onclose = reason => {
21
+ console.log("[socket] Disconnected:", reason);
22
+ };
28
23
 
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; }
24
+ socket.onerror = error => {
25
+ console.log("[socket] Error:", error);
26
+ };
30
27
 
31
- const socket = (0, _socket.default)('wss://streamer.cryptocompare.com');
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('~');
28
+ socket.onmessage = e => {
29
+ const data = JSON.parse(e.data);
45
30
 
46
- if (parseInt(eventTypeStr) !== 0) {
31
+ if (data.e == undefined) {
47
32
  // skip all non-TRADE events
48
33
  return;
49
34
  }
50
35
 
51
- const tradePrice = parseFloat(tradePriceStr);
52
- const tradeTime = parseInt(tradeTimeStr);
53
- const channelString = "0~".concat(exchange, "~").concat(fromSymbol, "~").concat(toSymbol);
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 lastDailyBar = subscriptionItem.lastDailyBar;
61
- const nextDailyBarTime = getNextDailyBarTime(lastDailyBar.time);
62
- let bar;
63
-
64
- if (tradeTime >= nextDailyBarTime) {
65
- bar = {
66
- time: nextDailyBarTime,
67
- open: tradePrice,
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, lastDailyBar) {
94
- const parsedSymbol = (0, _helpers.parseFullSymbol)(symbolInfo.full_name);
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
- console.log('[subscribeBars]: Subscribe to streaming. Channel:', channelString);
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('[unsubscribeBars]: Unsubscribe from streaming. Channel:', channelString);
134
- socket.emit('SubRemove', {
135
- subs: [channelString]
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.8",
2
+ "version": "0.2.2",
3
3
  "name": "binbot-charts",
4
4
  "dependencies": {
5
5
  "@babel/cli": "^7.18.10",