首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >连接到加密比较的Python套接字示例

连接到加密比较的Python套接字示例
EN

Stack Overflow用户
提问于 2017-10-05 00:37:48
回答 3查看 3K关注 0票数 6

我正在尝试从Python客户端使用socketIO连接到Cryptocompare的websocket流。事实证明,这是具有挑战性的。以下是一些示例Python代码:

代码语言:javascript
复制
from socketIO_client import SocketIO

print "connecting to server"
socketIO = SocketIO('https://streamer.cryptocompare.com/',443, transports=['websocket'])
print "Connected"

然而,无论我做什么,我都不能连接。实际上,这是连接结果

代码语言:javascript
复制
connecting to server
Traceback (most recent call last):
  File "test.py", line 4, in <module>
socketIO = SocketIO('https://streamer.cryptocompare.com/',443, transports=['websocket'])
  File "/usr/local/lib/python2.7/site-packages/socketIO_client/__init__.py", line 353, in __init__
resource, hurry_interval_in_seconds, **kw)
  File "/usr/local/lib/python2.7/site-packages/socketIO_client/__init__.py", line 54, in __init__
self._transport
  File "/usr/local/lib/python2.7/site-packages/socketIO_client/__init__.py", line 62, in _transport
self._engineIO_session = self._get_engineIO_session()
  File "/usr/local/lib/python2.7/site-packages/socketIO_client/__init__.py", line 76, in _get_engineIO_session
transport.recv_packet())
StopIteration

将上述代码包装在try-catch中并打印异常不会产生额外的信息。任何帮助都将不胜感激。

EN

回答 3

Stack Overflow用户

发布于 2018-01-29 19:52:49

socketIO_client库似乎不支持加密比较所使用的XHR轮询协议。我通过覆盖socketIO_client.transports.XHR_PollingTransport类中的recv_packet方法使其正常工作。

代码语言:javascript
复制
import logging
import socketIO_client
from socketIO_client.transports import get_response
from socketIO_client.parsers import get_byte, _read_packet_text, parse_packet_text

from requests.exceptions import ConnectionError

# extra function to support XHR1 style protocol
def _new_read_packet_length(content, content_index):
    packet_length_string = ''
    while get_byte(content, content_index) != ord(':'):
        byte = get_byte(content, content_index)
        packet_length_string += chr(byte)
        content_index += 1
    content_index += 1
    return content_index, int(packet_length_string)

def new_decode_engineIO_content(content):
    content_index = 0
    content_length = len(content)
    while content_index < content_length:
        try:
            content_index, packet_length = _new_read_packet_length(
                content, content_index)
        except IndexError:
            break
        content_index, packet_text = _read_packet_text(
            content, content_index, packet_length)
        engineIO_packet_type, engineIO_packet_data = parse_packet_text(
            packet_text)
        yield engineIO_packet_type, engineIO_packet_data

def new_recv_packet(self):
    params = dict(self._params)
    params['t'] = self._get_timestamp()
    response = get_response(
        self.http_session.get,
        self._http_url,
        params=params,
        **self._kw_get)
    for engineIO_packet in new_decode_engineIO_content(response.content):
        engineIO_packet_type, engineIO_packet_data = engineIO_packet
        yield engineIO_packet_type, engineIO_packet_data

setattr(socketIO_client.transports.XHR_PollingTransport, 'recv_packet', new_recv_packet)

logging.basicConfig(level=logging.DEBUG)

try:
    socket = socketIO_client.SocketIO('https://streamer.cryptocompare.com')
    socket.emit('SubAdd', { 'subs': ['0~Kraken~BTC~USD'] });
    socket.wait()
except ConnectionError:
    print('The server is down. Try again later.')

该解决方案在很大程度上基于github的评论:https://github.com/invisibleroads/socketIO-client/issues/129#issuecomment-330058318

票数 4
EN

Stack Overflow用户

发布于 2017-12-23 10:40:07

您需要在设置套接字之后立即调用emit来设置您想要接收的订阅。

代码语言:javascript
复制
socketIO.emit('SubAdd', { subs: ['0~Poloniex~BTC~USD'] });
票数 0
EN

Stack Overflow用户

发布于 2018-01-07 11:40:44

