Beispiel #1
0
def trade_from_binance(binance_trade: Dict) -> Trade:
    """Turn a binance trade returned from trade history to our common trade
    history format"""
    amount = FVal(binance_trade['qty'])
    rate = FVal(binance_trade['price'])
    pair = binance_pair_to_world(binance_trade['symbol'])

    base_asset, quote_asset = pair_get_assets(pair)

    if binance_trade['isBuyer']:
        order_type = 'buy'
        # e.g. in RDNETH we buy RDN by paying ETH
        cost_currency = quote_asset
    else:
        order_type = 'sell'
        # e.g. in RDNETH we sell RDN to obtain ETH
        cost_currency = base_asset

    fee_currency = binance_trade['commissionAsset']
    fee = FVal(binance_trade['commission'])
    cost = rate * amount

    return Trade(
        timestamp=binance_trade['time'],
        pair=pair,
        type=order_type,
        rate=rate,
        cost=cost,
        cost_currency=cost_currency,
        fee=fee,
        fee_currency=fee_currency,
        amount=amount,
        location='binance'
    )
Beispiel #2
0
    def choose_pair(
        self,
        timestamp: Timestamp,
        price_query: Callable[[Asset, Asset, Timestamp], FVal],
    ) -> TradePair:
        """Choose a random pair to trade from the available pairs at the selected timestamp"""
        choices = set(list(self.asset_pairs['result'].keys()))
        found = False
        while len(choices) != 0:
            pair = random.choice(tuple(choices))
            choices.remove(pair)
            pair = kraken_to_world_pair(pair)
            base, quote = pair_get_assets(pair)
            kbase = base.to_kraken()
            kquote = quote.to_kraken()
            if kbase in self.balances_dict or kquote in self.balances_dict:
                # Before choosing make sure that at the selected timestamp both of
                # the pair assets exist (had a price)
                if not assets_exist_at_time(base, quote, timestamp,
                                            price_query):
                    continue
                found = True
                break

        if not found:
            raise ValueError(
                'Could not find a pair to trade with the current funds')
        return trade_pair_from_assets(base, quote)
Beispiel #3
0
    def trade_to_binance(self, trade: Trade) -> Dict[str, Any]:
        """Turns our trade into a binance trade"""
        base, quote = pair_get_assets(trade.pair)
        bbase = base.to_binance()
        bquote = quote.to_binance()
        binance_symbol = bbase + bquote
        # Binance trades have timestamps with 3 extra zeros at the end
        timestamp = trade.timestamp * 1000
        msg = 'The given trade symbol is not a valid binance pair'
        assert binance_symbol in self._symbols_to_pair, msg

        trade_data = {
            'symbol': binance_symbol,
            'id': 1,
            'orderId': 1,
            'price': str(trade.rate),
            'qty': str(trade.amount),
            'commission': str(trade.fee),
            'commissionAsset': str(trade.fee_currency.to_binance()),
            'time': timestamp,
            'isBuyer': trade.trade_type == TradeType.BUY,
            'isMaker': True,
            'isBestMatch': True,
        }
        return trade_data
Beispiel #4
0
def world_pair_to_bittrex(pair: TradePair) -> str:
    """Turns a rotkehlchen pair to a bittrex pair"""
    base_asset, quote_asset = pair_get_assets(pair)

    base_asset_str = base_asset.to_bittrex()
    quote_asset_str = quote_asset.to_bittrex()

    # In bittrex the pairs are inverted and use '-'
    return f'{quote_asset_str}-{base_asset_str}'
Beispiel #5
0
    def choose_pair(self):
        choices = set(KRAKEN_PAIRS)
        found = False
        while len(choices) != 0:
            pair = random.choice(tuple(choices))
            choices.remove(pair)
            base, quote = pair_get_assets(pair)
            if base in self.funds or quote in self.funds:
                found = True
                break

        if not found:
            raise ValueError(
                'Could not find a pair to trade with the current funds')

        return pair
Beispiel #6
0
def world_to_kraken_pair(tradeable_pairs: List[str], pair: str) -> str:
    base_currency, quote_currency = pair_get_assets(pair)

    if base_currency not in KRAKEN_TO_WORLD:
        base_currency = WORLD_TO_KRAKEN[base_currency]
    if quote_currency not in KRAKEN_TO_WORLD:
        quote_currency = WORLD_TO_KRAKEN[quote_currency]

    if base_currency + quote_currency in tradeable_pairs:
        new_pair = base_currency + quote_currency
    elif quote_currency + base_currency in tradeable_pairs:
        new_pair = quote_currency + base_currency
    else:
        raise ValueError(
            f'Unknown pair "{pair}" provided. Couldnt find {base_currency + quote_currency}'
            f' or {quote_currency + base_currency} in tradeable pairs',
        )

    return new_pair
