get-crypto-txs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #!/usr/bin/python3.6
  2. import sys
  3. import time
  4. import requests
  5. import json
  6. key_file = open('whale-alert-api-key', 'r')
  7. apikey = key_file.read()[:-1]
  8. key_file.close()
  9. tickers = ['btc', 'eth', 'usdc', 'usdt']
  10. stable_tickers = ['usdc','usdt']
  11. accumulated_usd = {} # [ticker][timestamp][direction] : [btc][123091820938][out]
  12. for ticker in tickers:
  13. accumulated_usd[ticker] = {}
  14. total_usd_unknown_to_exchange = {}
  15. total_txs_unknown_to_exchange = {}
  16. current_second_timestamp = int(time.time())
  17. current_minute = current_second_timestamp // 60
  18. current_hour = current_second_timestamp // 3600
  19. fetch_minute = current_minute-12 #fetch transactions from the minute - 12 since thats the maximum time it takes for a block to be mined
  20. fetch_minute_timestamp = 60*fetch_minute
  21. fetch_minute_hour = fetch_minute_timestamp // 3600 #the hour that this minute belongs to
  22. fetch_minute_hour_timestamp = fetch_minute_hour*3600
  23. cache_file = open("dbs/crypto-txs.cache.json", "r")
  24. cache_objs = json.load(cache_file)
  25. cache_file.close()
  26. # determine the interval to fetch
  27. # start should be > cache file, > (fetch_minute - 40)
  28. allowed_timestamp = (fetch_minute - 40)*60
  29. cache_timestamp = cache_objs["last-known-minute-timestamp"]
  30. cache_hour_timestamp = (cache_timestamp // 3600) * 3600
  31. start_timestamp = max(cache_timestamp+60,allowed_timestamp)
  32. end_timestamp = fetch_minute_timestamp + 60
  33. start_hour = start_timestamp // 3600
  34. end_hour = fetch_minute_timestamp // 3600
  35. if end_timestamp - start_timestamp > 60:
  36. print( "start hour: "+str(start_hour)+" end hour: "+str(end_hour) )
  37. print( 'start timestamp: '+str(start_timestamp)+' end timestamp: '+str(end_timestamp) )
  38. if fetch_minute_timestamp == cache_timestamp:
  39. print( "already fetched minute "+str(fetch_minute_timestamp) )
  40. sys.exit()
  41. for ticker in tickers:
  42. accumulated_usd[ticker][str(cache_hour_timestamp)] = { 'in': 0, 'out': 0 } #create dict for the cache hour since it might be out of range
  43. for hour in range(start_hour, end_hour+1):
  44. accumulated_usd[ticker][str(hour*3600)] = { 'in': 0, 'out': 0 }
  45. #fill accumulated_usd with data from cache_file
  46. for ticker in tickers:
  47. for direction, amount in cache_objs[ticker].items():
  48. accumulated_usd[ticker][str(cache_hour_timestamp)][direction] = amount
  49. for ticker in tickers:
  50. cursor = ''
  51. done = False
  52. while not done:
  53. time.sleep(6) #this is necessary since the API doesnt reset every seccond but cheks for interval between requests
  54. response = requests.get('https://api.whale-alert.io/v1/transactions?api_key='+apikey+'&min_value=500000&start='+str(start_timestamp)+'&end='+str(end_timestamp)+'&currency='+ticker+cursor, timeout=4 )
  55. if response.status_code != 200:
  56. print('http error: '+str(response.status_code))
  57. sys.exit()
  58. response_str = response.text
  59. response_objs = json.loads(response_str)
  60. if response_objs['count'] < 100:
  61. done = True
  62. else:
  63. cursor = "&cursor="+response_objs['cursor']
  64. print( "more than 100 txs between "+str(start_timestamp)+":"+str(end_timestamp) )
  65. if response_objs['count'] == 0:
  66. break
  67. transactions = response_objs['transactions']
  68. for tx in transactions:
  69. if tx['transaction_type'] != 'transfer':
  70. print('weird tx type '+tx['transaction_type']+'-'+tx['symbol'])
  71. continue
  72. tx_hour_timestamp = (int(tx['timestamp']) // 3600) * 3600
  73. tx_usd_amount = int(tx['amount_usd'])
  74. from_type = tx['from']['owner_type']
  75. to_type = tx['to']['owner_type']
  76. #ins
  77. if (to_type == 'exchange') and (from_type == 'unknown'):
  78. accumulated_usd[ticker][str(tx_hour_timestamp)]['in'] += tx_usd_amount
  79. #outs
  80. if (to_type == 'unknown') and (from_type == 'exchange'):
  81. accumulated_usd[ticker][str(tx_hour_timestamp)]['out'] += tx_usd_amount
  82. # update cache with current hour
  83. cache_objs['last-known-minute-timestamp'] = fetch_minute_timestamp
  84. for ticker in tickers:
  85. cache_objs[ticker]['in'] = accumulated_usd[ticker][str(fetch_minute_hour_timestamp)]['in']
  86. cache_objs[ticker]['out'] = accumulated_usd[ticker][str(fetch_minute_hour_timestamp)]['out']
  87. # remove current hour from accum_usd since it was added to cache
  88. del accumulated_usd[ticker][str(fetch_minute_hour_timestamp)]
  89. cache_file = open("dbs/crypto-txs.cache.json", "w")
  90. json.dump(cache_objs, cache_file)
  91. cache_file.close()
  92. # TODO remove this, it doesnt belong on this script
  93. # update btc net ins cache
  94. total_ins_btc_cache_file = open(".whale-txs-total-in-btc.cache", "w")
  95. total_ins_btc_cache_file.write(str( (cache_objs['btc']['in'] - cache_objs['btc']['out'])//1000000 )+"M\n")
  96. total_ins_btc_cache_file.close()
  97. # update stables net ins cache
  98. net_in_stable = 0
  99. for ticker in stable_tickers:
  100. net_in_stable += ( (cache_objs[ticker]['in'] - cache_objs[ticker]['out'])//1000000 )
  101. total_ins_stable_cache_file = open(".whale-txs-total-in-stable.cache", "w")
  102. total_ins_stable_cache_file.write(str( net_in_stable )+"M\n")
  103. total_ins_stable_cache_file.close()
  104. # if remaining hours > 0 load db
  105. if len(accumulated_usd['btc']) > 0: #all tickers should have the same length
  106. # for each remaining hour (the ones not added to cache)
  107. for ticker in tickers:
  108. db_file = open("dbs/crypto-txs-"+ticker+".db.json", "rb+")
  109. db_file.seek(-3, 2) # remove the \n}\n
  110. db_file.write(b",\n")
  111. for timestamp, accumulator in accumulated_usd[ticker].items():
  112. usd_in = str(accumulator['in'])
  113. usd_out = str(accumulator['out'])
  114. entry_string = '"'+timestamp+'"'+":"+'{"in":'+usd_in+',"out":'+usd_out+'},\n'
  115. db_file.write( entry_string.encode('utf-8') )
  116. db_file.seek(-2, 1) #remove ,\n of the last entry
  117. db_file.write(b"\n}\n")
  118. db_file.close()