我已经从几个角度考虑了这个问题,并得出结论,python的socketio客户端不能与此API一起工作。如果您只想将数据从CryptoCompare流api流式传输到python,那么我有一个变通方法,它使用websockets向一个简单的nodejs应用程序提交请求,然后该应用程序使用其socketio-client来流式传输所需的数据。我是python的新手,只是在这个解决方案中使用了nodejs,所以不要对我太苛刻。

Crypto目前很热门,所以我相信这会对一些人有用

Python部分:

代码语言:javascript
复制
import json
import pandas as pd
try:
   import thread
except ImportError:
import _thread as thread

import threading
import time
import websocket


class WebSocketClient(threading.Thread):

 def __init__(self):
    self.url = 'ws://localhost:9030/path'
    # self.daemon = True
    self.clist = list()
    threading.Thread.__init__(self)


 def run(self):

    # Running the run_forever() in a seperate thread.
    #websocket.enableTrace(True)
    self.ws = websocket.WebSocketApp(self.url,
                                     on_message = self.on_message,
                                     on_error = self.on_error,
                                     on_close = self.on_close)
    self.ws.on_open = self.on_open
    self.ws.run_forever()

 def send(self, data):

    data = self._encode_message(data)
    # Wait till websocket is connected.
    while not self.ws.sock.connected:
        time.sleep(0.25)

    print(f'Sending data... {data}')
    self.ws.send(data)

 def stop(self):
    print(f'Stopping the websocket...')
    self.ws.close()

 def on_message(self, ws, message):
    message = self._decode_message(message)
    print(f'Received data...{message}')
    if message['msg']=='crypto':

        self.clist.append(message['data'])

 def on_error(self, ws, error):
    print(f'Received error...')
    print(error)

 def on_close(self, ws):
    print('Closed the connection...')

 def on_open(self, ws):
    print('Opened the connection...')
    data = {"msg":"open" ,"from":"Rob", "data":"Hello from the client"}
    self.send(data)

 def _encode_message(self,message):

    message = json.dumps(message)
    return message

 def _decode_message(self, message):

    message = json.loads(message)
    return message

 def getclist(self):
    return self.clist


wsCli =  WebSocketClient()
wsCli.daemon = True
wsCli.start()
wsCli.send({"msg":"getcrypto" ,"from":"Client", "data":['0~Coinbase~BTC~USD'],"subs":['0~Coinbase~BTC~USD']})
wsCli.stop()

Nodejs部分:

代码语言:javascript
复制
var socket = require('socket.io-client')('https://streamer.cryptocompare.com/')
var socketon = false

var WebSocketServer = require('ws').Server , wss = new WebSocketServer({port: 9030});
wss.on('connection', function(ws) {
         ws.on('message', function(message) {
			           msg = decode_message(message);
                       console.log('received: %s', message);
                       console.log('test: %s', msg['msg']);
							   switch(msg['msg']) {
								   case 'open':
                                       message_type = 'open';
									   
	
									 // do something with chat data. i.e.:
									 console.log("open from " + msg['from'] +
										   ": " + msg['data']);
									
                                     outmessage = 'welcome from server ' + msg['from'];
									 ws.send(encode_message(outmessage, message_type = 'open'));
									 break
								  case 'getcrypto':
									 message_type = "crypto"
									 // do something with chat data. i.e.:
									 console.log("'getcrypto': object" + msg['data']);
                                     socket.emit('SubAdd', { subs: msg.subs });
                                     if (!socketon) {
                                         socket.on("m", function (message) {
                                             var messageType = message.substring(0, message.indexOf("~"));
                                             var res = {};
                                             switch (messageType) {
                                                 case CCC.STATIC.TYPE.TRADE:
                                                     res = CCC.TRADE.unpack(message);
                                                     break;
                                                 case CCC.STATIC.TYPE.CURRENT:
                                                     res = CCC.CURRENT.unpack(message);
                                                     break;
                                                 case CCC.STATIC.TYPE.CURRENTAGG:
                                                     res = CCC.CURRENT.unpack(message);
                                                     // updateQuote(res);
                                                     break;
                                                 case CCC.STATIC.TYPE.ORDERBOOK:
                                                     res = CCC.ORDER.unpack(message);
                                                     break;
                                                 case CCC.STATIC.TYPE.FULLORDERBOOK:
                                                     res = CCC.ORDER.unpack(message);
                                                     break;
                                             }
                                             console.log(message);
                                             console.log(res);
                                             ws.send(encode_message(res, message_type = "crypto"));
                                         })
                                     }
                                     socketon = true;
									 break
								  case 'canccrypto':
									  // do something with chat data. i.e.:
									   message_type = "crypto"
									  console.log(msg['msg'] +":" + msg['data']);
									  socket.emit('SubRemove', { subs: msg.subs });
									  break
								  case 'other':
									 // do something with chat data. i.e.:
									   
									 console.log("open from " + msg['from'] +
										   ": " + msg['data']);
									 outmessage = 'other from server ' + msg['from']
									 ws.send(encode_message(outmessage, message_type = "other"));
									 break
								  // ... and so on
							   }
           });

     });

