<commit_before>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { ExchangeError, AuthenticationError, InvalidNonce, InsufficientFunds, OrderNotFound, DDoSProtection } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class bitz extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'bitz',
            'name': 'Bit-Z',
            'countries': 'HK',
            'rateLimit': 1000,
            'has': {
                'fetchTickers': true,
                'fetchOHLCV': true,
                'fetchOpenOrders': true,
            },
            'timeframes': {
                '1m': '1m',
                '5m': '5m',
                '15m': '15m',
                '30m': '30m',
                '1h': '1h',
                '1d': '1d',
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/35862606-4f554f14-0b5d-11e8-957d-35058c504b6f.jpg',
                'api': 'https://www.bit-z.com/api_v1',
                'www': 'https://www.bit-z.com/',
                'doc': 'https://www.bit-z.com/api.html',
                'fees': 'https://www.bit-z.com/about/fee',
            },
            'api': {
                'public': {
                    'get': [
                        'ticker',
                        'tickerall',
                        'depth',
                        'orders',
                        'kline',
                    ],
                },
                'private': {
                    'post': [
                        'tradeAdd',
                        'tradeCancel',
                        'openOrders',
                    ],
                },
            },
            'fees': {
                'trading': {
                    'maker': 0.001,
                    'taker': 0.001,
                },
                'funding': {
                    'withdraw': {
                        'BTC': '0.5%',
                        'DKKT': '0.5%',
                        'ETH': 0.01,
                        'USDT': '0.5%',
                        'LTC': '0.5%',
                        'FCT': '0.5%',
                        'LSK': '0.5%',
                        'HXI': '0.8%',
                        'ZEC': '0.5%',
                        'DOGE': '0.5%',
                        'MZC': '0.5%',
                        'ETC': '0.5%',
                        'GXS': '0.5%',
                        'XPM': '0.5%',
                        'PPC': '0.5%',
                        'BLK': '0.5%',
                        'XAS': '0.5%',
                        'HSR': '0.5%',
                        'NULS': 5.0,
                        'VOISE': 350.0,
                        'PAY': 1.5,
                        'EOS': 0.6,
                        'YBCT': 35.0,
                        'OMG': 0.3,
                        'OTN': 0.4,
                        'BTX': '0.5%',
                        'QTUM': '0.5%',
                        'DASH': '0.5%',
                        'GAME': '0.5%',
                        'BCH': '0.5%',
                        'GNT': 9.0,
                        'SSS': 1500.0,
                        'ARK': '0.5%',
                        'PART': '0.5%',
                        'LEO': '0.5%',
                        'DGB': '0.5%',
                        'ZSC': 130.0,
                        'VIU': 350.0,
                        'BTG': '0.5%',
                        'ARN': 10.0,
                        'VTC': '0.5%',
                        'BCD': '0.5%',
                        'TRX': 200.0,
                        'HWC': '0.5%',
                        'UNIT': '0.5%',
                        'OXY': '0.5%',
                        'MCO': 0.3500,
                        'SBTC': '0.5%',
                        'BCX': '0.5%',
                        'ETF': '0.5%',
                        'PYLNT': 0.4000,
                        'XRB': '0.5%',
                        'ETP': '0.5%',
                    },
                },
            },
            'precision': {
                'amount': 8,
                'price': 8,
            },
        });
    }

    async fetchMarkets () {
        let response = await this.publicGetTickerall ();
        let markets = response['data'];
        let ids = Object.keys (markets);
        let result = [];
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let market = markets[id];
            let idUpper = id.toUpperCase ();
            let [ base, quote ] = idUpper.split ('_');
            base = this.commonCurrencyCode (base);
            quote = this.commonCurrencyCode (quote);
            let symbol = base + '/' + quote;
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'active': true,
                'info': market,
            });
        }
        return result;
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = ticker['date'] * 1000;
        let symbol = market['symbol'];
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': parseFloat (ticker['high']),
            'low': parseFloat (ticker['low']),
            'bid': parseFloat (ticker['buy']),
            'ask': parseFloat (ticker['sell']),
            'vwap': undefined,
            'open': undefined,
            'close': undefined,
            'first': undefined,
            'last': parseFloat (ticker['last']),
            'change': undefined,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': parseFloat (ticker['vol']),
            'quoteVolume': undefined,
            'info': ticker,
        };
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetTicker (this.extend ({
            'coin': market['id'],
        }, params));
        return this.parseTicker (response['data'], market);
    }

    async fetchTickers (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let response = await this.publicGetTickerall (params);
        let tickers = response['data'];
        let result = {};
        let ids = Object.keys (tickers);
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let market = this.marketsById[id];
            let symbol = market['symbol'];
            result[symbol] = this.parseTicker (tickers[id], market);
        }
        return result;
    }

    async fetchOrderBook (symbol, params = {}) {
        await this.loadMarkets ();
        let response = await this.publicGetDepth (this.extend ({
            'coin': this.marketId (symbol),
        }, params));
        let orderbook = response['data'];
        let timestamp = orderbook['date'] * 1000;
        return this.parseOrderBook (orderbook, timestamp);
    }

    parseTrade (trade, market = undefined) {
        let hkt = this.sum (this.milliseconds (), 28800000);
        let utcDate = this.iso8601 (hkt);
        utcDate = utcDate.split ('T');
        utcDate = utcDate[0] + ' ' + trade['t'] + '+08';
        let timestamp = this.parse8601 (utcDate);
        let price = parseFloat (trade['p']);
        let amount = parseFloat (trade['n']);
        let symbol = market['symbol'];
        let cost = this.priceToPrecision (symbol, amount * price);
        return {
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': symbol,
            'id': undefined,
            'order': undefined,
            'type': 'limit',
            'side': trade['s'],
            'price': price,
            'amount': amount,
            'cost': cost,
            'fee': undefined,
            'info': trade,
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetOrders (this.extend ({
            'coin': market['id'],
        }, params));
        let trades = response['data']['d'];
        return this.parseTrades (trades, market, since, limit);
    }

    async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetKline (this.extend ({
            'coin': market['id'],
            'type': this.timeframes[timeframe],
        }, params));
        let ohlcv = this.unjson (response['data']['datas']['data']);
        return this.parseOHLCVs (ohlcv, market, timeframe, since, limit);
    }

    parseOrder (order, market) {
        let symbol = undefined;
        if (market)
            symbol = market['symbol'];
        return {
            'id': order['id'],
            'datetime': undefined,
            'timestamp': undefined,
            'status': 'open',
            'symbol': symbol,
            'type': 'limit',
            'side': order['type'],
            'price': order['price'],
            'cost': undefined,
            'amount': order['number'],
            'filled': undefined,
            'remaining': undefined,
            'trades': undefined,
            'fee': undefined,
            'info': order,
        };
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.privatePostTradeAdd (this.extend ({
            'coin': market['id'],
            'type': side,
            'price': this.priceToPrecision (symbol, price),
            'number': this.amountToPrecision (symbol, amount),
            'tradepwd': this.password,
        }, params));
        let order = {
            'id': response['data'],
            'price': price,
            'number': amount,
            'type': side,
        };
        let id = order['id'];
        this.orders[id] = this.parseOrder (order, market);
        return order;
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostTradeCancel (this.extend ({
            'id': id,
        }, params));
        return response;
    }

    async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.privatePostOpenOrders (this.extend ({
            'coin': market['id'],
        }, params));
        return this.parseOrders (response['data'], market);
    }

    nonce () {
        let milliseconds = this.milliseconds ();
        return (milliseconds % 1000000);
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'] + '/' + path;
        let query = undefined;
        if (api === 'public') {
            query = this.urlencode (params);
            if (query.length)
                url += '?' + query;
        } else {
            this.checkRequiredCredentials ();
            body = this.urlencode (this.keysort (this.extend ({
                'api_key': this.apiKey,
                'timestamp': this.seconds (),
                'nonce': this.nonce (),
            }, params)));
            body += '&sign=' + this.hash (this.encode (body + this.secret));
            headers = { 'Content-type': 'application/x-www-form-urlencoded' };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        let code = this.safeString (response, 'code');
        if (code !== '0') {
            let ErrorClass = this.safeValue ({
                '103': AuthenticationError,
                '104': AuthenticationError,
                '200': AuthenticationError,
                '202': AuthenticationError,
                '401': AuthenticationError,
                '406': AuthenticationError,
                '203': InvalidNonce,
                '201': OrderNotFound,
                '408': InsufficientFunds,
                '106': DDoSProtection,
            }, code, ExchangeError);
            let message = this.safeString (response, 'msg', 'Error');
            throw new ErrorClass (message);
        }
        return response;
    }
};
<commit_msg>updated fetchOrderBook signature for new limit argument in bitz #1126 #860<commit_after>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { ExchangeError, AuthenticationError, InvalidNonce, InsufficientFunds, OrderNotFound, DDoSProtection } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class bitz extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'bitz',
            'name': 'Bit-Z',
            'countries': 'HK',
            'rateLimit': 1000,
            'has': {
                'fetchTickers': true,
                'fetchOHLCV': true,
                'fetchOpenOrders': true,
            },
            'timeframes': {
                '1m': '1m',
                '5m': '5m',
                '15m': '15m',
                '30m': '30m',
                '1h': '1h',
                '1d': '1d',
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/35862606-4f554f14-0b5d-11e8-957d-35058c504b6f.jpg',
                'api': 'https://www.bit-z.com/api_v1',
                'www': 'https://www.bit-z.com/',
                'doc': 'https://www.bit-z.com/api.html',
                'fees': 'https://www.bit-z.com/about/fee',
            },
            'api': {
                'public': {
                    'get': [
                        'ticker',
                        'tickerall',
                        'depth',
                        'orders',
                        'kline',
                    ],
                },
                'private': {
                    'post': [
                        'tradeAdd',
                        'tradeCancel',
                        'openOrders',
                    ],
                },
            },
            'fees': {
                'trading': {
                    'maker': 0.001,
                    'taker': 0.001,
                },
                'funding': {
                    'withdraw': {
                        'BTC': '0.5%',
                        'DKKT': '0.5%',
                        'ETH': 0.01,
                        'USDT': '0.5%',
                        'LTC': '0.5%',
                        'FCT': '0.5%',
                        'LSK': '0.5%',
                        'HXI': '0.8%',
                        'ZEC': '0.5%',
                        'DOGE': '0.5%',
                        'MZC': '0.5%',
                        'ETC': '0.5%',
                        'GXS': '0.5%',
                        'XPM': '0.5%',
                        'PPC': '0.5%',
                        'BLK': '0.5%',
                        'XAS': '0.5%',
                        'HSR': '0.5%',
                        'NULS': 5.0,
                        'VOISE': 350.0,
                        'PAY': 1.5,
                        'EOS': 0.6,
                        'YBCT': 35.0,
                        'OMG': 0.3,
                        'OTN': 0.4,
                        'BTX': '0.5%',
                        'QTUM': '0.5%',
                        'DASH': '0.5%',
                        'GAME': '0.5%',
                        'BCH': '0.5%',
                        'GNT': 9.0,
                        'SSS': 1500.0,
                        'ARK': '0.5%',
                        'PART': '0.5%',
                        'LEO': '0.5%',
                        'DGB': '0.5%',
                        'ZSC': 130.0,
                        'VIU': 350.0,
                        'BTG': '0.5%',
                        'ARN': 10.0,
                        'VTC': '0.5%',
                        'BCD': '0.5%',
                        'TRX': 200.0,
                        'HWC': '0.5%',
                        'UNIT': '0.5%',
                        'OXY': '0.5%',
                        'MCO': 0.3500,
                        'SBTC': '0.5%',
                        'BCX': '0.5%',
                        'ETF': '0.5%',
                        'PYLNT': 0.4000,
                        'XRB': '0.5%',
                        'ETP': '0.5%',
                    },
                },
            },
            'precision': {
                'amount': 8,
                'price': 8,
            },
        });
    }

    async fetchMarkets () {
        let response = await this.publicGetTickerall ();
        let markets = response['data'];
        let ids = Object.keys (markets);
        let result = [];
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let market = markets[id];
            let idUpper = id.toUpperCase ();
            let [ base, quote ] = idUpper.split ('_');
            base = this.commonCurrencyCode (base);
            quote = this.commonCurrencyCode (quote);
            let symbol = base + '/' + quote;
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'active': true,
                'info': market,
            });
        }
        return result;
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = ticker['date'] * 1000;
        let symbol = market['symbol'];
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': parseFloat (ticker['high']),
            'low': parseFloat (ticker['low']),
            'bid': parseFloat (ticker['buy']),
            'ask': parseFloat (ticker['sell']),
            'vwap': undefined,
            'open': undefined,
            'close': undefined,
            'first': undefined,
            'last': parseFloat (ticker['last']),
            'change': undefined,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': parseFloat (ticker['vol']),
            'quoteVolume': undefined,
            'info': ticker,
        };
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetTicker (this.extend ({
            'coin': market['id'],
        }, params));
        return this.parseTicker (response['data'], market);
    }

    async fetchTickers (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let response = await this.publicGetTickerall (params);
        let tickers = response['data'];
        let result = {};
        let ids = Object.keys (tickers);
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let market = this.marketsById[id];
            let symbol = market['symbol'];
            result[symbol] = this.parseTicker (tickers[id], market);
        }
        return result;
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let response = await this.publicGetDepth (this.extend ({
            'coin': this.marketId (symbol),
        }, params));
        let orderbook = response['data'];
        let timestamp = orderbook['date'] * 1000;
        return this.parseOrderBook (orderbook, timestamp);
    }

    parseTrade (trade, market = undefined) {
        let hkt = this.sum (this.milliseconds (), 28800000);
        let utcDate = this.iso8601 (hkt);
        utcDate = utcDate.split ('T');
        utcDate = utcDate[0] + ' ' + trade['t'] + '+08';
        let timestamp = this.parse8601 (utcDate);
        let price = parseFloat (trade['p']);
        let amount = parseFloat (trade['n']);
        let symbol = market['symbol'];
        let cost = this.priceToPrecision (symbol, amount * price);
        return {
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': symbol,
            'id': undefined,
            'order': undefined,
            'type': 'limit',
            'side': trade['s'],
            'price': price,
            'amount': amount,
            'cost': cost,
            'fee': undefined,
            'info': trade,
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetOrders (this.extend ({
            'coin': market['id'],
        }, params));
        let trades = response['data']['d'];
        return this.parseTrades (trades, market, since, limit);
    }

    async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetKline (this.extend ({
            'coin': market['id'],
            'type': this.timeframes[timeframe],
        }, params));
        let ohlcv = this.unjson (response['data']['datas']['data']);
        return this.parseOHLCVs (ohlcv, market, timeframe, since, limit);
    }

    parseOrder (order, market) {
        let symbol = undefined;
        if (market)
            symbol = market['symbol'];
        return {
            'id': order['id'],
            'datetime': undefined,
            'timestamp': undefined,
            'status': 'open',
            'symbol': symbol,
            'type': 'limit',
            'side': order['type'],
            'price': order['price'],
            'cost': undefined,
            'amount': order['number'],
            'filled': undefined,
            'remaining': undefined,
            'trades': undefined,
            'fee': undefined,
            'info': order,
        };
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.privatePostTradeAdd (this.extend ({
            'coin': market['id'],
            'type': side,
            'price': this.priceToPrecision (symbol, price),
            'number': this.amountToPrecision (symbol, amount),
            'tradepwd': this.password,
        }, params));
        let order = {
            'id': response['data'],
            'price': price,
            'number': amount,
            'type': side,
        };
        let id = order['id'];
        this.orders[id] = this.parseOrder (order, market);
        return order;
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostTradeCancel (this.extend ({
            'id': id,
        }, params));
        return response;
    }

    async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.privatePostOpenOrders (this.extend ({
            'coin': market['id'],
        }, params));
        return this.parseOrders (response['data'], market);
    }

    nonce () {
        let milliseconds = this.milliseconds ();
        return (milliseconds % 1000000);
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'] + '/' + path;
        let query = undefined;
        if (api === 'public') {
            query = this.urlencode (params);
            if (query.length)
                url += '?' + query;
        } else {
            this.checkRequiredCredentials ();
            body = this.urlencode (this.keysort (this.extend ({
                'api_key': this.apiKey,
                'timestamp': this.seconds (),
                'nonce': this.nonce (),
            }, params)));
            body += '&sign=' + this.hash (this.encode (body + this.secret));
            headers = { 'Content-type': 'application/x-www-form-urlencoded' };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        let code = this.safeString (response, 'code');
        if (code !== '0') {
            let ErrorClass = this.safeValue ({
                '103': AuthenticationError,
                '104': AuthenticationError,
                '200': AuthenticationError,
                '202': AuthenticationError,
                '401': AuthenticationError,
                '406': AuthenticationError,
                '203': InvalidNonce,
                '201': OrderNotFound,
                '408': InsufficientFunds,
                '106': DDoSProtection,
            }, code, ExchangeError);
            let message = this.safeString (response, 'msg', 'Error');
            throw new ErrorClass (message);
        }
        return response;
    }
};
<|endoftext|>