Beispiel #7
0
def world_to_kraken_pair(tradeable_pairs: List[str], pair: TradePair) -> str:
    base_asset, quote_asset = pair_get_assets(pair)

    if base_asset not in KRAKEN_TO_WORLD:
        base_asset = WORLD_TO_KRAKEN[base_asset]
    if quote_asset not in KRAKEN_TO_WORLD:
        quote_asset = WORLD_TO_KRAKEN[quote_asset]

    pair1 = base_asset + quote_asset
    pair2 = quote_asset + base_asset

    # In some pairs, XXBT is XBT and ZEUR is EUR ...
    pair3 = None
    if 'XXBT' in pair1:
        pair3 = pair1.replace('XXBT', 'XBT')
    pair4 = None
    if 'XXBT' in pair2:
        pair4 = pair2.replace('XXBT', 'XBT')
    if 'ZEUR' in pair1:
        pair3 = pair1.replace('ZEUR', 'EUR')
    pair4 = None
    if 'ZEUR' in pair2:
        pair4 = pair2.replace('ZEUR', 'EUR')

    if pair1 in tradeable_pairs:
        new_pair = pair1
    elif pair2 in tradeable_pairs:
        new_pair = pair2
    elif pair3 in tradeable_pairs:
        new_pair = pair3
    elif pair4 in tradeable_pairs:
        new_pair = pair4
    else:
        raise ValueError(
            f'Unknown pair "{pair}" provided. Couldnt find {base_asset + quote_asset}'
            f' or {quote_asset + base_asset} in tradeable pairs',
        )

    return new_pair
Beispiel #8
0
def world_to_kraken_pair(tradeable_pairs: List[str], pair: TradePair) -> str:
    base_asset, quote_asset = pair_get_assets(pair)

    base_asset_str = base_asset.to_kraken()
    quote_asset_str = quote_asset.to_kraken()

    pair1 = base_asset_str + quote_asset_str
    pair2 = quote_asset_str + base_asset_str

    # In some pairs, XXBT is XBT and ZEUR is EUR ...
    pair3 = None
    if 'XXBT' in pair1:
        pair3 = pair1.replace('XXBT', 'XBT')
    pair4 = None
    if 'XXBT' in pair2:
        pair4 = pair2.replace('XXBT', 'XBT')
    if 'ZEUR' in pair1:
        pair3 = pair1.replace('ZEUR', 'EUR')
    pair4 = None
    if 'ZEUR' in pair2:
        pair4 = pair2.replace('ZEUR', 'EUR')

    if pair1 in tradeable_pairs:
        new_pair = pair1
    elif pair2 in tradeable_pairs:
        new_pair = pair2
    elif pair3 in tradeable_pairs:
        new_pair = pair3
    elif pair4 in tradeable_pairs:
        new_pair = pair4
    else:
        raise ValueError(
            f'Unknown pair "{pair}" provided. Couldnt find {base_asset_str + quote_asset_str}'
            f' or {quote_asset_str + base_asset_str} in tradeable pairs',
        )

    return new_pair
Beispiel #9
0
def test_pair_get_assets():
    a1, a2 = pair_get_assets('ETH_BTC')
    assert isinstance(a1, Asset)
    assert a1 == A_ETH
    assert isinstance(a2, Asset)
    assert a2 == A_BTC

    with pytest.raises(ValueError):
        pair_get_assets('_')
    with pytest.raises(ValueError):
        pair_get_assets('ETH_')
    with pytest.raises(ValueError):
        pair_get_assets('_BTC')
    with pytest.raises(ValueError):
        pair_get_assets('ETH_BTC_USD')

    with pytest.raises(UnknownAsset):
        pair_get_assets('ETH_FDFSFDSFDSF')
    with pytest.raises(UnknownAsset):
        pair_get_assets('FDFSFDSFDSF_BTC')

    a1, a2 = pair_get_assets('ETH_RDN')
    assert isinstance(a1, Asset)
    assert a1 == A_ETH
    assert isinstance(a2, Asset)
    assert a2 == A_RDN