function decode_message(message) {
	msg = JSON.parse(message);
	return msg;
}

function encode_message(message, messsage_type) {
	if (message_type == "crypto") {
		var msg_crypto = { 'msg': 'crypto', 'data': message };
		msg = JSON.stringify(msg_crypto);
	}
	else {
		var msg_other = { 'msg': 'other', 'data': message };
		msg = JSON.stringify(msg_other);
	}
	return msg;
}


var CCC = CCC || {};

CCC.STATIC = CCC.STATIC || {};

CCC.STATIC.TYPE = {
	'TRADE': '0'
	, 'FEEDNEWS': '1'
	, 'CURRENT': '2'
	, 'LOADCOMPLATE': '3'
	, 'COINPAIRS': '4'
	, 'CURRENTAGG': '5'
	, 'TOPLIST': '6'
	, 'TOPLISTCHANGE': '7'
	, 'ORDERBOOK': '8'
	, 'FULLORDERBOOK': '9'
	, 'ACTIVATION': '10'

	, 'TRADECATCHUP': '100'
	, 'NEWSCATCHUP': '101'

	, 'TRADECATCHUPCOMPLETE': '300'
	, 'NEWSCATCHUPCOMPLETE': '301'

};

CCC.STATIC.CURRENCY = CCC.STATIC.CURRENCY || {};

CCC.STATIC.CURRENCY.SYMBOL = {
	'BTC': '?'
	, 'LTC': '?'
	, 'DAO': 'Ð'
	, 'USD': '$'
	, 'CNY': '¥'
	, 'EUR': '€'
	, 'GBP': '£'
	, 'JPY': '¥'
	, 'PLN': 'z?'
	, 'RUB': '?'
	, 'ETH': '?'
	, 'GOLD': 'Gold g'
	, 'INR': '?'
	, 'BRL': 'R$'
};

CCC.STATIC.CURRENCY.getSymbol = function (symbol) {
	return CCC.STATIC.CURRENCY.SYMBOL[symbol] || symbol;
};

