binbot-charts 0.3.0 → 0.3.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.
@@ -4,26 +4,17 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = TVChartContainer;
7
-
8
7
  var _react = _interopRequireWildcard(require("react"));
9
-
10
8
  var _charting_library = require("../charting_library");
11
-
12
9
  var _datafeed = _interopRequireDefault(require("./datafeed"));
13
-
14
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
15
-
16
11
  var _useImmer = require("use-immer");
17
-
18
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
-
20
13
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
21
-
22
14
  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
15
  function TVChartContainer(_ref) {
25
16
  let {
26
- symbol = "APEUSDT",
17
+ symbol = "BTCUSDT",
27
18
  interval = "1h",
28
19
  libraryPath = "/charting_library/",
29
20
  timescaleMarks = [],
@@ -39,27 +30,23 @@ function TVChartContainer(_ref) {
39
30
  const prevTimescaleMarks = (0, _react.useRef)(timescaleMarks);
40
31
  (0, _react.useEffect)(() => {
41
32
  if (!widgetState) {
42
- initializeChart();
33
+ initializeChart("1h");
43
34
  }
44
-
45
35
  if (orderLines && orderLines.length > 0) {
46
36
  updateOrderLines(orderLines);
47
37
  }
48
-
49
38
  if (widgetState && symbol !== symbolState) {
50
39
  widgetState.setSymbol(symbol, interval);
51
40
  }
52
-
53
41
  if (widgetState && prevTimescaleMarks.current && timescaleMarks !== prevTimescaleMarks.current) {
54
42
  widgetState._options.datafeed.timescaleMarks = timescaleMarks;
55
43
  prevTimescaleMarks.current = timescaleMarks;
56
44
  }
57
45
  }, [orderLines, timescaleMarks]);
58
-
59
- const initializeChart = () => {
46
+ const initializeChart = interval => {
60
47
  const widgetOptions = {
61
48
  symbol: symbol,
62
- datafeed: new _datafeed.default(timescaleMarks),
49
+ datafeed: new _datafeed.default(timescaleMarks, interval),
63
50
  interval: interval,
64
51
  container: containerRef.current,
65
52
  library_path: libraryPath,
@@ -76,8 +63,9 @@ function TVChartContainer(_ref) {
76
63
  const tvWidget = new _charting_library.widget(widgetOptions);
77
64
  tvWidget.onChartReady(() => {
78
65
  tvWidget.subscribe("onTick", event => onTick(event));
79
- setWidgetState(tvWidget); // get latest bar for last price
66
+ setWidgetState(tvWidget);
80
67
 
68
+ // get latest bar for last price
81
69
  const prices = async () => {
82
70
  const data = await tvWidget.activeChart().exportData({
83
71
  includeTime: false,
@@ -86,11 +74,9 @@ function TVChartContainer(_ref) {
86
74
  });
87
75
  getLatestBar(data.data[data.data.length - 1]);
88
76
  };
89
-
90
77
  prices();
91
78
  });
92
79
  };
93
-
94
80
  const updateOrderLines = orderLines => {
95
81
  if (chartOrderLines && chartOrderLines.length > 0) {
96
82
  chartOrderLines.forEach(item => {
@@ -104,8 +90,9 @@ function TVChartContainer(_ref) {
104
90
  if (widgetState && orderLines && orderLines.length > 0) {
105
91
  orderLines.forEach(order => {
106
92
  const lineStyle = order.lineStyle || 0;
107
- let chartOrderLine = widgetState.chart().createOrderLine().setText(order.text).setTooltip(order.tooltip).setQuantity(order.quantity).setQuantityFont("inherit 14px Arial").setQuantityBackgroundColor(order.color).setQuantityBorderColor(order.color).setLineStyle(lineStyle).setLineLength(25).setLineColor(order.color).setBodyFont("inherit 14px Arial").setBodyBorderColor(order.color).setBodyTextColor(order.color).setPrice(order.price); // set custom id easier search
93
+ let chartOrderLine = widgetState.chart().createOrderLine().setText(order.text).setTooltip(order.tooltip).setQuantity(order.quantity).setQuantityFont("inherit 14px Arial").setQuantityBackgroundColor(order.color).setQuantityBorderColor(order.color).setLineStyle(lineStyle).setLineLength(25).setLineColor(order.color).setBodyFont("inherit 14px Arial").setBodyBorderColor(order.color).setBodyTextColor(order.color).setPrice(order.price);
108
94
 
95
+ // set custom id easier search
109
96
  chartOrderLine.id = order.id;
110
97
  setChartOrderLines(draft => {
111
98
  draft.push(chartOrderLine);
@@ -115,7 +102,6 @@ function TVChartContainer(_ref) {
115
102
  }
116
103
  }
117
104
  };
118
-
119
105
  return /*#__PURE__*/_react.default.createElement("div", {
120
106
  ref: containerRef,
121
107
  style: {
@@ -123,7 +109,6 @@ function TVChartContainer(_ref) {
123
109
  }
124
110
  });
125
111
  }
126
-
127
112
  TVChartContainer.propTypes = {
128
113
  apiKey: _propTypes.default.string,
129
114
  symbol: _propTypes.default.string,
@@ -4,15 +4,12 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _helpers = require("./helpers.js");
9
-
10
8
  var _streaming = require("./streaming.js");
11
-
12
- 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; }
13
-
9
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
10
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
11
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
14
12
  const binanceResolutions = ["1s", "1m", "3m", "5m", "15m", "30m", "1h", "2h", "4h", "6h", "8h", "12h", "1d", "3d", "1w", "1M"];
15
-
16
13
  const getConfigurationData = async () => {
17
14
  return {
18
15
  supports_marks: true,
@@ -32,26 +29,27 @@ const getConfigurationData = async () => {
32
29
  };
33
30
  };
34
31
 
32
+ /**
33
+ * @param timescale { Array }. timescaleMark objects
34
+ * @param interval { string }. Klines timescale from the list of Binance Enums
35
+ */
35
36
  class Datafeed {
36
37
  constructor() {
37
38
  let timescaleMarks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
38
-
39
+ let _interval = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "1h";
39
40
  _defineProperty(this, "onReady", async callback => {
40
41
  this.configurationData = await getConfigurationData();
41
42
  callback(this.configurationData);
42
43
  });
43
-
44
44
  _defineProperty(this, "searchSymbols", async (userInput, exchange, symbolType, onResultReadyCallback) => {
45
45
  const symbols = await (0, _helpers.getAllSymbols)(userInput);
46
46
  onResultReadyCallback(symbols);
47
47
  });
48
-
49
48
  _defineProperty(this, "resolveSymbol", async (symbolName, onSymbolResolvedCallback, onResolveErrorCallback) => {
50
49
  if (!symbolName) {
51
50
  await onResolveErrorCallback("cannot resolve symbol");
52
51
  return;
53
52
  }
54
-
55
53
  const symbolInfo = () => {
56
54
  return {
57
55
  ticker: symbolName,
@@ -75,11 +73,9 @@ class Datafeed {
75
73
  resolution: "1h"
76
74
  };
77
75
  };
78
-
79
76
  const symbol = await symbolInfo();
80
77
  onSymbolResolvedCallback(symbol);
81
78
  });
82
-
83
79
  _defineProperty(this, "getBars", async (symbolInfo, resolution, periodParams, onHistoryCallback, onErrorCallback) => {
84
80
  const {
85
81
  from,
@@ -88,7 +84,6 @@ class Datafeed {
88
84
  } = periodParams;
89
85
  let interval = "60"; // 1 hour
90
86
  // Calculate interval using resolution data
91
-
92
87
  if (!/[a-zA-Z]$/.test(resolution)) {
93
88
  if (parseInt(resolution) >= 60) {
94
89
  interval = parseInt(resolution) / 60 + "h";
@@ -98,7 +93,6 @@ class Datafeed {
98
93
  } else {
99
94
  interval = resolution.toLowerCase().replace(/[a-z]\b/g, c => c.toLowerCase());
100
95
  }
101
-
102
96
  let urlParameters = {
103
97
  symbol: symbolInfo.name,
104
98
  interval: interval,
@@ -107,10 +101,8 @@ class Datafeed {
107
101
  limit: 600
108
102
  };
109
103
  const query = Object.keys(urlParameters).map(name => `${name}=${encodeURIComponent(urlParameters[name])}`).join("&");
110
-
111
104
  try {
112
105
  const data = await (0, _helpers.makeApiRequest)(`api/v3/uiKlines?${query}`);
113
-
114
106
  if (data.Response && data.Response === "Error" || data.length === 0) {
115
107
  // "noData" should be set if there is no data in the requested period.
116
108
  onHistoryCallback([], {
@@ -118,7 +110,6 @@ class Datafeed {
118
110
  });
119
111
  return;
120
112
  }
121
-
122
113
  let bars = [];
123
114
  data.forEach(bar => {
124
115
  if (bar[0] >= from * 1000 && bar[0] < to * 1000) {
@@ -140,32 +131,26 @@ class Datafeed {
140
131
  onErrorCallback(error);
141
132
  }
142
133
  });
143
-
144
134
  _defineProperty(this, "subscribeBars", (symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => {
145
135
  (0, _streaming.subscribeOnStream)(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback, this.interval);
146
136
  });
147
-
148
137
  _defineProperty(this, "unsubscribeBars", subscriberUID => {
149
138
  (0, _streaming.unsubscribeFromStream)(subscriberUID);
150
139
  });
151
-
152
140
  this.streaming = null;
153
141
  this.timescaleMarks = timescaleMarks;
142
+ this.interval = _interval;
154
143
  }
155
-
156
144
  getTimescaleMarks(symbolInfo, from, to, onDataCallback, resolution) {
157
145
  if (this.timescaleMarks.length > 0) {
158
146
  let timescaleMarks = Object.assign([], this.timescaleMarks);
159
147
  onDataCallback(timescaleMarks);
160
148
  }
161
149
  }
162
-
163
150
  async getServerTime(onServertimeCallback) {
164
151
  const data = await (0, _helpers.makeApiRequest)(`api/v3/time`);
165
152
  const serverTime = data.serverTime / 1000;
166
153
  onServertimeCallback(serverTime);
167
154
  }
168
-
169
155
  }
170
-
171
156
  exports.default = Datafeed;
@@ -6,9 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.getAllSymbols = getAllSymbols;
7
7
  exports.makeApiRequest = makeApiRequest;
8
8
  exports.usePrevious = usePrevious;
9
-
10
9
  var _react = require("react");
11
-
12
10
  async function makeApiRequest(path) {
13
11
  try {
14
12
  const response = await fetch(`https://api.binance.com/${path}`);
@@ -17,10 +15,8 @@ async function makeApiRequest(path) {
17
15
  throw new Error(`Binance request error: ${error.status}`);
18
16
  }
19
17
  }
20
-
21
18
  async function getAllSymbols(symbol) {
22
19
  let newSymbols = [];
23
-
24
20
  try {
25
21
  const data = await makeApiRequest(`api/v3/exchangeInfo?symbol=${symbol.toUpperCase()}`);
26
22
  data.symbols.forEach(item => {
@@ -38,10 +34,8 @@ async function getAllSymbols(symbol) {
38
34
  } catch (e) {
39
35
  return newSymbols;
40
36
  }
41
-
42
37
  return newSymbols;
43
38
  }
44
-
45
39
  function usePrevious(value) {
46
40
  const ref = (0, _react.useRef)();
47
41
  (0, _react.useEffect)(() => {
@@ -9,7 +9,5 @@ Object.defineProperty(exports, "TVChartContainer", {
9
9
  return _TVChartContainer.default;
10
10
  }
11
11
  });
12
-
13
12
  var _TVChartContainer = _interopRequireDefault(require("./TVChartContainer"));
14
-
15
13
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -6,32 +6,25 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.subscribeOnStream = subscribeOnStream;
7
7
  exports.unsubscribeFromStream = unsubscribeFromStream;
8
8
  const channelToSubscription = new Map();
9
-
10
9
  function setupSockets(subRequest) {
11
10
  const socket = new WebSocket("wss://stream.binance.com:9443/ws");
12
11
  window.socket = socket;
13
-
14
12
  socket.onopen = event => {
15
13
  console.log("[socket] Connected");
16
14
  socket.send(JSON.stringify(subRequest));
17
15
  };
18
-
19
16
  socket.onclose = reason => {
20
17
  console.log("[socket] Disconnected:", reason);
21
18
  };
22
-
23
19
  socket.onerror = error => {
24
20
  console.log("[socket] Error:", error);
25
21
  };
26
-
27
22
  socket.onmessage = e => {
28
23
  const data = JSON.parse(e.data);
29
-
30
24
  if (data.e == undefined) {
31
25
  // skip all non-TRADE events
32
26
  return;
33
27
  }
34
-
35
28
  const {
36
29
  s: symbol,
37
30
  t: startTime,
@@ -47,11 +40,9 @@ function setupSockets(subRequest) {
47
40
  } = data.k;
48
41
  const channelString = `${symbol.toLowerCase()}@kline_${interval}`;
49
42
  const subscriptionItem = channelToSubscription.get(channelString);
50
-
51
43
  if (subscriptionItem === undefined) {
52
44
  return;
53
45
  }
54
-
55
46
  const bar = {
56
47
  time: startTime,
57
48
  open: open,
@@ -59,12 +50,11 @@ function setupSockets(subRequest) {
59
50
  low: low,
60
51
  close: close,
61
52
  volume: volume
62
- }; // send data to every subscriber of that symbol
63
-
53
+ };
54
+ // send data to every subscriber of that symbol
64
55
  subscriptionItem.handlers.forEach(handler => handler.callback(bar));
65
56
  };
66
57
  }
67
-
68
58
  function subscribeOnStream(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback, interval) {
69
59
  const channelString = `${symbolInfo.name.toLowerCase()}@kline_${interval}`;
70
60
  const handler = {
@@ -72,13 +62,11 @@ function subscribeOnStream(symbolInfo, resolution, onRealtimeCallback, subscribe
72
62
  callback: onRealtimeCallback
73
63
  };
74
64
  let subscriptionItem = channelToSubscription.get(channelString);
75
-
76
65
  if (subscriptionItem) {
77
66
  // already subscribed to the channel, use the existing subscription
78
67
  subscriptionItem.handlers.push(handler);
79
68
  return;
80
69
  }
81
-
82
70
  subscriptionItem = {
83
71
  subscribeUID,
84
72
  resolution,
@@ -92,17 +80,14 @@ function subscribeOnStream(symbolInfo, resolution, onRealtimeCallback, subscribe
92
80
  channelToSubscription.set(channelString, subscriptionItem);
93
81
  setupSockets(subRequest);
94
82
  }
95
-
96
83
  function unsubscribeFromStream(subscriberUID) {
97
84
  // find a subscription with id === subscriberUID
98
85
  for (const channelString of channelToSubscription.keys()) {
99
86
  const subscriptionItem = channelToSubscription.get(channelString);
100
87
  const handlerIndex = subscriptionItem.handlers.findIndex(handler => handler.id === subscriberUID);
101
-
102
88
  if (handlerIndex !== -1) {
103
89
  // remove from handlers
104
90
  subscriptionItem.handlers.splice(handlerIndex, 1);
105
-
106
91
  if (subscriptionItem.handlers.length === 0) {
107
92
  // unsubscribe from the channel, if it was the last handler
108
93
  console.log("[unsubscribeBars]: Unsubscribe from streaming. Channel:", channelString);
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.3.0",
2
+ "version": "0.3.2",
3
3
  "name": "binbot-charts",
4
4
  "dependencies": {
5
5
  "react": "^17.0.1",
@@ -11,14 +11,18 @@
11
11
  "@babel/core": "^7.18.13",
12
12
  "@babel/polyfill": "^7.12.1",
13
13
  "@babel/preset-env": "^7.19.0",
14
- "react-scripts": "^5.0.1"
14
+ "@types/react": "^18.0.26",
15
+ "@types/react-dom": "^18.0.10",
16
+ "immer": "^9.0.17",
17
+ "react-scripts": "^5.0.1",
18
+ "typescript": "^4.9.4"
15
19
  },
16
20
  "scripts": {
17
21
  "start": "react-scripts start",
18
22
  "build": "rm -rf dist && NODE_ENV=production babel -d dist/components src/components --extensions \".js,.jsx\" && cp -r src/charting_library dist/charting_library",
19
23
  "release": "yarn build && yarn publish"
20
24
  },
21
- "description": "Binbot charts is the default candlestick bars chart used in terminal.binbot.com to render bots graphically.",
25
+ "description": "Binbot charts is the default candlestick bars chart used in terminal.binbot.in to render bots graphically.",
22
26
  "repository": {
23
27
  "type": "git",
24
28
  "url": "git+https://github.com/carkod/binbot-charts.git"