Beispiel #10
0
    def create_action(self, index: int, ts: Timestamp):
        """Create a random trade action on a random exchange depending
        on the funds that are available in that exchange"""
        # choose an exchange at random
        exchange_name = random.choice(ALLOWED_EXCHANGES)
        exchange = getattr(self, exchange_name)
        # choose a random pair at that exchange
        pair = exchange.choose_pair(
            timestamp=ts,
            price_query=self.query_historical_price,
        )
        print(
            f'Creating trade {index + 1} / {self.trades_number} in {exchange_name}'
            f' for the pair: {pair} at timestamp {ts}', )
        # depending on our funds decide on what to do. Buy/sell
        base, quote = pair_get_assets(pair)
        if exchange.get_balance(base) is None:
            action_type = TradeType.BUY
        elif exchange.get_balance(quote) is None:
            action_type = TradeType.SELL
        else:
            # TODO: trade the one we have most of
            action_type = random.choice(list(TradeType))

        # if we are buying we are going to spend from the quote asset
        if action_type == TradeType.BUY:
            spending_asset = quote
        else:  # selling spends from the base asset
            spending_asset = base
        # get a spending asset amount within our per-trade equivalent range and
        # our available funds
        spending_usd_rate = self.query_historical_price(
            spending_asset, 'USD', ts)
        max_usd_in_spending_asset = spending_usd_rate * exchange.get_balance(
            spending_asset)
        max_usd_equivalent_to_spend = min(max_usd_in_spending_asset,
                                          MAX_TRADE_USD_VALUE)
        rate = self.query_historical_price(base, quote, ts)
        usd_to_spend = FVal(
            random.uniform(0.01, float(max_usd_equivalent_to_spend)))
        amount_in_spending_asset = usd_to_spend / spending_usd_rate
        # if we are buying then the amount is the amount of asset we bought
        if action_type == TradeType.BUY:
            amount = amount_in_spending_asset / rate
        # if we are selling the amount is the spending asset amount
        else:
            amount = amount_in_spending_asset

        quote_asset_usd_rate = self.query_historical_price(quote, 'USD', ts)
        fee_in_quote_currency = FVal(random.uniform(
            0, MAX_FEE_USD_VALUE)) / quote_asset_usd_rate

        # create the trade
        trade = Trade(
            timestamp=ts,
            location=exchange_name,
            pair=pair,
            trade_type=action_type,
            amount=amount,
            rate=rate,
            fee=fee_in_quote_currency,
            fee_currency=quote,
            link='',
            notes='',
        )
        logger.info(f'Created trade: {trade}')

        # Adjust our global and per exchange accounting
        if action_type == TradeType.BUY:
            # we buy so we increase our base asset by amount
            self.increase_asset(base, amount, exchange_name)
            # and decrease quote by amount * rate
            self.decrease_asset(quote, amount * rate, exchange_name)
        else:
            # we sell so we increase our quote asset
            self.increase_asset(quote, amount * rate, exchange_name)
            # and decrease our base asset
            self.decrease_asset(base, amount, exchange_name)

        # finally add it to the exchange
        exchange.append_trade(trade)
Beispiel #11
0
    def create_action(self):
        """Create a random trade action"""
        ts = self.get_next_ts()
        # choose a random pair
        pair = self.choose_pair()
        # depending on our funds decide on what to do. Buy/sell
        base, quote = pair_get_assets(pair)
        if base not in self.funds:
            action_type = 'buy'
        elif quote not in self.funds:
            action_type = 'sell'
        else:
            # TODO: trade the one we have most of
            action_type = random.choice(('buy', 'sell'))

        # if we are buying we are going to spend from the quote asset
        if action_type == 'buy':
            spending_asset = quote
        else:  # selling spends from the base asset
            spending_asset = base
        # get a spending asset amount within our per-trade equivalent range and
        # our available funds
        spending_usd_rate = self.query_historical_price(
            spending_asset, 'USD', ts)
        max_usd_in_spending_asset = spending_usd_rate * self.funds[
            spending_asset]
        max_usd_equivalent_to_spend = min(max_usd_in_spending_asset,
                                          MAX_TRADE_USD_VALUE)
        rate = self.query_historical_price(base, quote, ts)
        usd_to_spend = FVal(
            random.uniform(0.01, float(max_usd_equivalent_to_spend)))
        amount_in_spending_asset = usd_to_spend / spending_usd_rate
        # if we are buying then the amount of asset we bought
        if action_type == 'buy':
            amount = amount_in_spending_asset / rate
        # if we are selling the amount is the spending asset amount
        else:
            amount = amount_in_spending_asset

        quote_asset_usd_rate = self.query_historical_price(base, quote, ts)
        fee_in_quote_currency = FVal(random.uniform(
            0, MAX_FEE_USD_VALUE)) / quote_asset_usd_rate

        # create the trade
        trade = Trade(
            time=ts,
            location='kraken',
            pair=pair,
            trade_type=action_type,
            amount=amount,
            rate=rate,
            fee=fee_in_quote_currency,
            fee_currency=quote,
            link='',
            notes='',
        )

        logger.info(f'Created trade: {trade}')

        if action_type == 'buy':
            # we buy so we increase our base asset by amount
            self.increase_asset(base, amount)
            # and decrease quote by amount * rate
            self.decrease_asset(quote, amount * rate)
        else:
            # we sell so we increase our quote asset
            self.increase_asset(quote, amount * rate)
            # and decrease our base asset
            self.decrease_asset(base, amount)

        # normally here you would input it into the appropriate fake exchange
        # but since we only got kraken faker now ...
        self.fake_kraken.append_trade(trade)