CCC.STATIC.UTIL = {
	exchangeNameMapping: {
		'CCCAGG': 'CryptoCompare Index',
		'BTCChina': 'BTCC'
	},
	isMobile: function (userAgent) {
		if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(userAgent)
			|| /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(userAgent.substr(0, 4)))
			return true;
		return false;
	},
	convertToMB: function (bytes) {
		return (parseInt(bytes, 10) / 1024 / 1024).toFixed(2) + ' MB';
	},
	getNameForExchange: function (exchangeName) {
		if (this.exchangeNameMapping.hasOwnProperty(exchangeName)) {
			return this.exchangeNameMapping[exchangeName];
		}
		return exchangeName;
	},
	noExponents: function (value) {
		var data = String(value).split(/[eE]/);
		if (data.length == 1) return data[0];

		var z = '', sign = value < 0 ? '-' : '',
			str = data[0].replace('.', ''),
			mag = Number(data[1]) + 1;

		if (mag < 0) {
			z = sign + '0.';
			while (mag++) z += '0';
			return z + str.replace(/^\-/, '');
		}
		mag -= str.length;
		while (mag--) z += '0';
		return str + z;
	},
	reduceFloatVal: function (value) {
		value = parseFloat(value);
		if (value > 1) {
			value = Math.round(value * 100) / 100;
			return value;
		}
		if (value >= 0.00001000) {
			return parseFloat(value.toPrecision(4));
		}
		if (value >= 0.00000100) {
			return parseFloat(value.toPrecision(3));
		}
		if (value >= 0.00000010) {
			return parseFloat(value.toPrecision(2));
		}
		return parseFloat(value.toPrecision(1));
	},
	reduceReal: function (value) {
		value = parseFloat(value);
		return parseFloat(value.toFixed(8));
	},
	convertCurrentKeyToAll: function (key) {
		var valuesArray = key.split("~");
		valuesArray[0] = CCC.STATIC.TYPE.CURRENTAGG;
		valuesArray[1] = 'CCCAGG';
		return valuesArray.join('~');
	},
	convertCurrentKeyToTrade: function (key) {
		var valuesArray = key.split("~");
		valuesArray[0] = CCC.STATIC.TYPE.TRADE;
		return valuesArray.join('~');
	},
	convertValueToDisplay: function (symbol, value, filterNumberFunctionAngularJS, type, fullNumbers) {
		var prefix = '';
		var valueSign = 1;
		value = parseFloat(value);
		var valueAbs = Math.abs(value);
		var decimalsOnBigNumbers = 2;
		var decimalsOnNormalNumbers = 2;
		var decimalsOnSmallNumbers = 4;
		if (fullNumbers === true) {
			decimalsOnBigNumbers = 2;
			decimalsOnNormalNumbers = 0;
			decimalsOnSmallNumbers = 4;
		}
		if (type == "8decimals") {
			decimalsOnBigNumbers = 4;
			decimalsOnNormalNumbers = 8;
			decimalsOnSmallNumbers = 8;
			if (value < 0.0001 && value >= 0.00001) { decimalsOnSmallNumbers = 4; }
			if (value < 0.001 && value >= 0.0001) { decimalsOnSmallNumbers = 5; }
			if (value < 0.01 && value >= 0.001) { decimalsOnSmallNumbers = 6; }
			if (value < 0.1 && value >= 0.01) { decimalsOnSmallNumbers = 7; }
		}
		if (symbol != '') { prefix = symbol + ' '; }
		if (value < 0) { valueSign = -1; }
		if (value == 0) { return prefix + '0'; }

		if (value < 0.00001000 && value >= 0.00000100 && decimalsOnSmallNumbers > 3) {
			decimalsOnSmallNumbers = 3;
		}
		if (value < 0.00000100 && value >= 0.00000010 && decimalsOnSmallNumbers > 2) {
			decimalsOnSmallNumbers = 2;
		}
		if (value < 0.00000010 && decimalsOnSmallNumbers > 1) {
			decimalsOnSmallNumbers = 1;
		}

		if (type == "short" || type == "8decimals") {
			if (valueAbs > 10000000000) {
				valueAbs = valueAbs / 1000000000;
				return prefix + filterNumberFunctionAngularJS(valueSign * valueAbs, decimalsOnBigNumbers) + ' B';
			}
			if (valueAbs > 10000000) {
				valueAbs = valueAbs / 1000000;
				return prefix + filterNumberFunctionAngularJS(valueSign * valueAbs, decimalsOnBigNumbers) + ' M';
			}
			if (valueAbs > 10000) {
				valueAbs = valueAbs / 1000;
				return prefix + filterNumberFunctionAngularJS(valueSign * valueAbs, decimalsOnBigNumbers) + ' K';
			}
			if (type == "8decimals" && valueAbs >= 100) {
				return prefix + filterNumberFunctionAngularJS(valueSign * valueAbs, decimalsOnBigNumbers);
			}
			if (valueAbs >= 1) {
				return prefix + filterNumberFunctionAngularJS(valueSign * valueAbs, decimalsOnNormalNumbers);
			}
			return prefix + (valueSign * valueAbs).toPrecision(decimalsOnSmallNumbers);
		} else {
			if (valueAbs >= 1) {
				return prefix + filterNumberFunctionAngularJS(valueSign * valueAbs, decimalsOnNormalNumbers);
			}

			return prefix + this.noExponents((valueSign * valueAbs).toPrecision(decimalsOnSmallNumbers));
		}
	}
};


CCC.TRADE = CCC.TRADE || {};
/*
trade fields binary values always in the last ~
*/

CCC.TRADE.FLAGS = {
	'SELL': 0x1 // hex for binary 1
	, 'BUY': 0x2 // hex for binary 10
	, 'UNKNOWN': 0x4 // hex for binary 100
}

