关于tradingView与websocket结合的可用案例

HTML部分:


    
        
        
    

    
        


        

        
        
        
        
        
        
    

socket.js部分:

'use strict';


function _classCallCheck(instance, Constructor) { 
    if (!(instance instanceof Constructor)) 
    { throw new TypeError("Cannot call a class as a function"); 
    } 
}

var socket = function () {
  function socket() {
    var url = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'wss://api.fcoin.com/v2/ws';
    var options = arguments[1];

    _classCallCheck(this, socket);

    this.heartBeatTimer = null;
    this.options = options;
    this.messageMap = {};
    this.connState = 0;
    this.socket = null;
    this.url = url;
  }

  socket.prototype.doOpen = function doOpen() {
    var _this = this;
    console.log("我被调用了")
    if (this.connState) return;
    this.connState = 1;
    this.afterOpenEmit = [];
    var BrowserWebSocket = window.WebSocket || window.MozWebSocket;
    var socket = new BrowserWebSocket(this.url);
    socket.binaryType = 'arraybuffer';
    socket.onopen = function (evt) {
      return _this.onOpen(evt);
    };
    socket.onclose = function (evt) {
      return _this.onClose(evt);
    };
    socket.onmessage = function (evt) {
      return _this.onMessage(evt.data);
    };
    socket.onerror = function (err) {
      return _this.onError(err);
    };
    this.socket = socket;
  };

  socket.prototype.onOpen = function onOpen(evt) {
    this.connState = 2;
    this.heartBeatTimer = setInterval(this.checkHeartbeat.bind(this), 20000);
    this.onReceiver({ Event: 'open' });
  };

  socket.prototype.checkOpen = function checkOpen() {
    return this.connState === 2;
  };

  socket.prototype.onClose = function onClose() {
    this.connState = 0;
    if (this.connState) {
      this.onReceiver({ Event: 'close' });
    }
  };

  socket.prototype.send = function send(data) {
    this.socket.send(JSON.stringify(data));
  };

  socket.prototype.emit = function emit(data) {
    var _this2 = this;

    return new Promise(function (resolve) {
      _this2.socket.send(JSON.stringify(data));
      _this2.on('message', function (data) {
        resolve(data);
      });
    });
  };

  socket.prototype.onMessage = function onMessage(message) {
    try {
      var data = JSON.parse(message);
      this.onReceiver({ Event: 'message', Data: data });
    } catch (err) {
      console.error(' >> Data parsing error:', err);
    }
  };

  socket.prototype.checkHeartbeat = function checkHeartbeat() {
    var data = {
      'cmd': 'ping',
      'args': [Date.parse(new Date())]
    };
    this.send(data);
  };

  socket.prototype.onError = function onError(err) {};

  socket.prototype.onReceiver = function onReceiver(data) {
    var callback = this.messageMap[data.Event];
    if (callback) callback(data.Data);
  };

  socket.prototype.on = function on(name, handler) {
    this.messageMap[name] = handler;
  };

  socket.prototype.doClose = function doClose() {
    this.socket.close();
  };

  socket.prototype.destroy = function destroy() {
    if (this.heartBeatTimer) {
      clearInterval(this, this.heartBeatTimer);
      this.heartBeatTimer = null;
    }
    this.doClose();
    this.messageMap = {};
    this.connState = 0;
    this.socket = null;
  };

  return socket;
}();
 

datafees.js部分:

'use strict';

var _dataUpdater2 = _interopRequireDefault(dataUpdater);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
                                                                                                                                                           * JS API
                                                                                                                                                           */
