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
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)
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}'
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
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)
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