CCC.TRADE.FIELDS = {
	'T': 0x0  // hex for binary 0, it is a special case of fields that are always there TYPE
	, 'M': 0x0  // hex for binary 0, it is a special case of fields that are always there MARKET
	, 'FSYM': 0x0  // hex for binary 0, it is a special case of fields that are always there FROM SYMBOL
	, 'TSYM': 0x0  // hex for binary 0, it is a special case of fields that are always there TO SYMBOL
	, 'F': 0x0  // hex for binary 0, it is a special case of fields that are always there FLAGS
	, 'ID': 0x1  // hex for binary 1                                                       ID
	, 'TS': 0x2  // hex for binary 10                                                      TIMESTAMP
	, 'Q': 0x4  // hex for binary 100                                                     QUANTITY
	, 'P': 0x8  // hex for binary 1000                                                    PRICE
	, 'TOTAL': 0x10 // hex for binary 10000                                                   TOTAL

};

CCC.TRADE.DISPLAY = CCC.TRADE.DISPLAY || {};
CCC.TRADE.DISPLAY.FIELDS = {
	'T': { "Show": false }
	, 'M': { "Show": true, 'Filter': 'Market' }
	, 'FSYM': { "Show": true, 'Filter': 'CurrencySymbol' }
	, 'TSYM': { "Show": true, 'Filter': 'CurrencySymbol' }
	, 'F': { "Show": true, 'Filter': 'TradeFlag' }
	, 'ID': { "Show": true, 'Filter': 'Text' }
	, 'TS': { 'Show': true, 'Filter': 'Date', 'Format': 'yyyy MMMM dd HH:mm:ss' }
	, 'Q': { 'Show': true, 'Filter': 'Number', 'Symbol': 'FSYM' }
	, 'P': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TSYM' }
	, 'TOTAL': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TSYM' }

};

CCC.TRADE.pack = function (tradeObject) {
	var mask = 0;
	var packedTrade = '';
	for (var field in tradeObject) {
		packedTrade += '~' + tradeObject[field];
		mask |= this.FIELDS[field];
	}
	return packedTrade.substr(1) + '~' + mask.toString(16);
};

CCC.TRADE.unpack = function (tradeString) {
	var valuesArray = tradeString.split("~");
	var valuesArrayLenght = valuesArray.length;
	var mask = valuesArray[valuesArrayLenght - 1];
	var maskInt = parseInt(mask, 16);
	var unpackedTrade = {};
	var currentField = 0;
	for (var property in this.FIELDS) {
		if (this.FIELDS[property] === 0) {
			unpackedTrade[property] = valuesArray[currentField];
			currentField++;
		}
		else if (maskInt & this.FIELDS[property]) {
			unpackedTrade[property] = valuesArray[currentField];
			currentField++;
		}
	}

	return unpackedTrade;
}

CCC.TRADE.getKey = function (tradeObject) {
	return tradeObject['T'] + '~' + tradeObject['M'] + '~' + tradeObject['FSYM'] + '~' + tradeObject['TSYM'];
};

CCC.CURRENT = CCC.CURRENT || {};
/*
current fields mask values always in the last ~
*/

CCC.CURRENT.FLAGS = {
	'PRICEUP': 0x1    // hex for binary 1
	, 'PRICEDOWN': 0x2    // hex for binary 10
	, 'PRICEUNCHANGED': 0x4    // hex for binary 100
	, 'BIDUP': 0x8    // hex for binary 1000
	, 'BIDDOWN': 0x10   // hex for binary 10000
	, 'BIDUNCHANGED': 0x20   // hex for binary 100000
	, 'OFFERUP': 0x40   // hex for binary 1000000
	, 'OFFERDOWN': 0x80   // hex for binary 10000000
	, 'OFFERUNCHANGED': 0x100  // hex for binary 100000000
	, 'AVGUP': 0x200  // hex for binary 1000000000
	, 'AVGDOWN': 0x400  // hex for binary 10000000000
	, 'AVGUNCHANGED': 0x800  // hex for binary 100000000000
};


