123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- import json
- from pycoingecko import CoinGeckoAPI
- from rediscluster import RedisCluster
- # from redis import Redis
- import ast
- import requests
- import traceback
- #const
- DEFAULT_PRICE = 0.00000000000000001
- #redis keys
- TOKENPRICE = 'TOKENPRICE_TO_FETCH'
- def get_swap_price(tokens):
- ret_d = {}
- for t in tokens:
- segs = t.split('_')
- chain = segs[0]
- contract = segs[1]
- if chain.strip().upper() == 'bsc':
- price = get_pancakeswap_price(contract)
- if price is not None:
- ret_d[t] = price
- return ret_d
- def get_pancakeswap_price(contract):
- url = f'https://api.pancakeswap.info/api/v2/tokens/{contract}'
- try:
- ret = requests.get(url)
- price = float(ret.json()['data']['price'])
- print(price)
- return price
- except:
- traceback.print_exc()
- return None
- def get_coingecko_price(tokens):
- exceptions = set()
- ret_d = {}
- try:
- cg = CoinGeckoAPI()
- coin_prices = cg.get_price(ids=list(tokens), vs_currencies='usd')
- print(coin_prices)
- for k, v in coin_prices.items():
- if v.get('usd') is None:
- exceptions.add(k)
- continue
- price = v['usd']
- ret_d[k] = price
- except:
- traceback.print_exc()
- print('get_coingecko_price exception tokens', exceptions)
- return ret_d
- def get_tokens():
- tokens = r.smembers(TOKENPRICE)
- tokens = [ast.literal_eval(t) for t in tokens]
- realtime_price_token = set()
- fixed_or_swap_price_token = set()
- for t in tokens:
- if t.get('fixed_price') is None:
- realtime_price_token.add(t.get('coingecko_id'))
- else:
- fixed_or_swap_price_token.add(f"{t.get('chain')}_{t.get('contract')}")
- realtime_price = get_coingecko_price(realtime_price_token) #{'coingecko_id':price}
- swap_price_token = get_swap_price(fixed_or_swap_price_token) #{'chain_contract': price}
- return tokens, realtime_price, swap_price_token
- def merge_price(tokens, realtime_price, swap_price_token):
- ret_d = {}
- exceptions = set()
- for t in tokens:
- chain = t.get('chain')
- contract = t.get('contract')
- coingecko_id = t.get('coingecko_id')
- fixed_price = t.get('fixed_price')
- now_price = realtime_price.get(coingecko_id)
- if now_price is None:
- now_price = swap_price_token.get(f'{chain}_{contract}')
- if now_price is None:
- now_price = fixed_price
- if now_price is None:
- exceptions.add(t)
- else:
- l = ret_d.get(chain, [])
- l.append({'contract': contract_address, 'usdPrice': price})
- ret_d[chain] = l
- print('merge_price exceptions', exceptions)
- return ret_d
- def save_price(prices):
- for chain, token_dict in prices.items():
- r.set(f'{TOKENPRICE}{chain.upper()}', json.dumps({'tokenPrice':token_dict}))
- def _recover_history_data():
- #TODO
- #1. 读取历史数据,修改数据格式,并重新导入
- #2. 对比历史token记录表,筛选是否有丢失数据的情况
- #3. 修改api server接口,以新数据结构存储
- pass
- if __name__ == '__main__':
- tokens, realtime_price, swap_price_token = get_tokens()
- prices = merge_price(tokens, realtime_price, swap_price_token)
- save_price(prices)
|