<commit_before>import React from 'react';
import {Decorator as Cerebral} from 'cerebral-react';
import Title from './components/Title';

@Cerebral({
  title: ['title'],
  color: ['color']
})
class App extends React.Component {
  render() {
    return (

        <Title color={this.props.color}>{this.props.title}</Title>
        <button onClick={() => this.props.signals.colorChanged({color: 'red'})}>Red</button>
        {' | '}
        <button onClick={() => this.props.signals.colorChanged({color: 'blue'})}>Blue</button>

    );
  }
}

export default App;
<commit_msg>use Link from cerebral-react<commit_after>import React from 'react';
import {Decorator as Cerebral, Link} from 'cerebral-react';
import Title from './components/Title';

@Cerebral({
  title: ['title'],
  color: ['color']
})
class App extends React.Component {
  render() {
    return (

        <Title color={this.props.color}>{this.props.title}</Title>
        <Link signal="colorChanged" params={{color: 'red'}}>Red</Link>
        {' | '}
        <Link signal="colorChanged" params={{color: 'blue'}}>Blue</Link>

    );
  }
}

export default App;
<|endoftext|>


<commit_before>// creates array of matches
// _.flatten(d3.values(data).map(function(d){ return d3.values(d); }))

var height = 500,
		width = 750,
		margin = {left: 20, right: 20, top: 20, bottom: 20};