CCC.CURRENT.FIELDS = {
	'TYPE': 0x0       // hex for binary 0, it is a special case of fields that are always there
	, 'MARKET': 0x0       // hex for binary 0, it is a special case of fields that are always there
	, 'FROMSYMBOL': 0x0       // hex for binary 0, it is a special case of fields that are always there
	, 'TOSYMBOL': 0x0       // hex for binary 0, it is a special case of fields that are always there
	, 'FLAGS': 0x0       // hex for binary 0, it is a special case of fields that are always there
	, 'PRICE': 0x1       // hex for binary 1
	, 'BID': 0x2       // hex for binary 10
	, 'OFFER': 0x4       // hex for binary 100
	, 'LASTUPDATE': 0x8       // hex for binary 1000
	, 'AVG': 0x10      // hex for binary 10000
	, 'LASTVOLUME': 0x20      // hex for binary 100000
	, 'LASTVOLUMETO': 0x40      // hex for binary 1000000
	, 'LASTTRADEID': 0x80      // hex for binary 10000000
	, 'VOLUMEHOUR': 0x100     // hex for binary 100000000
	, 'VOLUMEHOURTO': 0x200     // hex for binary 1000000000
	, 'VOLUME24HOUR': 0x400     // hex for binary 10000000000
	, 'VOLUME24HOURTO': 0x800     // hex for binary 100000000000
	, 'OPENHOUR': 0x1000    // hex for binary 1000000000000
	, 'HIGHHOUR': 0x2000    // hex for binary 10000000000000
	, 'LOWHOUR': 0x4000    // hex for binary 100000000000000
	, 'OPEN24HOUR': 0x8000    // hex for binary 1000000000000000
	, 'HIGH24HOUR': 0x10000   // hex for binary 10000000000000000
	, 'LOW24HOUR': 0x20000   // hex for binary 100000000000000000
	, 'LASTMARKET': 0x40000   // hex for binary 1000000000000000000, this is a special case and will only appear on CCCAGG messages
};

CCC.CURRENT.DISPLAY = CCC.CURRENT.DISPLAY || {};
CCC.CURRENT.DISPLAY.FIELDS = {
	'TYPE': { 'Show': false }
	, 'MARKET': { 'Show': true, 'Filter': 'Market' }
	, 'FROMSYMBOL': { 'Show': false }
	, 'TOSYMBOL': { 'Show': false }
	, 'FLAGS': { 'Show': false }
	, 'PRICE': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
	, 'BID': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
	, 'OFFER': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
	, 'LASTUPDATE': { 'Show': true, 'Filter': 'Date', 'Format': 'yyyy MMMM dd HH:mm:ss' }
	, 'AVG': { 'Show': true, ' Filter': 'Number', 'Symbol': 'TOSYMBOL' }
	, 'LASTVOLUME': { 'Show': true, 'Filter': 'Number', 'Symbol': 'FROMSYMBOL' }
	, 'LASTVOLUMETO': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
	, 'LASTTRADEID': { 'Show': true, 'Filter': 'String' }
	, 'VOLUMEHOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'FROMSYMBOL' }
	, 'VOLUMEHOURTO': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
	, 'VOLUME24HOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'FROMSYMBOL' }
	, 'VOLUME24HOURTO': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
	, 'OPENHOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
	, 'HIGHHOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
	, 'LOWHOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
	, 'OPEN24HOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
	, 'HIGH24HOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
	, 'LOW24HOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
	, 'LASTMARKET': { 'Show': true, 'Filter': 'String' }
};

CCC.CURRENT.pack = function (currentObject) {
	var mask = 0;
	var packedCurrent = '';
	for (var property in this.FIELDS) {
		if (currentObject.hasOwnProperty(property)) {
			packedCurrent += '~' + currentObject[property];
			mask |= this.FIELDS[property];
		}
	}
	//removing first character beacsue it is a ~
	return packedCurrent.substr(1) + '~' + mask.toString(16);
};

