binbot-charts 0.1.8 → 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.
@@ -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,27 @@ 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
+ overrides: {
46
+ volumePaneSize: "small",
47
+ "mainSeriesProperties.barStyle.dontDrawOpen": false
48
+ }
48
49
  };
49
50
  const tvWidget = new _charting_library.widget(widgetOptions);
50
51
  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
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
55
58
 
56
59
  return () => {
57
60
  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,57 @@ 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
- });
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 (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) {
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: symbolItem.full_name,
82
- name: symbolItem.symbol,
83
- description: symbolItem.description,
84
- type: symbolItem.type,
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: symbolItem.exchange,
88
- minmov: 1,
89
- pricescale: 100,
78
+ exchange: "Binance",
79
+ minmov: 100,
80
+ pricescale: 100000,
90
81
  has_intraday: true,
91
82
  has_no_volume: false,
92
- has_weekly_and_monthly: false,
93
- volume_precision: 4,
94
- data_status: "streaming"
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
- 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
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)("data/histoday?".concat(query));
109
+ const data = await (0, _helpers.makeApiRequest)("api/v3/uiKlines?".concat(query));
118
110
 
119
- if (data.Response && data.Response === "Error" || data.Data.length === 0) {
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.Data.forEach(bar => {
129
- if (bar.time >= from && bar.time < to) {
120
+ data.forEach(bar => {
121
+ if (bar[0] >= from * 1000 && bar[0] < to * 1000) {
130
122
  bars = [...bars, {
131
- time: bar.time * 1000,
132
- low: bar.low,
133
- high: bar.high,
134
- open: bar.open,
135
- close: bar.close
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, lastBarsCache.get(symbolInfo.full_name));
144
+ (0, _streaming.subscribeOnStream)(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback, this.interval);
157
145
  });
158
146
 
159
147
  _defineProperty(this, "unsubscribeBars", subscriberUID => {
160
- console.log('[unsubscribeBars]: Method call with subscriberUID:', subscriberUID);
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.apiKey = apiKey;
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://min-api.cryptocompare.com/".concat(path));
23
+ const response = await fetch("https://api.binance.com/".concat(path));
23
24
  return response.json();
24
25
  } catch (error) {
25
- throw new Error("CryptoCompare request error: ".concat(error.status));
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
  }
@@ -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.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"));
13
+ const channelToSubscription = new Map();
14
+ const socket = new WebSocket("wss://stream.binance.com:9443/ws");
22
15
 
23
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
+ socket.onopen = event => {
17
+ console.log("[socket] Connected", event);
18
+ };
24
19
 
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; }
20
+ socket.onclose = reason => {
21
+ console.log("[socket] Disconnected:", reason);
22
+ };
26
23
 
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; }
24
+ socket.onerror = error => {
25
+ console.log("[socket] Error:", error);
26
+ };
28
27
 
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; }
28
+ socket.onmessage = e => {
29
+ console.log("[socket] Message:", JSON.parse(e.data));
30
+ const data = JSON.parse(e.data);
30
31
 
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('~');
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 tradePrice = parseFloat(tradePriceStr);
52
- const tradeTime = parseInt(tradeTimeStr);
53
- const channelString = "0~".concat(exchange, "~").concat(fromSymbol, "~").concat(toSymbol);
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 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
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, lastDailyBar) {
94
- const parsedSymbol = (0, _helpers.parseFullSymbol)(symbolInfo.full_name);
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('[subscribeBars]: Subscribe to streaming. Channel:', channelString);
116
- socket.emit('SubAdd', {
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('[unsubscribeBars]: Unsubscribe from streaming. Channel:', channelString);
134
- socket.emit('SubRemove', {
135
- subs: [channelString]
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.1.8",
2
+ "version": "0.2.0",
3
3
  "name": "binbot-charts",
4
4
  "dependencies": {
5
5
  "@babel/cli": "^7.18.10",