var x = d3.scale.linear()
		.domain([0, 18])
		.range([0, width])

var y = d3.scale.linear()
		.domain([-9, 9])
		.range([height, 0])

var xAxis = d3.svg.axis()
    .scale(x)
    .ticks(18)

var xTick = x(1),
		yTick = y(8);

var radiusScale = d3.scale.sqrt()
		.range([0, 10])

var lineWidthScale = d3.scale.linear()
		.range([0, 1, 8])

var color = d3.scale.category10()
		.range(['#ec3221', '#01863e', '#1c4695'])

var svg = d3.select('#golf-wl')
  .append('svg')
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")")

svg.append('g')
		.attr('transform', 'translate(0,' + height + ')')
		.attr('class', 'x axis')
		.call(xAxis)
	.append('text')
		.attr('transform', 'translate(' + width/2 + ',0)')
		.text('Hole')
		.style('text-anchor', 'middle')

var holeConstrains = {},
		rounds = [],
		directions = ['down', 'same', 'up'],
		roundHash = {},
		matches,
		selectedMatches = [];

//load state from url
window.location.hash.substr(1).split(',').forEach(function(d){
		if (!d) return
    holeConstrains[d.split(':')[0]] = d.split(':')[1].split('_')
  		.map(function(d){ return +d; })
})

d3.range(0, 19).forEach(function(hole){
	d3.range(-9, 10).forEach(function(spread){
		if (10 - Math.abs(10 - hole) >= Math.abs(spread)){
			var round = {hole: hole, spread: spread};
			rounds.push(round);
			roundHash[hole + ':' + spread] = round;
		}
	})
})

var roundGs = svg.selectAll('.roundG')
		.data(rounds).enter()
	.append('g')
		.attr('transform', function(d){
			return ['translate(', x(d.hole), ',', y(d.spread), ')'].join(''); })

d3.json('flat-data.json', function(err, data){
	matches = data;
	//winner of the first match always on top -  do server side
	matches.forEach(function(match){
		var flip = false;
		match.scores.some(function(d){
			if (d < 0){ flip = true}
			return d != 0;
		})
		if (flip){
			match.oldScore = match.scores.slice();
			match.scores = match.scores.map(function(d){ return d === null ? null : -1*d; })
		}
	})

	function updateData(){
		rounds.forEach(function(d){
			directions.concat('count').forEach(function(str){ d[str] = 0 }) })
		selectedMatches = [];

		var holeConstrainsArray = d3.entries(holeConstrains);

		matches.forEach(function(match){
			//don't count matches that don't meet constraints
			var meetsConstraints = holeConstrainsArray.every(function(d){
				return _.contains(d.value, match.scores[d.key])
			})
			if (!meetsConstraints) return
			selectedMatches.push(match)

			match.scores.forEach(function(spread, hole){
				var round = roundHash[hole + ':' + spread]
				if (!round) return;
				round.count++;
				var nextSpread = match.scores[hole+1];
				if (nextSpread === null) return
				round[nextSpread < spread ? 'down' : nextSpread == spread ? 'same' : 'up']++;
			})
		})
	}
	updateData();

	function updateScales(){
		radiusScale.domain(d3.extent(rounds, f('count')))
		var maxLineVals = directions.map(function(str){ return d3.max(rounds, ƒ(str)) })
		lineWidthScale.domain([0, 1, d3.max(maxLineVals)])
	}
	updateScales();

	function firstDraw(){
		roundGs.selectAll('line')
				.data(function(d){
					return directions.map(function(str, i){
						return {type: str, direction: i - 1}
					}) })
				.enter()
			.append('line')
				.attr({x2: xTick})
				.attr('y2', function(d){ return d.direction*(-yTick)})
				.style('stroke', _.compose(color, f('type')))

		roundGs.append('circle')

		roundGs.append('rect')
				.attr({x: -xTick/2, y: -yTick/2, width: xTick, height: yTick})
				.on('mouseover', function(d){
					d3.select(this).classed('hovered', true)
					console.log(d.hole, d.spread, d.count)
				})
				.on('mouseout', function(d){
					d3.select(this).classed('hovered', false)
				})
				.on('click', function(d){
					var selected = !d3.select(this).classed('selected')
					d3.select(this).classed('selected', selected)
					if (selected){
						if (holeConstrains[d.hole]){
							holeConstrains[d.hole].push(d.spread);
						} else{
							holeConstrains[d.hole] = [d.spread];
						}
					} else{
						holeConstrains[d.hole] = holeConstrains[d.hole]
							.filter(function(spread){ return spread != d.spread; })

						if (!holeConstrains[d.hole].length){
							delete holeConstrains[d.hole];
						}
					}

					//update url
					var hash = '';
					d3.entries(holeConstrains).forEach(function(d){
						hash += [d.key, ':', d.value.join('_'), ','].join('');
					})
					window.location.hash = hash.substr(0, hash.length - 1);

					updateData();
					updateScales();
					updateDOM(d.hole, d.spread, 50, 300);
				})
				.classed('selected', function(d){
					return holeConstrains[d.hole] && _.contains(holeConstrains[d.hole], d.spread);
				})
	}
	firstDraw();

	function updateDOM(hole, spread, delayTime, duration){
		roundGs.selectAll('line')
				.data(function(d){
					return directions.map(function(str, i){
						return {type: str, count: d[str], direction: i - 1, hole: d.hole, spread: d.spread}
					})
				})
			.transition().delay(delayFn).duration(duration)
				.style('stroke-width', _.compose(lineWidthScale, f('count')))

		roundGs.select('circle')
			.transition().delay(delayFn).duration(duration)
				.attr('r', _.compose(radiusScale, f('count')))

		function delayFn(d){
			return (Math.abs(hole - d.hole) + Math.abs(spread - d.spread))*delayTime ;
		}
	}
	updateDOM(0, 0, 0, 0);
})<commit_msg>fixes inccorect ending matches<commit_after>// creates array of matches
// _.flatten(d3.values(data).map(function(d){ return d3.values(d); }))

var height = 500,
		width = 750,
		margin = {left: 20, right: 20, top: 20, bottom: 20};

var x = d3.scale.linear()
		.domain([0, 18])
		.range([0, width])

var y = d3.scale.linear()
		.domain([-9, 9])
		.range([height, 0])

var xAxis = d3.svg.axis()
    .scale(x)
    .ticks(18)

var xTick = x(1),
		yTick = y(8);

var radiusScale = d3.scale.sqrt()
		.range([0, 10])

var lineWidthScale = d3.scale.linear()
		.range([0, 1, 8])

var color = d3.scale.category10()
		.range(['#ec3221', '#01863e', '#1c4695'])

var svg = d3.select('#golf-wl')
  .append('svg')
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")")

svg.append('g')
		.attr('transform', 'translate(0,' + height + ')')
		.attr('class', 'x axis')
		.call(xAxis)
	.append('text')
		.attr('transform', 'translate(' + width/2 + ',0)')
		.text('Hole')
		.style('text-anchor', 'middle')