CCC.CURRENT.unpack = function (value) {
	var valuesArray = value.split("~");
	var valuesArrayLenght = valuesArray.length;
	var mask = valuesArray[valuesArrayLenght - 1];
	var maskInt = parseInt(mask, 16);
	var unpackedCurrent = {};
	var currentField = 0;
	for (var property in this.FIELDS) {
		if (this.FIELDS[property] === 0) {
			unpackedCurrent[property] = valuesArray[currentField];
			currentField++;
		}
		else if (maskInt & this.FIELDS[property]) {
			//i know this is a hack, for cccagg, future code please don't hate me:(, i did this to avoid
			//subscribing to trades as well in order to show the last market
			if (property === 'LASTMARKET') {
				unpackedCurrent[property] = valuesArray[currentField];
			} else {
				unpackedCurrent[property] = parseFloat(valuesArray[currentField]);
			}
			currentField++;
		}
	}

	return unpackedCurrent;
};
CCC.CURRENT.getKey = function (currentObject) {
	return currentObject['TYPE'] + '~' + currentObject['MARKET'] + '~' + currentObject['FROMSYMBOL'] + '~' + currentObject['TOSYMBOL'];
};
CCC.CURRENT.getKeyFromStreamerData = function (streamerData) {
	var valuesArray = streamerData.split("~");
	return valuesArray[0] + '~' + valuesArray[1] + '~' + valuesArray[2] + '~' + valuesArray[3];
};

CCC.noExponents = function (value) {
	var data = String(value).split(/[eE]/);
	if (data.length == 1) return data[0];

	var z = '', sign = value < 0 ? '-' : '',
		str = data[0].replace('.', ''),
		mag = Number(data[1]) + 1;

	if (mag < 0) {
		z = sign + '0.';
		while (mag++) z += '0';
		return z + str.replace(/^\-/, '');
	}
	mag -= str.length;
	while (mag--) z += '0';
	return str + z;
};

CCC.filterNumberFunctionPolyfill = function (value, decimals) {
	var decimalsDenominator = Math.pow(10, decimals);
	var numberWithCorrectDecimals = Math.round(value * decimalsDenominator) / decimalsDenominator;
	var parts = numberWithCorrectDecimals.toString().split(".");
	parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
	return parts.join(".");
}

CCC.convertValueToDisplay = function (symbol, value, type, fullNumbers) {
	var prefix = '';
	var valueSign = 1;
	value = parseFloat(value);
	var valueAbs = Math.abs(value);
	var decimalsOnBigNumbers = 2;
	var decimalsOnNormalNumbers = 2;
	var decimalsOnSmallNumbers = 4;
	if (fullNumbers === true) {
		decimalsOnBigNumbers = 2;
		decimalsOnNormalNumbers = 0;
		decimalsOnSmallNumbers = 4;
	}
	if (symbol != '') {
		prefix = symbol + ' ';
	}
	if (value < 0) {
		valueSign = -1;
	}

	if (value == 0) {
		return prefix + '0';
	}

	if (value < 0.00001000 && value >= 0.00000100 && decimalsOnSmallNumbers > 3) {
		decimalsOnSmallNumbers = 3;
	}
	if (value < 0.00000100 && value >= 0.00000010 && decimalsOnSmallNumbers > 2) {
		decimalsOnSmallNumbers = 2;
	}
	if (value < 0.00000010 && value >= 0.00000001 && decimalsOnSmallNumbers > 1) {
		decimalsOnSmallNumbers = 1;
	}

	if (type == "short") {
		if (valueAbs > 10000000000) {
			valueAbs = valueAbs / 1000000000;
			return prefix + CCC.filterNumberFunctionPolyfill(valueSign * valueAbs, decimalsOnBigNumbers) + ' B';
		}
		if (valueAbs > 10000000) {
			valueAbs = valueAbs / 1000000;
			return prefix + CCC.filterNumberFunctionPolyfill(valueSign * valueAbs, decimalsOnBigNumbers) + ' M';
		}
		if (valueAbs > 10000) {
			valueAbs = valueAbs / 1000;
			return prefix + CCC.filterNumberFunctionPolyfill(valueSign * valueAbs, decimalsOnBigNumbers) + ' K';
		}
		if (valueAbs >= 1) {
			return prefix + CCC.filterNumberFunctionPolyfill(valueSign * valueAbs, decimalsOnNormalNumbers);
		}
		return prefix + (valueSign * valueAbs).toPrecision(decimalsOnSmallNumbers);
	} else {
		if (valueAbs >= 1) {
			return prefix + CCC.filterNumberFunctionPolyfill(valueSign * valueAbs, decimalsOnNormalNumbers);
		}

		return prefix + CCC.noExponents((valueSign * valueAbs).toPrecision(decimalsOnSmallNumbers));
	}
};

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46569944

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档