var datafeeds = function () {

  /**
   * JS API
   * @param {*Object} vue vue实例
   */
  function datafeeds(vue) {
    _classCallCheck(this, datafeeds);

    this.self = vue;
    this.barsUpdater = new _dataUpdater2.default(this);
  }

  /**
   * @param {*Function} callback  回调函数
   * `onReady` should return result asynchronously.
   */


  datafeeds.prototype.onReady = function onReady(callback) {
    var _this = this;

    return new Promise(function (resolve, reject) {
      var configuration = _this.defaultConfiguration();
      if (_this.self.getConfig) {
        configuration = Object.assign(_this.defaultConfiguration(), _this.self.getConfig());
      }
      resolve(configuration);
    }).then(function (data) {
      return callback(data);
    });
  };

  /**
   * @param {*String} symbolName  商品名称或ticker
   * @param {*Function} onSymbolResolvedCallback 成功回调 
   * @param {*Function} onResolveErrorCallback   失败回调
   * `resolveSymbol` should return result asynchronously.
   */


  datafeeds.prototype.resolveSymbol = function resolveSymbol(symbolName, onSymbolResolvedCallback, onResolveErrorCallback) {
    var _this2 = this;

    return new Promise(function (resolve, reject) {
      var symbolInfo = _this2.defaultSymbol();
      if (_this2.self.getSymbol) {
        symbolInfo = Object.assign(_this2.defaultSymbol(), _this2.self.getSymbol());
      }
      resolve(symbolInfo);
    }).then(function (data) {
      return onSymbolResolvedCallback(data);
    }).catch(function (err) {
      return onResolveErrorCallback(err);
    });
  };

  /**
   * @param {*Object} symbolInfo  商品信息对象
   * @param {*String} resolution  分辨率
   * @param {*Number} rangeStartDate  时间戳、最左边请求的K线时间
   * @param {*Number} rangeEndDate  时间戳、最右边请求的K线时间
   * @param {*Function} onDataCallback  回调函数
   * @param {*Function} onErrorCallback  回调函数
   */


  datafeeds.prototype.getBars = function getBars(symbolInfo, resolution, rangeStartDate, rangeEndDate, onDataCallback, onErrorCallback) {
    var onLoadedCallback = function onLoadedCallback(data) {

                 if(data&&LastLength!=data.length){
                        onDataCallback(data, { noData: false });
                 }else{
                         onDataCallback([], { noData: true });
                }
                 LastLength = data.length;

 

//或者可以这样写:
      data && data.length ? onDataCallback(data, { noData: true }) : onDataCallback([], { noData: true });
    };
    this.self.getBars(symbolInfo, resolution, rangeStartDate, rangeEndDate, onLoadedCallback);
  };

  /**
   * 订阅K线数据。图表库将调用onRealtimeCallback方法以更新实时数据
   * @param {*Object} symbolInfo 商品信息
   * @param {*String} resolution 分辨率
   * @param {*Function} onRealtimeCallback 回调函数 
   * @param {*String} subscriberUID 监听的唯一标识符
   * @param {*Function} onResetCacheNeededCallback (从1.7开始): 将在bars数据发生变化时执行
   */


  datafeeds.prototype.subscribeBars = function subscribeBars(symbolInfo, resolution, onRealtimeCallback, subscriberUID, onResetCacheNeededCallback) {
    this.barsUpdater.subscribeBars(symbolInfo, resolution, onRealtimeCallback, subscriberUID, onResetCacheNeededCallback);
  };

  /**
   * 取消订阅K线数据
   * @param {*String} subscriberUID 监听的唯一标识符
   */


  datafeeds.prototype.unsubscribeBars = function unsubscribeBars(subscriberUID) {
    this.barsUpdater.unsubscribeBars(subscriberUID);
  };

  /**
   * 默认配置
   */


  datafeeds.prototype.defaultConfiguration = function defaultConfiguration() {
      //设置默认配置
    return {
      supports_search: false,
      supports_group_request: false,
      supported_resolutions: ['1', '5', '15', '30', '60', '240','1D', '5D', '1W', '1M'],
      supports_marks: true,
      supports_timescale_marks: true,
      supports_time: true
    };
  };

  /**
   * 默认商品信息
   */


  datafeeds.prototype.defaultSymbol = function defaultSymbol() {
    return {
      'name': 'BTCUSDT',
      'timezone': 'Asia/Shanghai',
      'minmov': 1,
      'minmov2': 0,
      'pointvalue': 1,
      'fractional': false,
      //设置周期
      'session': '24x7',
      'has_intraday': true,
      'has_no_volume': false,  
       //设置是否支持周月线
       "has_daily":true,
       //设置是否支持周月线
       "has_weekly_and_monthly":true,
      'description': 'BTCUSDT',
          //设置精度  100表示保留两位小数   1000三位   10000四位
      'pricescale': 100,
      'ticker': 'BTCUSDT',
      'supported_resolutions': ['1', '5', '15', '30', '60', '240','1D', '5D', '1W', '1M']
    };
  };

  return datafeeds;
}();

 

dataUpdater.js部分:

'use strict';


function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * 数据更新器
 * 通过更新器触发datafeeds的getBars实时更新图表数据
 */