var holeConstrains = {},
		rounds = [],
		directions = ['down', 'same', 'up'],
		roundHash = {},
		matches,
		selectedMatches = [];

//load state from url
window.location.hash.substr(1).split(',').forEach(function(d){
		if (!d) return
    holeConstrains[d.split(':')[0]] = d.split(':')[1].split('_')
  		.map(function(d){ return +d; })
})

d3.range(0, 19).forEach(function(hole){
	d3.range(-9, 10).forEach(function(spread){
		if (10 - Math.abs(10 - hole) >= Math.abs(spread)){
			var round = {hole: hole, spread: spread};
			rounds.push(round);
			roundHash[hole + ':' + spread] = round;
		}
	})
})

var roundGs = svg.selectAll('.roundG')
		.data(rounds).enter()
	.append('g')
		.attr('transform', function(d){
			return ['translate(', x(d.hole), ',', y(d.spread), ')'].join(''); })

d3.json('flat-data.json', function(err, data){
	matches = data;
	//winner of the first match always on top -  do server side
	matches.forEach(function(match){
		var flip = false;
		match.scores.some(function(d){
			if (d < 0){ flip = true}
			return d != 0;
		})
		if (flip){
			match.oldScore = match.scores.slice();
			match.scores = match.scores.map(function(d){ return d === null ? null : -1*d; })
		}
	})

	function updateData(){
		rounds.forEach(function(d){
			directions.concat('count').forEach(function(str){ d[str] = 0 }) })
		selectedMatches = [];

		var holeConstrainsArray = d3.entries(holeConstrains);

		matches.forEach(function(match){
			//don't count matches that don't meet constraints
			var meetsConstraints = holeConstrainsArray.every(function(d){
				return _.contains(d.value, match.scores[d.key])
			})
			if (!meetsConstraints) return
			selectedMatches.push(match)

			match.scores.forEach(function(spread, hole){
				var round = roundHash[hole + ':' + spread]
				if (!round) return;
				round.count++;
				var nextSpread = match.scores[hole+1];
				if (nextSpread == null) return
				round[nextSpread < spread ? 'down' : nextSpread == spread ? 'same' : 'up']++;
			})
		})
	}
	updateData();

	function updateScales(){
		radiusScale.domain(d3.extent(rounds, f('count')))
		var maxLineVals = directions.map(function(str){ return d3.max(rounds, ƒ(str)) })
		lineWidthScale.domain([0, 1, d3.max(maxLineVals)])
	}
	updateScales();

	function firstDraw(){
		roundGs.selectAll('line')
				.data(function(d){
					return directions.map(function(str, i){
						return {type: str, direction: i - 1}
					}) })
				.enter()
			.append('line')
				.attr({x2: xTick})
				.attr('y2', function(d){ return d.direction*(-yTick)})
				.style('stroke', _.compose(color, f('type')))

		roundGs.append('circle')

		roundGs.append('rect')
				.attr({x: -xTick/2, y: -yTick/2, width: xTick, height: yTick})
				.on('mouseover', function(d){
					d3.select(this).classed('hovered', true)
					console.log(d.hole, d.spread, d.count)
				})
				.on('mouseout', function(d){
					d3.select(this).classed('hovered', false)
				})
				.on('click', function(d){
					var selected = !d3.select(this).classed('selected')
					d3.select(this).classed('selected', selected)
					if (selected){
						if (holeConstrains[d.hole]){
							holeConstrains[d.hole].push(d.spread);
						} else{
							holeConstrains[d.hole] = [d.spread];
						}
					} else{
						holeConstrains[d.hole] = holeConstrains[d.hole]
							.filter(function(spread){ return spread != d.spread; })

						if (!holeConstrains[d.hole].length){
							delete holeConstrains[d.hole];
						}
					}

					//update url
					var hash = '';
					d3.entries(holeConstrains).forEach(function(d){
						hash += [d.key, ':', d.value.join('_'), ','].join('');
					})
					window.location.hash = hash.substr(0, hash.length - 1);

					updateData();
					updateScales();
					updateDOM(d.hole, d.spread, 50, 300);
				})
				.classed('selected', function(d){
					return holeConstrains[d.hole] && _.contains(holeConstrains[d.hole], d.spread);
				})
	}
	firstDraw();

	function updateDOM(hole, spread, delayTime, duration){
		roundGs.selectAll('line')
				.data(function(d){
					return directions.map(function(str, i){
						return {type: str, count: d[str], direction: i - 1, hole: d.hole, spread: d.spread}
					})
				})
			.transition().delay(delayFn).duration(duration)
				.style('stroke-width', _.compose(lineWidthScale, f('count')))

		roundGs.select('circle')
			.transition().delay(delayFn).duration(duration)
				.attr('r', _.compose(radiusScale, f('count')))

		function delayFn(d){
			return (Math.abs(hole - d.hole) + Math.abs(spread - d.spread))*delayTime ;
		}
	}
	updateDOM(0, 0, 0, 0);
})<|endoftext|>


<commit_before>'use strict';

var isArguments = require('../../function/is-arguments')
  , toPosInt    = require('../../number/to-pos-integer')
  , callable    = require('../../object/valid-callable')
  , validValue  = require('../../object/valid-value')
  , isString    = require('../../string/is-string')

  , isArray = Array.isArray, call = Function.prototype.call;

module.exports = function (arrayLike/*, mapFn, thisArg*/) {
	var mapFn = arguments[1], thisArg = arguments[2], Constructor, i, arr, l, char, code, iterator
	  , result;

	arrayLike = Object(validValue(arrayLike));

	if (!this || !Array.isPrototypeOf(this)) Constructor = Array;
	else Constructor = this;
	if (mapFn != null) callable(mapFn);

	if (!isArray(arrayLike)) {
		if (isString(arrayLike)) {
			l = arrayLike.length;
			arr = new Constructor();
			for (i = 0; i < l; ++i) {
				char = arrayLike[i];
				if ((i + 1) < l) {
					code = char.charCodeAt(0);
					if ((code >= 0xD800) && (code <= 0xDBFF)) char += arrayLike[++i];
				}
				arr.push(mapFn ? call.call(mapFn, thisArg, char, i) : char);
			}
			return arr;
		}
		if ((typeof arrayLike['@@iterator'] === 'function')) {
			arr = new Constructor();
			iterator = arrayLike['@@iterator']();
			result = iterator.next();
			i = 0;
			while (!result.done) {
				arr[i] = mapFn ? call.call(mapFn, thisArg, result.value, i) : result.value;
				result = iterator.next();
				++i;
			}
			return arr;
		}
	}

	l = toPosInt(arrayLike.length);
	if (mapFn != null) {
		arr = new Constructor(l);
		for (i = 0; i < l; ++i) arr[i] = call.call(mapFn, thisArg, arrayLike[i], i);
		return arr;
	}

	if (isArguments(arrayLike)) {
		if (l !== 1) return Constructor.apply(null, arrayLike);
		arr = new Constructor(1);
		arr[0] = arrayLike[0];
		return arr;
	}

	arr = new Constructor(l);
	for (i = 0; i < l; ++i) arr[i] = arrayLike[i];
	return arr;
};
<commit_msg>Improve iterators handling in Array.from<commit_after>'use strict';

var iteratorSymbol = require('es6-symbol').iterator
  , isArguments    = require('../../function/is-arguments')
  , toPosInt       = require('../../number/to-pos-integer')
  , callable       = require('../../object/valid-callable')
  , validValue     = require('../../object/valid-value')
  , isString       = require('../../string/is-string')

  , isArray = Array.isArray, call = Function.prototype.call;

