backtests

This commit is contained in:
Nicolás Sánchez 2024-11-30 20:06:59 -03:00
parent 759b1cf557
commit ad759fe60a
2 changed files with 121 additions and 1 deletions

View File

@ -43,6 +43,7 @@ TRADERS
65) toggle_pause 66) toggle_cleanup 67) toggle_autoswitch 65) toggle_pause 66) toggle_cleanup 67) toggle_autoswitch
68) toggle_check_old_long_price 69) switch_quote_currency 68) toggle_check_old_long_price 69) switch_quote_currency
70) reload_safety_order 71) view_old_long 72) switch_price 70) reload_safety_order 71) view_old_long 72) switch_price
73) backtests
98) Change broker 99) Exit 98) Change broker 99) Exit
''' '''
@ -615,3 +616,24 @@ if __name__=="__main__":
url = f"{base_url}{port}/switch_to_long_price?base={base}&quote={quote}" url = f"{base_url}{port}/switch_to_long_price?base={base}&quote={quote}"
print(json.loads(requests.get(url,headers=headers).content)) print(json.loads(requests.get(url,headers=headers).content))
input("Press ENTER to continue ") input("Press ENTER to continue ")
elif command==73:
print("Returns backtests of the pairs available in an exchange")
broker = input("Exchange? (binance, gateio, kucoin or okx): ")
amount = input("Amount of days to consider? ")
max_rank = input("Maximum CoinMarketCap rank? ")
if not validate_int(amount):
print("The amount of days specified is invalid")
break
if not validate_int(max_rank):
print("The max_rank specified is invalid")
break
if input("Proceed? (Y/n) ") in ["Y","y",""]:
url = f"{base_url}/statistics_server/fetch_backtests?exchange_name={broker}&days={amount}&max_rank={max_rank}"
result = json.loads(requests.get(url,headers=headers).content)
#for item in result:
# print(item, round(result[item],2))
sorted_result = {key: value for key, value in sorted(result.items(),key=lambda item: item[1])}
for item in sorted_result:
print(item, sorted_result[item])
input("Press ENTER to continue ")

View File

@ -2,6 +2,9 @@ import sqlite3
import sys import sys
import datetime import datetime
import time import time
import ccxt
import credentials
import requests
from flask import Flask, jsonify, request from flask import Flask, jsonify, request
@ -32,6 +35,12 @@ hashes_db = {"fetch_last_n_deals":0,
"total_profit_by_pair":0} "total_profit_by_pair":0}
def get_market_caps(limit):
api_key = credentials.get_credentials("CMC")["key"]
url = f"https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?CMC_PRO_API_KEY={api_key}&convert=USD&limit={limit}"
return requests.get(url).json()["data"]
def load_keys_from_db(file_name): def load_keys_from_db(file_name):
#valid_keys = [] #valid_keys = []
@ -219,8 +228,97 @@ def last_n_lines(file_name,width,amount=4,full_log=False):
return result[:amount],len(file_contents) return result[:amount],len(file_contents)
def return_parkinson_backtests(broker, days, max_rank):
'''
Returns a dictionary containing backtests with the format {coin: value}
'''
if broker not in ["binance", "gateio", "kucoin", "okx"]:
return {}
evaluation_dictionary = {}
start_of_day = int(time.mktime(datetime.datetime.now().date().timetuple()))
since = int(start_of_day - 60*60*24*days)
# Getting the data from the database
print("Querying database...")
conn = sqlite3.connect(f"data/{broker}.db")
cursor = conn.cursor()
cursor.execute('SELECT * FROM volatilities_table WHERE timestamp > ?', (since,))
rows = cursor.fetchall()
conn.close()
# Parse the data
print("Parsing the data...")
for row in rows:
if row[0] not in evaluation_dictionary:
evaluation_dictionary[row[0]] = [row[2]]
else:
evaluation_dictionary[row[0]].append(row[2])
#Calculate weighted averages
print("Calculating weighted averages")
weighted_averages = {}
for key in evaluation_dictionary:
multiplier = len(evaluation_dictionary[key])
total = 0
for value in evaluation_dictionary[key][::-1]:
total+=value*multiplier/len(evaluation_dictionary[key])
multiplier-=1
weighted_averages[key] = total/len(evaluation_dictionary[key])
#Filter by rank
print("Filtering results by CMC rank")
coins_accepted = []
market_caps = get_market_caps(max_rank)
for result in market_caps:
coins_accepted.append(result["symbol"])
for coin in weighted_averages.copy():
if coin.split("/")[0] not in coins_accepted:
del(weighted_averages[coin])
#Checking open markets
print("Filtering results by market state")
exchange_class = getattr(ccxt, broker)
broker = exchange_class({
"apiKey": "",
"secret": "",
"timeout": 30000,
"enableRateLimit": True,
'options': {
'newOrderRespType': 'FULL'}
})
markets = broker.load_markets()
for key in weighted_averages.copy():
if key not in markets or not markets[key]["active"]:
del(weighted_averages[key])
return weighted_averages
stats_api = Flask(__name__) stats_api = Flask(__name__)
@stats_api.route("/fetch_backtests")
def fetch_backtests():
'''
GET request
Parameters: 'exchange_name" -> string
'days' -> int
'max_rank' -> int
'''
if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys:
try:
broker = request.args.get("exchange_name")
days = int(request.args.get("days")) # type: ignore
max_rank = int(request.args.get("max_rank")) # type: ignore
return return_parkinson_backtests(broker,days,max_rank)
except Exception as e:
print(e)
return jsonify({"HORROR": f"{e}"})
return jsonify({'Error': 'API key invalid'}), 401
@stats_api.route("/clear_caches") @stats_api.route("/clear_caches")
def clear_hashes(): def clear_hashes():