def transactions_from_dictlist(given_transactions, start_ts, end_ts): """ Gets a list of transaction, most probably read from the json files and a time period. Returns it as a list of the transaction tuples that are inside the time period """ returned_transactions = list() for given_tx in given_transactions: if given_tx['timestamp'] < start_ts: continue if given_tx['timestamp'] > end_ts: break returned_transactions.append( EthereumTransaction( timestamp=convert_to_int(given_tx['timestamp']), block_number=convert_to_int(given_tx['block_number']), hash=given_tx['hash'], from_address=given_tx['from_address'], to_address=given_tx['to_address'], value=FVal(given_tx['value']), gas=FVal(given_tx['gas']), gas_price=FVal(given_tx['gas_price']), gas_used=FVal(given_tx['gas_used']), )) return returned_transactions
def query_txlist(address, internal, from_block=None, to_block=None): result = list() if internal: reqstring = ('https://api.etherscan.io/api?module=account&action=' 'txlistinternal&address={}'.format(address)) else: reqstring = ('https://api.etherscan.io/api?module=account&action=' 'txlist&address={}'.format(address)) if from_block: reqstring += '&startblock={}'.format(from_block) if to_block: reqstring += '&endblock={}'.format(to_block) resp = urlopen(Request(reqstring)) resp = rlk_jsonloads(resp.read()) if 'status' not in resp or convert_to_int(resp['status']) != 1: status = convert_to_int(resp['status']) if status == 0 and resp['message'] == 'No transactions found': return list() # else unknown error raise ValueError( 'Failed to query txlist from etherscan with query: {} . ' 'Response was: {}'.format(reqstring, resp)) for v in resp['result']: # internal tx list contains no gasprice gas_price = -1 if internal else FVal(v['gasPrice']) result.append( EthereumTransaction( timestamp=convert_to_int(v['timeStamp']), block_number=convert_to_int(v['blockNumber']), hash=v['hash'], from_address=v['from'], to_address=v['to'], value=FVal(v['value']), gas=FVal(v['gas']), gas_price=gas_price, gas_used=FVal(v['gasUsed']), )) return result
def trade_from_kraken(kraken_trade): """Turn a kraken trade returned from kraken trade history to our common trade history format""" currency_pair = kraken_to_world_pair(kraken_trade['pair']) quote_currency = get_pair_position(currency_pair, 'second') return Trade( # Kraken timestamps have floating point ... timestamp=convert_to_int(kraken_trade['time'], accept_only_exact=False), pair=currency_pair, type=kraken_trade['type'], rate=FVal(kraken_trade['price']), cost=FVal(kraken_trade['cost']), cost_currency=quote_currency, fee=FVal(kraken_trade['fee']), fee_currency=quote_currency, amount=FVal(kraken_trade['vol']), location='kraken')
def query_deposits_withdrawals(self, start_ts, end_ts, end_at_least_ts): with self.lock: cache = self.check_trades_cache( start_ts, end_at_least_ts, special_name='deposits_withdrawals') if cache is not None: result = cache else: result = self.query_until_finished(endpoint='Ledgers', keyname='ledger', start_ts=start_ts, end_ts=end_ts, extra_dict=dict(type='deposit')) result.extend( self.query_until_finished(endpoint='Ledgers', keyname='ledger', start_ts=start_ts, end_ts=end_ts, extra_dict=dict(type='withdrawal'))) with self.lock: self.update_trades_cache(result, start_ts, end_ts, special_name='deposits_withdrawals') movements = list() for movement in result: movements.append( AssetMovement( exchange='kraken', category=movement['type'], # Kraken timestamps have floating point timestamp=convert_to_int(movement['time'], accept_only_exact=False), asset=KRAKEN_TO_WORLD[movement['asset']], amount=FVal(movement['amount']), fee=FVal(movement['fee']))) return movements
def query_historical_price(self, from_asset, to_asset, timestamp): """ Query the historical price on `timestamp` for `from_asset` in `to_asset`. So how much `to_asset` does 1 unit of `from_asset` cost. Args: from_asset (str): The ticker symbol of the asset for which we want to know the price. to_asset (str): The ticker symbol of the asset against which we want to know the price. timestamp (int): The timestamp at which to query the price """ if from_asset == to_asset: return 1 if from_asset not in self.cryptocompare_coin_list: raise PriceQueryUnknownFromAsset(from_asset) data = self.get_historical_data(from_asset, to_asset, timestamp) # all data are sorted and timestamps are always increasing by 1 hour # find the closest entry to the provided timestamp # print("loaded {}_{}".format(from_asset, to_asset)) assert timestamp > data[0]['time'] index = convert_to_int((timestamp - data[0]['time']) / 3600, accept_only_exact=False) # print("timestamp: {} index: {} data_length: {}".format(timestamp, index, len(data))) diff = abs(data[index]['time'] - timestamp) if index + 1 <= len(data) - 1: diff_p1 = abs(data[index + 1]['time'] - timestamp) if diff_p1 < diff: index = index + 1 if data[index]['high'] is None or data[index]['low'] is None: # If we get some None in the hourly set price to 0 so that we check daily price price = FVal(0) else: price = FVal((data[index]['high'] + data[index]['low'])) / 2 if price == 0: if from_asset != 'BTC' and to_asset != 'BTC': # Just get the BTC price asset_btc_price = self.query_historical_price( from_asset, 'BTC', timestamp) btc_to_asset_price = self.query_historical_price( 'BTC', to_asset, timestamp) price = asset_btc_price * btc_to_asset_price else: # attempt to get the daily price by timestamp query_string = ( 'https://min-api.cryptocompare.com/data/pricehistorical?' 'fsym={}&tsyms={}&ts={}'.format(from_asset, to_asset, timestamp)) if to_asset == 'BTC': query_string += '&tryConversion=false' resp = urlopen(Request(query_string)) resp = rlk_jsonloads(resp.read()) print('DAILY PRICE OF ASSET: "{}"'.format(resp)) if from_asset not in resp: error_message = 'Failed to query cryptocompare for: "{}"'.format( query_string) raise ValueError(error_message) price = FVal(resp[from_asset][to_asset]) if price == 0: raise NoPriceForGivenTimestamp( from_asset, to_asset, tsToDate(timestamp, formatstr='%d/%m/%Y, %H:%M:%S')) return price