forked from pwillworth/dfkreport
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprices.py
executable file
·167 lines (157 loc) · 6.88 KB
/
prices.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/usr/bin/env python3
# Price data resources
import requests
import sys
import json
import datetime
import logging
import decimal
import db
token_map = {
'0xcF664087a5bB0237a0BAd6742852ec6c8d69A27a': 'harmony',
'0x72Cb10C6bfA5624dD07Ef608027E366bd690048F': 'defi-kingdoms',
'0x985458E523dB3d53125813eD68c274899e9DfAb4': 'usd-coin',
'0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7': 'avalanche-2',
'0xb12c13e66AdE1F72f71834f2FC5082Db8C091358': 'avalanche-2',
'0x4f60a160D8C2DDdaAfe16FCC57566dB84D674BD6': 'defi-kingdoms'
}
def priceLookup(timestamp, token, fiatType='usd'):
lookupDate = datetime.date.fromtimestamp(timestamp).strftime('%d-%m-%Y')
# if token is in map, switch to gecko token name instead
if token in token_map:
token = token_map[token]
# TODO - if fail to lookup price in DFK graph, try to get current price as fallback, but do not store
return decimal.Decimal(getPrice(token, lookupDate, fiatType))
# Date format DD-MM-YYYY for da gecko api
def fetchPriceData(token, date):
realDate = datetime.datetime.strptime(date, '%d-%m-%Y')
# Coin Gecko only has prices from October 20th 2021 forward for JEWEL
if (realDate > datetime.datetime.strptime('19-10-2021', '%d-%m-%Y') or token != 'defi-kingdoms') and token[0] != '0':
gecko_uri = "https://api.coingecko.com/api/v3/coins/{0}/history?date={1}&localization=false".format(token, date)
r = requests.get(gecko_uri)
if r.status_code == 200:
result = r.json()
prices = result['market_data']['current_price']
marketcap = result['market_data']['market_cap']
volume = result['market_data']['total_volume']
db.savePriceData(date, token, json.dumps(prices), json.dumps(marketcap), json.dumps(volume))
logging.info('Saved a new price for {0} on {1} from coin gecko'.format(token, date))
result = prices
else:
result = "Error: failed to get prices - {0}".format(r.text)
logging.error(result + '\n')
else:
# Lookup up price in DFK graph for some stuff
result = fetchItemPrice(token, date)
return result
# Get price of stuff from DFK dex graph for stuff that is not listed on CoinGecko or for coins before they were there
def fetchItemPrice(token, date):
# adjust for graphql inputs
realDate = int(datetime.datetime.strptime(date, '%d-%m-%Y').timestamp())
#### temporarily don't try to lookup from 12/19 forward because it will fail, graph empty
#if realDate >= int(datetime.datetime.strptime('19-12-2021', '%d-%m-%Y').timestamp()):
# return json.loads('{ "usd" : 0.0 }')
#####
spreadDate = realDate + 86401
graphToken = token
if token == 'defi-kingdoms':
graphToken = '0x72Cb10C6bfA5624dD07Ef608027E366bd690048F'
query = """query {
tokenDayDatas(
where: {date_gt: %d
date_lt: %d
token: "%s" }
)
{
priceUSD
totalLiquidityUSD
dailyVolumeUSD
}
}
"""
data = query % (realDate, spreadDate, graphToken.lower())
graph_uri = "http://graph3.defikingdoms.com/subgraphs/name/defikingdoms/dex"
r = requests.post(graph_uri, json={'query': data})
if r.status_code == 200:
result = r.json()
if len(result['data']['tokenDayDatas']) > 0:
price = result['data']['tokenDayDatas'][0]['priceUSD']
liquid = result['data']['tokenDayDatas'][0]['totalLiquidityUSD']
volume = result['data']['tokenDayDatas'][0]['dailyVolumeUSD']
db.savePriceData(date, token, '{ "usd" : %s }' % price, '{ "usd" : %s }' % liquid, '{ "usd" : %s }' % volume)
logging.info('Saved a new price for {0} on {1} from DFK Graph'.format(token, date))
result = json.loads('{ "usd" : %s }' % price)
else:
logging.error('Failed to lookup a price for {0} on {1}, trying current price'.format(token, date))
# last ditch effort, try to find a current price pair data with jewel and base on jewel to USD
jewelPair = fetchCurrentPrice(token, '0x72cb10c6bfa5624dd07ef608027e366bd690048f')
price = 0
if len(jewelPair) == 2:
jewelPrice = priceLookup(realDate, '0x72Cb10C6bfA5624dD07Ef608027E366bd690048F')
logging.debug('got current price ' + str(jewelPair[1]))
price = decimal.Decimal(jewelPair[1]) * jewelPrice
result = json.loads('{ "usd" : %s }' % price)
else:
result = json.loads('{ "usd" : 0.0 }')
else:
result = "Error: failed to get prices - {0} {1}".format(str(r.status_code), r.text)
logging.error(result)
result = json.loads('{ "usd" : 0.0 }')
return result
# Just get current prices on a pair
def fetchCurrentPrice(token0, token1):
query = """query {
pairs(
where: {token0: "%s"
token1: "%s" }
)
{
id
token0Price
token1Price
}
}
"""
data = query % (token0.lower(), token1.lower())
graph_uri = "http://graph3.defikingdoms.com/subgraphs/name/defikingdoms/dex"
r = requests.post(graph_uri, json={'query': data})
if r.status_code == 200:
result = r.json()
if len(result['data']['pairs']) > 0:
price0 = result['data']['pairs'][0]['token0Price']
price1 = result['data']['pairs'][0]['token1Price']
result = [price0, price1]
else:
# TODO: Update this to be able to fetch for Gold paired quest rewards
logging.error('Failed to lookup a price for {0} / {1}'.format(token0, token1))
result = []
else:
result = "Error: failed to get prices - {0} {1}".format(str(r.status_code), r.text)
logging.error(result)
result = []
return result
def getPrice(token, date, fiatType='usd'):
row = db.findPriceData(date, token)
if row != None:
logging.debug('Found existing price to use in database')
prices = json.loads(row[2])
else:
prices = fetchPriceData(token, date)
if fiatType in prices:
return prices[fiatType]
else:
logging.error('Failed to lookup a price for {0} on {1}: {2}'.format(token, date, prices))
return -1
def main():
# Initialize database and ensure price history is pre-populated
db.createDatabase()
startDate = datetime.datetime.strptime('01-01-2021', '%d-%m-%Y')
endDate = datetime.datetime.strptime('15-12-2021', '%d-%m-%Y')
sys.stdout.write(str(getPrice('0x3a4edcf3312f44ef027acfd8c21382a5259936e7', endDate.strftime('%d-%m-%Y'))))
#while startDate <= endDate:
# sys.stdout.write(getPrice('harmony', startDate.strftime('%d-%m-%Y'), 'usd'))
# sys.stdout.write(startDate)
# startDate += datetime.timedelta(days=1)
# time.sleep(10)
if __name__ == "__main__":
main()