123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- #!/usr/bin/python3.6
- import sys
- import time
- import requests
- import json
- key_file = open('whale-alert-api-key', 'r')
- apikey = key_file.read()[:-1]
- key_file.close()
- tickers = ['btc', 'eth', 'usdc', 'usdt']
- stable_tickers = ['usdc','usdt']
- accumulated_usd = {} # [ticker][timestamp][direction] : [btc][123091820938][out]
- for ticker in tickers:
- accumulated_usd[ticker] = {}
- total_usd_unknown_to_exchange = {}
- total_txs_unknown_to_exchange = {}
- current_second_timestamp = int(time.time())
- current_minute = current_second_timestamp // 60
- current_hour = current_second_timestamp // 3600
- fetch_minute = current_minute-12 #fetch transactions from the minute - 12 since thats the maximum time it takes for a block to be mined
- fetch_minute_timestamp = 60*fetch_minute
- fetch_minute_hour = fetch_minute_timestamp // 3600 #the hour that this minute belongs to
- fetch_minute_hour_timestamp = fetch_minute_hour*3600
- cache_file = open("dbs/crypto-txs.cache.json", "r")
- cache_objs = json.load(cache_file)
- cache_file.close()
- # determine the interval to fetch
- # start should be > cache file, > (fetch_minute - 40)
- allowed_timestamp = (fetch_minute - 40)*60
- cache_timestamp = cache_objs["last-known-minute-timestamp"]
- cache_hour_timestamp = (cache_timestamp // 3600) * 3600
- start_timestamp = max(cache_timestamp+60,allowed_timestamp)
- end_timestamp = fetch_minute_timestamp + 60
- start_hour = start_timestamp // 3600
- end_hour = fetch_minute_timestamp // 3600
- if end_timestamp - start_timestamp > 60:
- print( "start hour: "+str(start_hour)+" end hour: "+str(end_hour) )
- print( 'start timestamp: '+str(start_timestamp)+' end timestamp: '+str(end_timestamp) )
- if fetch_minute_timestamp == cache_timestamp:
- print( "already fetched minute "+str(fetch_minute_timestamp) )
- sys.exit()
- for ticker in tickers:
- accumulated_usd[ticker][str(cache_hour_timestamp)] = { 'in': 0, 'out': 0 } #create dict for the cache hour since it might be out of range
- for hour in range(start_hour, end_hour+1):
- accumulated_usd[ticker][str(hour*3600)] = { 'in': 0, 'out': 0 }
- #fill accumulated_usd with data from cache_file
- for ticker in tickers:
- for direction, amount in cache_objs[ticker].items():
- accumulated_usd[ticker][str(cache_hour_timestamp)][direction] = amount
- for ticker in tickers:
- cursor = ''
- done = False
- while not done:
- time.sleep(6) #this is necessary since the API doesnt reset every seccond but cheks for interval between requests
- response = requests.get('https://api.whale-alert.io/v1/transactions?api_key='+apikey+'&min_value=500000&start='+str(start_timestamp)+'&end='+str(end_timestamp)+'¤cy='+ticker+cursor, timeout=4 )
- if response.status_code != 200:
- print('http error: '+str(response.status_code))
- sys.exit()
- response_str = response.text
- response_objs = json.loads(response_str)
- if response_objs['count'] < 100:
- done = True
- else:
- cursor = "&cursor="+response_objs['cursor']
- print( "more than 100 txs between "+str(start_timestamp)+":"+str(end_timestamp) )
- if response_objs['count'] == 0:
- break
- transactions = response_objs['transactions']
- for tx in transactions:
- if tx['transaction_type'] != 'transfer':
- print('weird tx type '+tx['transaction_type']+'-'+tx['symbol'])
- continue
- tx_hour_timestamp = (int(tx['timestamp']) // 3600) * 3600
- tx_usd_amount = int(tx['amount_usd'])
- from_type = tx['from']['owner_type']
- to_type = tx['to']['owner_type']
-
- #ins
- if (to_type == 'exchange') and (from_type == 'unknown'):
- accumulated_usd[ticker][str(tx_hour_timestamp)]['in'] += tx_usd_amount
- #outs
- if (to_type == 'unknown') and (from_type == 'exchange'):
- accumulated_usd[ticker][str(tx_hour_timestamp)]['out'] += tx_usd_amount
- # update cache with current hour
- cache_objs['last-known-minute-timestamp'] = fetch_minute_timestamp
- for ticker in tickers:
- cache_objs[ticker]['in'] = accumulated_usd[ticker][str(fetch_minute_hour_timestamp)]['in']
- cache_objs[ticker]['out'] = accumulated_usd[ticker][str(fetch_minute_hour_timestamp)]['out']
- # remove current hour from accum_usd since it was added to cache
- del accumulated_usd[ticker][str(fetch_minute_hour_timestamp)]
- cache_file = open("dbs/crypto-txs.cache.json", "w")
- json.dump(cache_objs, cache_file)
- cache_file.close()
- # TODO remove this, it doesnt belong on this script
- # update btc net ins cache
- total_ins_btc_cache_file = open(".whale-txs-total-in-btc.cache", "w")
- total_ins_btc_cache_file.write(str( (cache_objs['btc']['in'] - cache_objs['btc']['out'])//1000000 )+"M\n")
- total_ins_btc_cache_file.close()
- # update stables net ins cache
- net_in_stable = 0
- for ticker in stable_tickers:
- net_in_stable += ( (cache_objs[ticker]['in'] - cache_objs[ticker]['out'])//1000000 )
- total_ins_stable_cache_file = open(".whale-txs-total-in-stable.cache", "w")
- total_ins_stable_cache_file.write(str( net_in_stable )+"M\n")
- total_ins_stable_cache_file.close()
- # if remaining hours > 0 load db
- if len(accumulated_usd['btc']) > 0: #all tickers should have the same length
- # for each remaining hour (the ones not added to cache)
- for ticker in tickers:
- db_file = open("dbs/crypto-txs-"+ticker+".db.json", "rb+")
- db_file.seek(-3, 2) # remove the \n}\n
- db_file.write(b",\n")
- for timestamp, accumulator in accumulated_usd[ticker].items():
- usd_in = str(accumulator['in'])
- usd_out = str(accumulator['out'])
- entry_string = '"'+timestamp+'"'+":"+'{"in":'+usd_in+',"out":'+usd_out+'},\n'
- db_file.write( entry_string.encode('utf-8') )
- db_file.seek(-2, 1) #remove ,\n of the last entry
- db_file.write(b"\n}\n")
- db_file.close()
|