module.exports = function (arrayLike/*, mapFn, thisArg*/) {
	var mapFn = arguments[1], thisArg = arguments[2], Constructor, i, arr, l, char, code, iterator
	  , result, getIterator;

	arrayLike = Object(validValue(arrayLike));

	if (!this || !Array.isPrototypeOf(this)) Constructor = Array;
	else Constructor = this;
	if (mapFn != null) callable(mapFn);

	if (!isArray(arrayLike)) {
		if (isString(arrayLike)) {
			l = arrayLike.length;
			arr = new Constructor();
			for (i = 0; i < l; ++i) {
				char = arrayLike[i];
				if ((i + 1) < l) {
					code = char.charCodeAt(0);
					if ((code >= 0xD800) && (code <= 0xDBFF)) char += arrayLike[++i];
				}
				arr.push(mapFn ? call.call(mapFn, thisArg, char, i) : char);
			}
			return arr;
		}
		if ((getIterator = arrayLike[iteratorSymbol]) !== undefined) {
			arr = new Constructor();
			iterator = callable(getIterator).call(arrayLike);
			result = iterator.next();
			i = 0;
			while (!result.done) {
				arr[i] = mapFn ? call.call(mapFn, thisArg, result.value, i) : result.value;
				result = iterator.next();
				++i;
			}
			return arr;
		}
	}

	l = toPosInt(arrayLike.length);
	if (mapFn != null) {
		arr = new Constructor(l);
		for (i = 0; i < l; ++i) arr[i] = call.call(mapFn, thisArg, arrayLike[i], i);
		return arr;
	}

	if (isArguments(arrayLike)) {
		if (l !== 1) return Constructor.apply(null, arrayLike);
		arr = new Constructor(1);
		arr[0] = arrayLike[0];
		return arr;
	}

	arr = new Constructor(l);
	for (i = 0; i < l; ++i) arr[i] = arrayLike[i];
	return arr;
};
<|endoftext|>