var dataUpdater = function () {
  function dataUpdater(datafeeds) {
    _classCallCheck(this, dataUpdater);

    this.subscribers = {};
    this.requestsPending = 0;
    this.historyProvider = datafeeds;
  }

  dataUpdater.prototype.subscribeBars = function subscribeBars(symbolInfo, resolution, newDataCallback, listenerGuid) {
    this.subscribers[listenerGuid] = {
      lastBarTime: null,
      listener: newDataCallback,
      resolution: resolution,
      symbolInfo: symbolInfo
    };
  };

  dataUpdater.prototype.unsubscribeBars = function unsubscribeBars(listenerGuid) {
    delete this.subscribers[listenerGuid];
  };

  dataUpdater.prototype.updateData = function updateData() {
    var _this = this;

    if (this.requestsPending) return;
    this.requestsPending = 0;
    for (var listenerGuid in this.subscribers) {
      this.requestsPending++;
      this.updateDataForSubscriber(listenerGuid).then(function () {
        return _this.requestsPending--;
      }).catch(function () {
        return _this.requestsPending--;
      });
    }
  };

  dataUpdater.prototype.updateDataForSubscriber = function updateDataForSubscriber(listenerGuid) {
    var _this2 = this;

    return new Promise(function (resolve, reject) {
      var subscriptionRecord = _this2.subscribers[listenerGuid];
      var rangeEndTime = parseInt((Date.now() / 1000).toString());
      var rangeStartTime = rangeEndTime - _this2.periodLengthSeconds(subscriptionRecord.resolution, 10);
      _this2.historyProvider.getBars(subscriptionRecord.symbolInfo, subscriptionRecord.resolution, rangeStartTime, rangeEndTime, function (bars) {
        _this2.onSubscriberDataReceived(listenerGuid, bars);
        resolve();
      }, function () {
        reject();
      });
    });
  };

  dataUpdater.prototype.onSubscriberDataReceived = function onSubscriberDataReceived(listenerGuid, bars) {
    if (!this.subscribers.hasOwnProperty(listenerGuid)) return;
    if (!bars.length) return;
    var lastBar = bars[bars.length - 1];
    var subscriptionRecord = this.subscribers[listenerGuid];
    if (subscriptionRecord.lastBarTime !== null && lastBar.time < subscriptionRecord.lastBarTime) return;
    var isNewBar = subscriptionRecord.lastBarTime !== null && lastBar.time > subscriptionRecord.lastBarTime;
    if (isNewBar) {
      if (bars.length < 2) {
        throw new Error('Not enough bars in history for proper pulse update. Need at least 2.');
      }

      var previousBar = bars[bars.length - 2];
      subscriptionRecord.listener(previousBar);
    }

    subscriptionRecord.lastBarTime = lastBar.time;
    subscriptionRecord.listener(lastBar);
  };

  dataUpdater.prototype.periodLengthSeconds = function periodLengthSeconds(resolution, requiredPeriodsCount) {
    var daysCount = 0;
    if (resolution === 'D' || resolution === '1D') {
      daysCount = requiredPeriodsCount;
    } else if (resolution === 'M' || resolution === '1M') {
      daysCount = 31 * requiredPeriodsCount;
    } else if (resolution === 'W' || resolution === '1W') {
      daysCount = 7 * requiredPeriodsCount;
    } else {
      daysCount = requiredPeriodsCount * parseInt(resolution) / (24 * 60);
    }
    return daysCount * 24 * 60 * 60;
  };

  return dataUpdater;
}();

 

//参考资料:

https://b.aitrade.ga/books/tradingview/book/UDF.html  牛人整理的帮助文档

https://github.com/zlq4863947/proficient-tradingview/blob/master/book/01-Basic-Compose.md

http://tradingview.github.io/featuresets.html属性配置

https://github.com/huobiapi/API_Docs/wiki/REST_api_reference 火币接口

http://i.youku.com/i/UMTM3NjEzNTY4/videos?spm=a2hzp.8244740.0.0  视频教程   C:\Users\admin\Documents\Tencent Files\416253521\FileRecv


https://blog.csdn.net/young_gao/article/details/80691800 好的案例

控制加载闪白的方法:在tv-chart.630b704a2b9d0eaf1593.html中设置style:#loading-indicator,body.chart-page{background:0 0}

你可能感兴趣的:(前端,区块链技术,ES6)