binbot-charts 0.4.2 → 0.5.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.
package/README.md CHANGED
@@ -6,7 +6,7 @@ Import it in your project as a React component
6
6
 
7
7
  ## How to start
8
8
 
9
- 1. Run `yarn install && yarn start`. It will build the project and open a default browser with the Charting Library.
9
+ 1. Run `npm install && npm start`. It will build the project and open a default browser with the Charting Library.
10
10
  2. `library_path` should be `node_modules/dist/charting_library`
11
11
  3. Write a script to copy `charting_library` to `public/charting_library` during build. E.g. `cp -r node_modules/dist/charting_library/ src/public/charting_library`
12
12
 
@@ -15,4 +15,4 @@ Import it in your project as a React component
15
15
  This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app).
16
16
 
17
17
  ## Notes
18
- The earliest supported version of the charting library for these examples is `v20`.
18
+ The earliest supported version of Node of the charting library for these examples is `v20`.
@@ -6,9 +6,6 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _helpers = require("./helpers.js");
8
8
  var _streaming = require("./streaming.js");
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); }
12
9
  const binanceResolutions = ["1s", "1m", "3m", "5m", "15m", "30m", "1h", "2h", "4h", "6h", "8h", "12h", "1d", "3d", "1w", "1M"];
13
10
  const getConfigurationData = async () => {
14
11
  return {
@@ -36,111 +33,105 @@ const getConfigurationData = async () => {
36
33
  class Datafeed {
37
34
  constructor() {
38
35
  let timescaleMarks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
39
- let _interval = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "1h";
40
- _defineProperty(this, "onReady", async callback => {
41
- this.configurationData = await getConfigurationData();
42
- callback(this.configurationData);
43
- });
44
- _defineProperty(this, "searchSymbols", async (userInput, exchange, symbolType, onResultReadyCallback) => {
45
- const symbols = await (0, _helpers.getAllSymbols)(userInput);
46
- onResultReadyCallback(symbols);
47
- });
48
- _defineProperty(this, "resolveSymbol", async (symbolName, onSymbolResolvedCallback, onResolveErrorCallback) => {
49
- if (!symbolName) {
50
- await onResolveErrorCallback("cannot resolve symbol");
51
- return;
52
- }
53
- const symbolInfo = () => {
54
- return {
55
- ticker: symbolName,
56
- name: symbolName,
57
- ticker: symbolName,
58
- description: symbolName,
59
- type: "crypto",
60
- session: "24x7",
61
- timezone: "Etc/UTC",
62
- exchange: "Binance",
63
- minmov: 100,
64
- pricescale: 100000,
65
- has_daily: true,
66
- has_intraday: true,
67
- has_no_volume: false,
68
- has_seconds: true,
69
- seconds_multipliers: [1],
70
- volume: "hundreds",
71
- volume_precision: 9,
72
- data_status: "streaming",
73
- resolution: "1h"
74
- };
36
+ let interval = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "1h";
37
+ this.streaming = null;
38
+ this.timescaleMarks = timescaleMarks;
39
+ this.interval = interval;
40
+ }
41
+ onReady = async callback => {
42
+ this.configurationData = await getConfigurationData();
43
+ callback(this.configurationData);
44
+ };
45
+ searchSymbols = async (userInput, exchange, symbolType, onResultReadyCallback) => {
46
+ const symbols = await (0, _helpers.getAllSymbols)(userInput);
47
+ onResultReadyCallback(symbols);
48
+ };
49
+ resolveSymbol = async (symbolName, onSymbolResolvedCallback, onResolveErrorCallback) => {
50
+ if (!symbolName) {
51
+ await onResolveErrorCallback("cannot resolve symbol");
52
+ return;
53
+ }
54
+ const symbolInfo = () => {
55
+ return {
56
+ ticker: symbolName,
57
+ name: symbolName,
58
+ ticker: symbolName,
59
+ description: symbolName,
60
+ type: "crypto",
61
+ session: "24x7",
62
+ timezone: "Etc/UTC",
63
+ exchange: "Binance",
64
+ minmov: 100,
65
+ pricescale: 100000000,
66
+ has_daily: true,
67
+ has_intraday: true,
68
+ has_no_volume: false,
69
+ has_seconds: true,
70
+ seconds_multipliers: [1],
71
+ volume: "hundreds",
72
+ volume_precision: 9,
73
+ data_status: "streaming",
74
+ resolution: "1h"
75
75
  };
76
- const symbol = await symbolInfo();
77
- onSymbolResolvedCallback(symbol);
78
- });
79
- _defineProperty(this, "getBars", async (symbolInfo, resolution, periodParams, onHistoryCallback, onErrorCallback) => {
80
- const {
81
- from,
82
- to,
83
- firstDataRequest
84
- } = periodParams;
85
- let interval = "60"; // 1 hour
86
- // Calculate interval using resolution data
87
- if (!/[a-zA-Z]$/.test(resolution)) {
88
- if (parseInt(resolution) >= 60) {
89
- interval = parseInt(resolution) / 60 + "h";
90
- } else {
91
- interval = resolution + "m";
92
- }
76
+ };
77
+ const symbol = await symbolInfo();
78
+ onSymbolResolvedCallback(symbol);
79
+ };
80
+ getBars = async (symbolInfo, resolution, periodParams, onHistoryCallback, onErrorCallback) => {
81
+ const {
82
+ from,
83
+ to,
84
+ firstDataRequest
85
+ } = periodParams;
86
+ let interval = "60"; // 1 hour
87
+ // Calculate interval using resolution data
88
+ if (!/[a-zA-Z]$/.test(resolution)) {
89
+ if (parseInt(resolution) >= 60) {
90
+ interval = parseInt(resolution) / 60 + "h";
93
91
  } else {
94
- interval = resolution.toLowerCase().replace(/[a-z]\b/g, c => c.toLowerCase());
92
+ interval = resolution + "m";
95
93
  }
96
- let urlParameters = {
97
- symbol: symbolInfo.name,
98
- interval: interval,
99
- startTime: Math.abs(from * 1000),
100
- endTime: Math.abs(to * 1000),
101
- limit: 600
102
- };
103
- const query = Object.keys(urlParameters).map(name => `${name}=${encodeURIComponent(urlParameters[name])}`).join("&");
104
- try {
105
- const data = await (0, _helpers.makeApiRequest)(`api/v3/uiKlines?${query}`);
106
- if (data.Response && data.Response === "Error" || data.length === 0) {
107
- // "noData" should be set if there is no data in the requested period.
108
- onHistoryCallback([], {
109
- noData: true
110
- });
111
- return;
112
- }
113
- let bars = [];
114
- data.forEach(bar => {
115
- if (bar[0] >= from * 1000 && bar[0] < to * 1000) {
116
- bars = [...bars, {
117
- time: bar[0],
118
- low: bar[3],
119
- high: bar[2],
120
- open: bar[1],
121
- close: bar[4],
122
- volume: bar[5]
123
- }];
124
- }
125
- });
126
- onHistoryCallback(bars, {
127
- noData: false
94
+ } else {
95
+ interval = resolution.toLowerCase().replace(/[a-z]\b/g, c => c.toLowerCase());
96
+ }
97
+ let urlParameters = {
98
+ symbol: symbolInfo.name,
99
+ interval: interval,
100
+ startTime: Math.abs(from * 1000),
101
+ endTime: Math.abs(to * 1000),
102
+ limit: 600
103
+ };
104
+ const query = Object.keys(urlParameters).map(name => `${name}=${encodeURIComponent(urlParameters[name])}`).join("&");
105
+ try {
106
+ const data = await (0, _helpers.makeApiRequest)(`api/v3/uiKlines?${query}`);
107
+ if (data.Response && data.Response === "Error" || data.length === 0) {
108
+ // "noData" should be set if there is no data in the requested period.
109
+ onHistoryCallback([], {
110
+ noData: true
128
111
  });
129
- } catch (error) {
130
- console.log("[getBars]: Get error", error);
131
- onErrorCallback(error);
112
+ return;
132
113
  }
133
- });
134
- _defineProperty(this, "subscribeBars", (symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => {
135
- (0, _streaming.subscribeOnStream)(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback, this.interval);
136
- });
137
- _defineProperty(this, "unsubscribeBars", subscriberUID => {
138
- (0, _streaming.unsubscribeFromStream)(subscriberUID);
139
- });
140
- this.streaming = null;
141
- this.timescaleMarks = timescaleMarks;
142
- this.interval = _interval;
143
- }
114
+ let bars = [];
115
+ data.forEach(bar => {
116
+ if (bar[0] >= from * 1000 && bar[0] < to * 1000) {
117
+ bars = [...bars, {
118
+ time: bar[0],
119
+ low: bar[3],
120
+ high: bar[2],
121
+ open: bar[1],
122
+ close: bar[4],
123
+ volume: bar[5]
124
+ }];
125
+ }
126
+ });
127
+ onHistoryCallback(bars, {
128
+ noData: false
129
+ });
130
+ } catch (error) {
131
+ console.log("[getBars]: Get error", error);
132
+ onErrorCallback(error);
133
+ }
134
+ };
144
135
  getTimescaleMarks(symbolInfo, from, to, onDataCallback, resolution) {
145
136
  if (this.timescaleMarks.length > 0) {
146
137
  let timescaleMarks = Object.assign([], this.timescaleMarks);
@@ -152,5 +143,11 @@ class Datafeed {
152
143
  const serverTime = data.serverTime / 1000;
153
144
  onServertimeCallback(serverTime);
154
145
  }
146
+ subscribeBars = (symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => {
147
+ (0, _streaming.subscribeOnStream)(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback, this.interval);
148
+ };
149
+ unsubscribeBars = subscriberUID => {
150
+ (0, _streaming.unsubscribeFromStream)(subscriberUID);
151
+ };
155
152
  }
156
153
  exports.default = Datafeed;
@@ -10,4 +10,4 @@ Object.defineProperty(exports, "TVChartContainer", {
10
10
  }
11
11
  });
12
12
  var _TVChartContainer = _interopRequireDefault(require("./TVChartContainer"));
13
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.4.2",
2
+ "version": "0.5.0",
3
3
  "name": "binbot-charts",
4
4
  "dependencies": {
5
5
  "react": "^17.0.1",
@@ -11,11 +11,12 @@
11
11
  "@babel/core": "^7.18.13",
12
12
  "@babel/polyfill": "^7.12.1",
13
13
  "@babel/preset-env": "^7.19.0",
14
+ "@types/node": "^22.7.5",
14
15
  "@types/react": "^18.0.26",
15
16
  "@types/react-dom": "^18.0.10",
16
17
  "immer": "^9.0.17",
17
18
  "react-scripts": "^5.0.1",
18
- "typescript": "^4.9.4"
19
+ "typescript": "^4.9.5"
19
20
  },
20
21
  "scripts": {
21
22
  "start": "react-scripts start",
@@ -1,122 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = TVChartContainer;
7
- var _react = _interopRequireWildcard(require("react"));
8
- var _charting_library = require("../charting_library");
9
- var _datafeed = _interopRequireDefault(require("./datafeed"));
10
- var _propTypes = _interopRequireDefault(require("prop-types"));
11
- var _useImmer = require("use-immer");
12
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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); }
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; }
15
- function TVChartContainer(_ref) {
16
- let {
17
- symbol = "BTCUSDT",
18
- interval = "1h",
19
- libraryPath = "/charting_library/",
20
- timescaleMarks = [],
21
- orderLines = [],
22
- height = "calc(100vh - 80px)",
23
- onTick,
24
- getLatestBar
25
- } = _ref;
26
- const containerRef = (0, _react.useRef)(null);
27
- const [chartOrderLines, setChartOrderLines] = (0, _useImmer.useImmer)([]);
28
- const [widgetState, setWidgetState] = (0, _useImmer.useImmer)(null);
29
- const [symbolState] = (0, _react.useState)(null);
30
- const prevTimescaleMarks = (0, _react.useRef)(timescaleMarks);
31
- (0, _react.useEffect)(() => {
32
- if (!widgetState) {
33
- initializeChart("1h");
34
- }
35
- if (orderLines && orderLines.length > 0) {
36
- updateOrderLines(orderLines);
37
- }
38
- if (widgetState && symbol !== symbolState) {
39
- widgetState.setSymbol(symbol, interval);
40
- }
41
- if (widgetState && prevTimescaleMarks.current && timescaleMarks !== prevTimescaleMarks.current) {
42
- widgetState._options.datafeed.timescaleMarks = timescaleMarks;
43
- prevTimescaleMarks.current = timescaleMarks;
44
- }
45
- }, [orderLines, timescaleMarks]);
46
- const initializeChart = interval => {
47
- const widgetOptions = {
48
- symbol: symbol,
49
- datafeed: new _datafeed.default(timescaleMarks, interval),
50
- interval: interval,
51
- container: containerRef.current,
52
- library_path: libraryPath,
53
- locale: "en",
54
- fullscreen: false,
55
- autosize: true,
56
- studies_overrides: {},
57
- symbol_search_request_delay: 1000,
58
- overrides: {
59
- volumePaneSize: "small",
60
- "mainSeriesProperties.barStyle.dontDrawOpen": false
61
- }
62
- };
63
- const tvWidget = new _charting_library.widget(widgetOptions);
64
- tvWidget.onChartReady(() => {
65
- tvWidget.subscribe("onTick", event => onTick(event));
66
- setWidgetState(tvWidget);
67
-
68
- // get latest bar for last price
69
- const prices = async () => {
70
- const data = await tvWidget.activeChart().exportData({
71
- includeTime: false,
72
- includeSeries: true,
73
- includedStudies: []
74
- });
75
- getLatestBar(data.data[data.data.length - 1]);
76
- };
77
- prices();
78
- });
79
- };
80
- const updateOrderLines = orderLines => {
81
- if (chartOrderLines && chartOrderLines.length > 0) {
82
- chartOrderLines.forEach(item => {
83
- orderLines.forEach(order => {
84
- if (item.id == order.id) {
85
- item.setText(order.text).setTooltip(order.tooltip).setQuantity(order.quantity).setPrice(order.price);
86
- }
87
- });
88
- });
89
- } else {
90
- if (widgetState && orderLines && orderLines.length > 0) {
91
- orderLines.forEach(order => {
92
- const lineStyle = order.lineStyle || 0;
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);
94
-
95
- // set custom id easier search
96
- chartOrderLine.id = order.id;
97
- setChartOrderLines(draft => {
98
- draft.push(chartOrderLine);
99
- return draft;
100
- });
101
- });
102
- }
103
- }
104
- };
105
- return /*#__PURE__*/_react.default.createElement("div", {
106
- ref: containerRef,
107
- style: {
108
- height: height
109
- }
110
- });
111
- }
112
- TVChartContainer.propTypes = {
113
- apiKey: _propTypes.default.string,
114
- symbol: _propTypes.default.string,
115
- interval: _propTypes.default.string,
116
- libraryPath: _propTypes.default.string,
117
- timescaleMarks: _propTypes.default.array,
118
- orderLines: _propTypes.default.array,
119
- height: _propTypes.default.string,
120
- onTick: _propTypes.default.func,
121
- getLatestBar: _propTypes.default.func
122
- };