<commit_before>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { ExchangeError } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class ccex extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'ccex',
            'name': 'C-CEX',
            'countries': [ 'DE', 'EU' ],
            'rateLimit': 1500,
            'has': {
                'CORS': false,
                'fetchTickers': true,
                'fetchOrderBooks': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/27766433-16881f90-5ed8-11e7-92f8-3d92cc747a6c.jpg',
                'api': {
                    'web': 'https://c-cex.com/t',
                    'public': 'https://c-cex.com/t/api_pub.html',
                    'private': 'https://c-cex.com/t/api.html',
                },
                'www': 'https://c-cex.com',
                'doc': 'https://c-cex.com/?id=api',
            },
            'api': {
                'web': {
                    'get': [
                        'coinnames',
                        '{market}',
                        'pairs',
                        'prices',
                        'volume_{coin}',
                    ],
                },
                'public': {
                    'get': [
                        'balancedistribution',
                        'markethistory',
                        'markets',
                        'marketsummaries',
                        'orderbook',
                        'fullorderbook',
                    ],
                },
                'private': {
                    'get': [
                        'buylimit',
                        'cancel',
                        'getbalance',
                        'getbalances',
                        'getopenorders',
                        'getorder',
                        'getorderhistory',
                        'mytrades',
                        'selllimit',
                    ],
                },
            },
            'fees': {
                'trading': {
                    'taker': 0.2 / 100,
                    'maker': 0.2 / 100,
                },
            },
            'commonCurrencies': {
                'IOT': 'IoTcoin',
                'BLC': 'Cryptobullcoin',
                'XID': 'InternationalDiamond',
            },
        });
    }

    async fetchMarkets () {
        let result = {};
        let response = await this.webGetPairs ();
        let markets = response['pairs'];
        for (let i = 0; i < markets.length; i++) {
            let id = markets[i];
            let [ baseId, quoteId ] = id.split ('-');
            let base = baseId.toUpperCase ();
            let quote = quoteId.toUpperCase ();
            base = this.commonCurrencyCode (base);
            quote = this.commonCurrencyCode (quote);
            let symbol = base + '/' + quote;
            result[symbol] = {
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'baseId': baseId,
                'quoteId': quoteId,
                'info': id,
            };
        }
        // an alternative documented parser
        //     let markets = await this.publicGetMarkets ();
        //     for (let p = 0; p < markets['result'].length; p++) {
        //         let market = markets['result'][p];
        //         let id = market['MarketName'];
        //         let base = market['MarketCurrency'];
        //         let quote = market['BaseCurrency'];
        //         base = this.commonCurrencyCode (base);
        //         quote = this.commonCurrencyCode (quote);
        //         let symbol = base + '/' + quote;
        //         result.push ({
        //             'id': id,
        //             'symbol': symbol,
        //             'base': base,
        //             'quote': quote,
        //             'info': market,
        //         });
        //     }
        return result;
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let response = await this.privateGetGetbalances ();
        let balances = response['result'];
        let result = { 'info': balances };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let code = balance['Currency'];
            let currency = this.commonCurrencyCode (code);
            let account = {
                'free': balance['Available'],
                'used': balance['Pending'],
                'total': balance['Balance'],
            };
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let request = {
            'market': this.marketId (symbol),
            'type': 'both',
        };
        if (typeof limit !== 'undefined')
            request['depth'] = limit; // 100
        let response = await this.publicGetOrderbook (this.extend (request, params));
        let orderbook = response['result'];
        return this.parseOrderBook (orderbook, undefined, 'buy', 'sell', 'Rate', 'Quantity');
    }

    async fetchOrderBooks (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let orderbooks = {};
        let response = await this.publicGetFullorderbook ();
        let types = Object.keys (response['result']);
        for (let i = 0; i < types.length; i++) {
            let type = types[i];
            let bidasks = response['result'][type];
            let bidasksByMarketId = this.groupBy (bidasks, 'Market');
            let marketIds = Object.keys (bidasksByMarketId);
            for (let j = 0; j < marketIds.length; j++) {
                let marketId = marketIds[j];
                let symbol = marketId.toUpperCase ();
                let side = type;
                if (symbol in this.markets_by_id) {
                    let market = this.markets_by_id[symbol];
                    symbol = market['symbol'];
                } else {
                    let [ base, quote ] = symbol.split ('-');
                    let invertedId = quote + '-' + base;
                    if (invertedId in this.markets_by_id) {
                        let market = this.markets_by_id[invertedId];
                        symbol = market['symbol'];
                    }
                }
                if (!(symbol in orderbooks))
                    orderbooks[symbol] = {};
                orderbooks[symbol][side] = bidasksByMarketId[marketId];
            }
        }
        let result = {};
        let keys = Object.keys (orderbooks);
        for (let k = 0; k < keys.length; k++) {
            let key = keys[k];
            result[key] = this.parseOrderBook (orderbooks[key], undefined, 'buy', 'sell', 'Rate', 'Quantity');
        }
        return result;
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = ticker['updated'] * 1000;
        let symbol = undefined;
        if (market)
            symbol = market['symbol'];
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': parseFloat (ticker['high']),
            'low': parseFloat (ticker['low']),
            'bid': parseFloat (ticker['buy']),
            'bidVolume': undefined,
            'ask': parseFloat (ticker['sell']),
            'askVolume': undefined,
            'vwap': undefined,
            'open': undefined,
            'close': undefined,
            'first': undefined,
            'last': parseFloat (ticker['lastprice']),
            'previousClose': undefined,
            'change': undefined,
            'percentage': undefined,
            'average': parseFloat (ticker['avg']),
            'baseVolume': undefined,
            'quoteVolume': this.safeFloat (ticker, 'buysupport'),
            'info': ticker,
        };
    }

    async fetchTickers (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let tickers = await this.webGetPrices (params);
        let result = { 'info': tickers };
        let ids = Object.keys (tickers);
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let ticker = tickers[id];
            let uppercase = id.toUpperCase ();
            let market = undefined;
            let symbol = undefined;
            if (uppercase in this.markets_by_id) {
                market = this.markets_by_id[uppercase];
                symbol = market['symbol'];
            } else {
                let [ base, quote ] = uppercase.split ('-');
                base = this.commonCurrencyCode (base);
                quote = this.commonCurrencyCode (quote);
                symbol = base + '/' + quote;
            }
            result[symbol] = this.parseTicker (ticker, market);
        }
        return result;
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.webGetMarket (this.extend ({
            'market': market['id'].toLowerCase (),
        }, params));
        let ticker = response['ticker'];
        return this.parseTicker (ticker, market);
    }

    parseTrade (trade, market) {
        let timestamp = this.parse8601 (trade['TimeStamp']);
        return {
            'id': trade['Id'].toString (),
            'info': trade,
            'order': undefined,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': undefined,
            'side': trade['OrderType'].toLowerCase (),
            'price': trade['Price'],
            'amount': trade['Quantity'],
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetMarkethistory (this.extend ({
            'market': market['id'],
            'type': 'both',
            'depth': 100,
        }, params));
        return this.parseTrades (response['result'], market, since, limit);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let method = 'privateGet' + this.capitalize (side) + type;
        let response = await this[method] (this.extend ({
            'market': this.marketId (symbol),
            'quantity': amount,
            'rate': price,
        }, params));
        return {
            'info': response,
            'id': response['result']['uuid'],
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        return await this.privateGetCancel ({ 'uuid': id });
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'][api];
        if (api === 'private') {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ().toString ();
            let query = this.keysort (this.extend ({
                'a': path,
                'apikey': this.apiKey,
                'nonce': nonce,
            }, params));
            url += '?' + this.urlencode (query);
            headers = { 'apisign': this.hmac (this.encode (url), this.encode (this.secret), 'sha512') };
        } else if (api === 'public') {
            url += '?' + this.urlencode (this.extend ({
                'a': 'get' + path,
            }, params));
        } else {
            url += '/' + this.implodeParams (path, params) + '.json';
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if (api === 'web')
            return response;
        if ('success' in response)
            if (response['success'])
                return response;
        throw new ExchangeError (this.id + ' ' + this.json (response));
    }
};
<commit_msg>ccex fetchTicker consistency<commit_after>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { ExchangeError } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class ccex extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'ccex',
            'name': 'C-CEX',
            'countries': [ 'DE', 'EU' ],
            'rateLimit': 1500,
            'has': {
                'CORS': false,
                'fetchTickers': true,
                'fetchOrderBooks': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/27766433-16881f90-5ed8-11e7-92f8-3d92cc747a6c.jpg',
                'api': {
                    'web': 'https://c-cex.com/t',
                    'public': 'https://c-cex.com/t/api_pub.html',
                    'private': 'https://c-cex.com/t/api.html',
                },
                'www': 'https://c-cex.com',
                'doc': 'https://c-cex.com/?id=api',
            },
            'api': {
                'web': {
                    'get': [
                        'coinnames',
                        '{market}',
                        'pairs',
                        'prices',
                        'volume_{coin}',
                    ],
                },
                'public': {
                    'get': [
                        'balancedistribution',
                        'markethistory',
                        'markets',
                        'marketsummaries',
                        'orderbook',
                        'fullorderbook',
                    ],
                },
                'private': {
                    'get': [
                        'buylimit',
                        'cancel',
                        'getbalance',
                        'getbalances',
                        'getopenorders',
                        'getorder',
                        'getorderhistory',
                        'mytrades',
                        'selllimit',
                    ],
                },
            },
            'fees': {
                'trading': {
                    'taker': 0.2 / 100,
                    'maker': 0.2 / 100,
                },
            },
            'commonCurrencies': {
                'IOT': 'IoTcoin',
                'BLC': 'Cryptobullcoin',
                'XID': 'InternationalDiamond',
            },
        });
    }

    async fetchMarkets () {
        let result = {};
        let response = await this.webGetPairs ();
        let markets = response['pairs'];
        for (let i = 0; i < markets.length; i++) {
            let id = markets[i];
            let [ baseId, quoteId ] = id.split ('-');
            let base = baseId.toUpperCase ();
            let quote = quoteId.toUpperCase ();
            base = this.commonCurrencyCode (base);
            quote = this.commonCurrencyCode (quote);
            let symbol = base + '/' + quote;
            result[symbol] = {
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'baseId': baseId,
                'quoteId': quoteId,
                'info': id,
            };
        }
        // an alternative documented parser
        //     let markets = await this.publicGetMarkets ();
        //     for (let p = 0; p < markets['result'].length; p++) {
        //         let market = markets['result'][p];
        //         let id = market['MarketName'];
        //         let base = market['MarketCurrency'];
        //         let quote = market['BaseCurrency'];
        //         base = this.commonCurrencyCode (base);
        //         quote = this.commonCurrencyCode (quote);
        //         let symbol = base + '/' + quote;
        //         result.push ({
        //             'id': id,
        //             'symbol': symbol,
        //             'base': base,
        //             'quote': quote,
        //             'info': market,
        //         });
        //     }
        return result;
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let response = await this.privateGetGetbalances ();
        let balances = response['result'];
        let result = { 'info': balances };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let code = balance['Currency'];
            let currency = this.commonCurrencyCode (code);
            let account = {
                'free': balance['Available'],
                'used': balance['Pending'],
                'total': balance['Balance'],
            };
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let request = {
            'market': this.marketId (symbol),
            'type': 'both',
        };
        if (typeof limit !== 'undefined')
            request['depth'] = limit; // 100
        let response = await this.publicGetOrderbook (this.extend (request, params));
        let orderbook = response['result'];
        return this.parseOrderBook (orderbook, undefined, 'buy', 'sell', 'Rate', 'Quantity');
    }

    async fetchOrderBooks (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let orderbooks = {};
        let response = await this.publicGetFullorderbook ();
        let types = Object.keys (response['result']);
        for (let i = 0; i < types.length; i++) {
            let type = types[i];
            let bidasks = response['result'][type];
            let bidasksByMarketId = this.groupBy (bidasks, 'Market');
            let marketIds = Object.keys (bidasksByMarketId);
            for (let j = 0; j < marketIds.length; j++) {
                let marketId = marketIds[j];
                let symbol = marketId.toUpperCase ();
                let side = type;
                if (symbol in this.markets_by_id) {
                    let market = this.markets_by_id[symbol];
                    symbol = market['symbol'];
                } else {
                    let [ base, quote ] = symbol.split ('-');
                    let invertedId = quote + '-' + base;
                    if (invertedId in this.markets_by_id) {
                        let market = this.markets_by_id[invertedId];
                        symbol = market['symbol'];
                    }
                }
                if (!(symbol in orderbooks))
                    orderbooks[symbol] = {};
                orderbooks[symbol][side] = bidasksByMarketId[marketId];
            }
        }
        let result = {};
        let keys = Object.keys (orderbooks);
        for (let k = 0; k < keys.length; k++) {
            let key = keys[k];
            result[key] = this.parseOrderBook (orderbooks[key], undefined, 'buy', 'sell', 'Rate', 'Quantity');
        }
        return result;
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = ticker['updated'] * 1000;
        let symbol = undefined;
        if (market)
            symbol = market['symbol'];
        let last = parseFloat (ticker['lastprice']);
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': parseFloat (ticker['high']),
            'low': parseFloat (ticker['low']),
            'bid': parseFloat (ticker['buy']),
            'bidVolume': undefined,
            'ask': parseFloat (ticker['sell']),
            'askVolume': undefined,
            'vwap': undefined,
            'open': undefined,
            'close': last,
            'last': last,
            'previousClose': undefined,
            'change': undefined,
            'percentage': undefined,
            'average': parseFloat (ticker['avg']),
            'baseVolume': undefined,
            'quoteVolume': this.safeFloat (ticker, 'buysupport'),
            'info': ticker,
        };
    }

    async fetchTickers (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let tickers = await this.webGetPrices (params);
        let result = { 'info': tickers };
        let ids = Object.keys (tickers);
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let ticker = tickers[id];
            let uppercase = id.toUpperCase ();
            let market = undefined;
            let symbol = undefined;
            if (uppercase in this.markets_by_id) {
                market = this.markets_by_id[uppercase];
                symbol = market['symbol'];
            } else {
                let [ base, quote ] = uppercase.split ('-');
                base = this.commonCurrencyCode (base);
                quote = this.commonCurrencyCode (quote);
                symbol = base + '/' + quote;
            }
            result[symbol] = this.parseTicker (ticker, market);
        }
        return result;
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.webGetMarket (this.extend ({
            'market': market['id'].toLowerCase (),
        }, params));
        let ticker = response['ticker'];
        return this.parseTicker (ticker, market);
    }

    parseTrade (trade, market) {
        let timestamp = this.parse8601 (trade['TimeStamp']);
        return {
            'id': trade['Id'].toString (),
            'info': trade,
            'order': undefined,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': undefined,
            'side': trade['OrderType'].toLowerCase (),
            'price': trade['Price'],
            'amount': trade['Quantity'],
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetMarkethistory (this.extend ({
            'market': market['id'],
            'type': 'both',
            'depth': 100,
        }, params));
        return this.parseTrades (response['result'], market, since, limit);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let method = 'privateGet' + this.capitalize (side) + type;
        let response = await this[method] (this.extend ({
            'market': this.marketId (symbol),
            'quantity': amount,
            'rate': price,
        }, params));
        return {
            'info': response,
            'id': response['result']['uuid'],
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        return await this.privateGetCancel ({ 'uuid': id });
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'][api];
        if (api === 'private') {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ().toString ();
            let query = this.keysort (this.extend ({
                'a': path,
                'apikey': this.apiKey,
                'nonce': nonce,
            }, params));
            url += '?' + this.urlencode (query);
            headers = { 'apisign': this.hmac (this.encode (url), this.encode (this.secret), 'sha512') };
        } else if (api === 'public') {
            url += '?' + this.urlencode (this.extend ({
                'a': 'get' + path,
            }, params));
        } else {
            url += '/' + this.implodeParams (path, params) + '.json';
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if (api === 'web')
            return response;
        if ('success' in response)
            if (response['success'])
                return response;
        throw new ExchangeError (this.id + ' ' + this.json (response));
    }
};
<|endoftext|>


<commit_before>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { ExchangeError } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class ccex extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'ccex',
            'name': 'C-CEX',
            'countries': [ 'DE', 'EU' ],
            'rateLimit': 1500,
            'has': {
                'CORS': false,
                'fetchTickers': true,
                'fetchOrderBooks': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/27766433-16881f90-5ed8-11e7-92f8-3d92cc747a6c.jpg',
                'api': {
                    'web': 'https://c-cex.com/t',
                    'public': 'https://c-cex.com/t/api_pub.html',
                    'private': 'https://c-cex.com/t/api.html',
                },
                'www': 'https://c-cex.com',
                'doc': 'https://c-cex.com/?id=api',
            },
            'api': {
                'web': {
                    'get': [
                        'coinnames',
                        '{market}',
                        'pairs',
                        'prices',
                        'volume_{coin}',
                    ],
                },
                'public': {
                    'get': [
                        'balancedistribution',
                        'markethistory',
                        'markets',
                        'marketsummaries',
                        'orderbook',
                        'fullorderbook',
                    ],
                },
                'private': {
                    'get': [
                        'buylimit',
                        'cancel',
                        'getbalance',
                        'getbalances',
                        'getopenorders',
                        'getorder',
                        'getorderhistory',
                        'mytrades',
                        'selllimit',
                    ],
                },
            },
            'fees': {
                'trading': {
                    'taker': 0.2 / 100,
                    'maker': 0.2 / 100,
                },
            },
            'commonCurrencies': {
                'IOT': 'IoTcoin',
                'BLC': 'Cryptobullcoin',
                'XID': 'InternationalDiamond',
                'LUX': 'Luxmi',
                'CRC': 'CoreCoin',
            },
        });
    }

    async fetchMarkets () {
        let result = {};
        let response = await this.webGetPairs ();
        let markets = response['pairs'];
        for (let i = 0; i < markets.length; i++) {
            let id = markets[i];
            let [ baseId, quoteId ] = id.split ('-');
            let base = baseId.toUpperCase ();
            let quote = quoteId.toUpperCase ();
            base = this.commonCurrencyCode (base);
            quote = this.commonCurrencyCode (quote);
            let symbol = base + '/' + quote;
            result[symbol] = {
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'baseId': baseId,
                'quoteId': quoteId,
                'info': id,
            };
        }
        // an alternative documented parser
        //     let markets = await this.publicGetMarkets ();
        //     for (let p = 0; p < markets['result'].length; p++) {
        //         let market = markets['result'][p];
        //         let id = market['MarketName'];
        //         let base = market['MarketCurrency'];
        //         let quote = market['BaseCurrency'];
        //         base = this.commonCurrencyCode (base);
        //         quote = this.commonCurrencyCode (quote);
        //         let symbol = base + '/' + quote;
        //         result.push ({
        //             'id': id,
        //             'symbol': symbol,
        //             'base': base,
        //             'quote': quote,
        //             'info': market,
        //         });
        //     }
        return result;
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let response = await this.privateGetGetbalances ();
        let balances = response['result'];
        let result = { 'info': balances };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let code = balance['Currency'];
            let currency = this.commonCurrencyCode (code);
            let account = {
                'free': balance['Available'],
                'used': balance['Pending'],
                'total': balance['Balance'],
            };
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let request = {
            'market': this.marketId (symbol),
            'type': 'both',
        };
        if (typeof limit !== 'undefined')
            request['depth'] = limit; // 100
        let response = await this.publicGetOrderbook (this.extend (request, params));
        let orderbook = response['result'];
        return this.parseOrderBook (orderbook, undefined, 'buy', 'sell', 'Rate', 'Quantity');
    }

    async fetchOrderBooks (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let orderbooks = {};
        let response = await this.publicGetFullorderbook ();
        let types = Object.keys (response['result']);
        for (let i = 0; i < types.length; i++) {
            let type = types[i];
            let bidasks = response['result'][type];
            let bidasksByMarketId = this.groupBy (bidasks, 'Market');
            let marketIds = Object.keys (bidasksByMarketId);
            for (let j = 0; j < marketIds.length; j++) {
                let marketId = marketIds[j];
                let symbol = marketId.toUpperCase ();
                let side = type;
                if (symbol in this.markets_by_id) {
                    let market = this.markets_by_id[symbol];
                    symbol = market['symbol'];
                } else {
                    let [ base, quote ] = symbol.split ('-');
                    let invertedId = quote + '-' + base;
                    if (invertedId in this.markets_by_id) {
                        let market = this.markets_by_id[invertedId];
                        symbol = market['symbol'];
                    }
                }
                if (!(symbol in orderbooks))
                    orderbooks[symbol] = {};
                orderbooks[symbol][side] = bidasksByMarketId[marketId];
            }
        }
        let result = {};
        let keys = Object.keys (orderbooks);
        for (let k = 0; k < keys.length; k++) {
            let key = keys[k];
            result[key] = this.parseOrderBook (orderbooks[key], undefined, 'buy', 'sell', 'Rate', 'Quantity');
        }
        return result;
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = ticker['updated'] * 1000;
        let symbol = undefined;
        if (typeof market !== 'undefined')
            symbol = market['symbol'];
        let last = this.safeFloat (ticker, 'lastprice');
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': this.safeFloat (ticker, 'high'),
            'low': this.safeFloat (ticker, 'low'),
            'bid': this.safeFloat (ticker, 'buy'),
            'bidVolume': undefined,
            'ask': this.safeFloat (ticker, 'sell'),
            'askVolume': undefined,
            'vwap': undefined,
            'open': undefined,
            'close': last,
            'last': last,
            'previousClose': undefined,
            'change': undefined,
            'percentage': undefined,
            'average': this.safeFloat (ticker, 'avg'),
            'baseVolume': undefined,
            'quoteVolume': this.safeFloat (ticker, 'buysupport'),
            'info': ticker,
        };
    }

    async fetchTickers (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let tickers = await this.webGetPrices (params);
        let result = {};
        let ids = Object.keys (tickers);
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let ticker = tickers[id];
            let market = undefined;
            let symbol = undefined;
            if (id in this.markets_by_id) {
                market = this.markets_by_id[id];
                symbol = market['symbol'];
            } else {
                let uppercase = id.toUpperCase ();
                let [ base, quote ] = uppercase.split ('-');
                base = this.commonCurrencyCode (base);
                quote = this.commonCurrencyCode (quote);
                symbol = base + '/' + quote;
            }
            result[symbol] = this.parseTicker (ticker, market);
        }
        return result;
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.webGetMarket (this.extend ({
            'market': market['id'].toLowerCase (),
        }, params));
        let ticker = response['ticker'];
        return this.parseTicker (ticker, market);
    }

    parseTrade (trade, market) {
        let timestamp = this.parse8601 (trade['TimeStamp']);
        return {
            'id': trade['Id'].toString (),
            'info': trade,
            'order': undefined,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': undefined,
            'side': trade['OrderType'].toLowerCase (),
            'price': trade['Price'],
            'amount': trade['Quantity'],
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetMarkethistory (this.extend ({
            'market': market['id'],
            'type': 'both',
            'depth': 100,
        }, params));
        return this.parseTrades (response['result'], market, since, limit);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let method = 'privateGet' + this.capitalize (side) + type;
        let response = await this[method] (this.extend ({
            'market': this.marketId (symbol),
            'quantity': amount,
            'rate': price,
        }, params));
        return {
            'info': response,
            'id': response['result']['uuid'],
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        return await this.privateGetCancel ({ 'uuid': id });
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'][api];
        if (api === 'private') {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ().toString ();
            let query = this.keysort (this.extend ({
                'a': path,
                'apikey': this.apiKey,
                'nonce': nonce,
            }, params));
            url += '?' + this.urlencode (query);
            headers = { 'apisign': this.hmac (this.encode (url), this.encode (this.secret), 'sha512') };
        } else if (api === 'public') {
            url += '?' + this.urlencode (this.extend ({
                'a': 'get' + path,
            }, params));
        } else {
            url += '/' + this.implodeParams (path, params) + '.json';
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if (api === 'web')
            return response;
        if ('success' in response)
            if (response['success'])
                return response;
        throw new ExchangeError (this.id + ' ' + this.json (response));
    }
};
<commit_msg>ccex VIT → VitalCoin fix #2987 https://c-cex.com/?id=info<commit_after>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { ExchangeError } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class ccex extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'ccex',
            'name': 'C-CEX',
            'countries': [ 'DE', 'EU' ],
            'rateLimit': 1500,
            'has': {
                'CORS': false,
                'fetchTickers': true,
                'fetchOrderBooks': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/27766433-16881f90-5ed8-11e7-92f8-3d92cc747a6c.jpg',
                'api': {
                    'web': 'https://c-cex.com/t',
                    'public': 'https://c-cex.com/t/api_pub.html',
                    'private': 'https://c-cex.com/t/api.html',
                },
                'www': 'https://c-cex.com',
                'doc': 'https://c-cex.com/?id=api',
            },
            'api': {
                'web': {
                    'get': [
                        'coinnames',
                        '{market}',
                        'pairs',
                        'prices',
                        'volume_{coin}',
                    ],
                },
                'public': {
                    'get': [
                        'balancedistribution',
                        'markethistory',
                        'markets',
                        'marketsummaries',
                        'orderbook',
                        'fullorderbook',
                    ],
                },
                'private': {
                    'get': [
                        'buylimit',
                        'cancel',
                        'getbalance',
                        'getbalances',
                        'getopenorders',
                        'getorder',
                        'getorderhistory',
                        'mytrades',
                        'selllimit',
                    ],
                },
            },
            'fees': {
                'trading': {
                    'taker': 0.2 / 100,
                    'maker': 0.2 / 100,
                },
            },
            'commonCurrencies': {
                'BLC': 'Cryptobullcoin',
                'CRC': 'CoreCoin',
                'IOT': 'IoTcoin',
                'LUX': 'Luxmi',
                'VIT': 'VitalCoin',
                'XID': 'InternationalDiamond',
            },
        });
    }

    async fetchMarkets () {
        let result = {};
        let response = await this.webGetPairs ();
        let markets = response['pairs'];
        for (let i = 0; i < markets.length; i++) {
            let id = markets[i];
            let [ baseId, quoteId ] = id.split ('-');
            let base = baseId.toUpperCase ();
            let quote = quoteId.toUpperCase ();
            base = this.commonCurrencyCode (base);
            quote = this.commonCurrencyCode (quote);
            let symbol = base + '/' + quote;
            result[symbol] = {
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'baseId': baseId,
                'quoteId': quoteId,
                'info': id,
            };
        }
        // an alternative documented parser
        //     let markets = await this.publicGetMarkets ();
        //     for (let p = 0; p < markets['result'].length; p++) {
        //         let market = markets['result'][p];
        //         let id = market['MarketName'];
        //         let base = market['MarketCurrency'];
        //         let quote = market['BaseCurrency'];
        //         base = this.commonCurrencyCode (base);
        //         quote = this.commonCurrencyCode (quote);
        //         let symbol = base + '/' + quote;
        //         result.push ({
        //             'id': id,
        //             'symbol': symbol,
        //             'base': base,
        //             'quote': quote,
        //             'info': market,
        //         });
        //     }
        return result;
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let response = await this.privateGetGetbalances ();
        let balances = response['result'];
        let result = { 'info': balances };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let code = balance['Currency'];
            let currency = this.commonCurrencyCode (code);
            let account = {
                'free': balance['Available'],
                'used': balance['Pending'],
                'total': balance['Balance'],
            };
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let request = {
            'market': this.marketId (symbol),
            'type': 'both',
        };
        if (typeof limit !== 'undefined')
            request['depth'] = limit; // 100
        let response = await this.publicGetOrderbook (this.extend (request, params));
        let orderbook = response['result'];
        return this.parseOrderBook (orderbook, undefined, 'buy', 'sell', 'Rate', 'Quantity');
    }

    async fetchOrderBooks (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let orderbooks = {};
        let response = await this.publicGetFullorderbook ();
        let types = Object.keys (response['result']);
        for (let i = 0; i < types.length; i++) {
            let type = types[i];
            let bidasks = response['result'][type];
            let bidasksByMarketId = this.groupBy (bidasks, 'Market');
            let marketIds = Object.keys (bidasksByMarketId);
            for (let j = 0; j < marketIds.length; j++) {
                let marketId = marketIds[j];
                let symbol = marketId.toUpperCase ();
                let side = type;
                if (symbol in this.markets_by_id) {
                    let market = this.markets_by_id[symbol];
                    symbol = market['symbol'];
                } else {
                    let [ base, quote ] = symbol.split ('-');
                    let invertedId = quote + '-' + base;
                    if (invertedId in this.markets_by_id) {
                        let market = this.markets_by_id[invertedId];
                        symbol = market['symbol'];
                    }
                }
                if (!(symbol in orderbooks))
                    orderbooks[symbol] = {};
                orderbooks[symbol][side] = bidasksByMarketId[marketId];
            }
        }
        let result = {};
        let keys = Object.keys (orderbooks);
        for (let k = 0; k < keys.length; k++) {
            let key = keys[k];
            result[key] = this.parseOrderBook (orderbooks[key], undefined, 'buy', 'sell', 'Rate', 'Quantity');
        }
        return result;
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = ticker['updated'] * 1000;
        let symbol = undefined;
        if (typeof market !== 'undefined')
            symbol = market['symbol'];
        let last = this.safeFloat (ticker, 'lastprice');
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': this.safeFloat (ticker, 'high'),
            'low': this.safeFloat (ticker, 'low'),
            'bid': this.safeFloat (ticker, 'buy'),
            'bidVolume': undefined,
            'ask': this.safeFloat (ticker, 'sell'),
            'askVolume': undefined,
            'vwap': undefined,
            'open': undefined,
            'close': last,
            'last': last,
            'previousClose': undefined,
            'change': undefined,
            'percentage': undefined,
            'average': this.safeFloat (ticker, 'avg'),
            'baseVolume': undefined,
            'quoteVolume': this.safeFloat (ticker, 'buysupport'),
            'info': ticker,
        };
    }

    async fetchTickers (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let tickers = await this.webGetPrices (params);
        let result = {};
        let ids = Object.keys (tickers);
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let ticker = tickers[id];
            let market = undefined;
            let symbol = undefined;
            if (id in this.markets_by_id) {
                market = this.markets_by_id[id];
                symbol = market['symbol'];
            } else {
                let uppercase = id.toUpperCase ();
                let [ base, quote ] = uppercase.split ('-');
                base = this.commonCurrencyCode (base);
                quote = this.commonCurrencyCode (quote);
                symbol = base + '/' + quote;
            }
            result[symbol] = this.parseTicker (ticker, market);
        }
        return result;
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.webGetMarket (this.extend ({
            'market': market['id'].toLowerCase (),
        }, params));
        let ticker = response['ticker'];
        return this.parseTicker (ticker, market);
    }

    parseTrade (trade, market) {
        let timestamp = this.parse8601 (trade['TimeStamp']);
        return {
            'id': trade['Id'].toString (),
            'info': trade,
            'order': undefined,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': undefined,
            'side': trade['OrderType'].toLowerCase (),
            'price': trade['Price'],
            'amount': trade['Quantity'],
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetMarkethistory (this.extend ({
            'market': market['id'],
            'type': 'both',
            'depth': 100,
        }, params));
        return this.parseTrades (response['result'], market, since, limit);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let method = 'privateGet' + this.capitalize (side) + type;
        let response = await this[method] (this.extend ({
            'market': this.marketId (symbol),
            'quantity': amount,
            'rate': price,
        }, params));
        return {
            'info': response,
            'id': response['result']['uuid'],
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        return await this.privateGetCancel ({ 'uuid': id });
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'][api];
        if (api === 'private') {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ().toString ();
            let query = this.keysort (this.extend ({
                'a': path,
                'apikey': this.apiKey,
                'nonce': nonce,
            }, params));
            url += '?' + this.urlencode (query);
            headers = { 'apisign': this.hmac (this.encode (url), this.encode (this.secret), 'sha512') };
        } else if (api === 'public') {
            url += '?' + this.urlencode (this.extend ({
                'a': 'get' + path,
            }, params));
        } else {
            url += '/' + this.implodeParams (path, params) + '.json';
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if (api === 'web')
            return response;
        if ('success' in response)
            if (response['success'])
                return response;
        throw new ExchangeError (this.id + ' ' + this.json (response));
    }
};
<|endoftext|>