示例#1
0
 def fetch_ticker(self, symbol):
     ohlcv = self._ohlcvs.get(symbol)
     if ohlcv is None:
         raise BadSymbol('ExchangeBackend: no prices for {}'.format(symbol))
     current_date = self._timeframe.date().floor('1T')
     row = ohlcv.loc[current_date]
     timestamp = int(current_date.value / 10**6)
     return {
         'symbol': symbol,
         'timestamp': timestamp,
         'datetime': Exchange.iso8601(timestamp),
         'high': row['high'],
         'low': row['low'],
         'bid': None,
         'bidVolume': None,
         'ask': None,
         'askVolume': None,
         'vwap': None,
         'open': row['open'],
         'close': row['close'],
         'last': None,
         'previousClose': None,
         'change': None,
         'percentage': None,
         'average': None,
         'baseVolume': None,
         'quoteVolume': None,
         'info': {},
     }
示例#2
0
 def iso8601(value):
     return ccxtExchange.iso8601(value)
示例#3
0
    def create_order(self, market, type, price, side, amount):
        self._update_orders()
        type_market = False
        type_limit = False
        if type == 'market':
            if price is not None:
                raise InvalidOrder(
                    'ExchangeAccount: market order has no price')
            type_market = True
        elif type == 'limit':
            price = _convert_float_or_raise(price, 'ExchangeAccount: price')
            type_limit = True
            if price <= 0:
                raise BadRequest('ExchangeAccount: price needs to be positive')
        else:
            raise InvalidOrder(
                'ExchangeAccount: only market and limit order supported')
        if market is None:
            raise InvalidOrder('ExchangeAccount: market is None')
        symbol = market.get('symbol')
        ohlcv = self._ohlcvs.get(symbol)
        if ohlcv is None:
            raise InvalidOrder('ExchangeAccount: no prices available for {}'
                               .format(symbol))
        if side not in ['buy', 'sell']:
            raise InvalidOrder('ExchangeAccount: side {} not supported'
                               .format(side))
        buy = side == 'buy'
        amount = _convert_float_or_raise(amount, 'ExchangeAccount: amount')
        if amount <= 0:
            raise BadRequest('ExchangeAccount: amount needs to be positive')
        base = market.get('base')
        quote = market.get('quote')
        if base is None:
            raise BadRequest('ExchangeAccount: market has no base')
        if quote is None:
            raise BadRequest('ExchangeAccount: market has no quote')

        self._last_order_id += 1
        order_id = str(self._last_order_id)
        date = self._timeframe.date()
        timestamp = int(date.value / 10e5)
        order = {
            'info': {},
            'id': order_id,
            'timestamp': timestamp,
            'datetime': Exchange.iso8601(timestamp),
            'lastTradeTimestamp': None,
            'symbol': symbol,
            'type': type,
            'side': side,
            'price': None,
            'amount': amount,
            'cost': None,
            'average': None,
            'filled': 0,
            'remaining': amount,
            'status': 'open',
            'fee': {'currency': base if buy else quote,
                    'cost': None,
                    'rate': None},
            'trades': None,
        }

        if type_market:
            # Determinie the price of the market order
            # We could use the next low/high to fill the order, but then we
            # need to wait for the next date to fill the order, otherwise we
            # would introduce a possibility to see the future price
            # (Look-Ahead Bias)
            # If we wait for the next date, we would return a market order that
            # is pending, but this should never happen in reality
            # Maybe the factor should depend on the volume
            factor = Decimal('0.0015')
            if buy:
                price = (1 + factor) * _convert_float(ohlcv['high'][date])
            else:
                price = (1 - factor) * _convert_float(ohlcv['low'][date])
            fee_percentage = market.get('taker', 0)
            fee_percentage = _convert_float_or_raise(fee_percentage,
                                                     'ExchangeAccount: fee')
            self._update_balance(price, amount, base, quote, buy,
                                 fee_percentage)
            self._fill_order(order, buy, price, timestamp, fee_percentage)
            self._closed_orders[order_id] = order
        if type_limit:
            # TODO Probably use taker fee, if the order can be filled now
            fee_percentage = market.get('maker', 0)
            fee_percentage = _convert_float_or_raise(fee_percentage,
                                                     'ExchangeAccount: fee')
            if buy:
                self._balances[quote].change_used(price * amount)
            else:
                self._balances[base].change_used(amount)
            self._open_orders[order_id] = order
            self._private_order_info[order_id] = {
                'id': order_id,
                'base': base,
                'quote': quote,
                'price': price,
                'buy': buy,
                'fee_percentage': fee_percentage,
                'fillable_date': self._limit_order_fillable_date(
                    symbol, buy, price),
            }
            self._update_next_private_order_to_update()

        return {'id': order_id,
                'info': {}}