示例#1
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
示例#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)
示例#3
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}'
示例#4
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
示例#5
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, A_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, A_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)
示例#6
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(UnprocessableTradePair):
        pair_get_assets('_')
    with pytest.raises(UnprocessableTradePair):
        pair_get_assets('ETH_')
    with pytest.raises(UnprocessableTradePair):
        pair_get_assets('_BTC')
    with pytest.raises(UnprocessableTradePair):
        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