Compare commits
No commits in common. "1303ee7c5124dd3a6a9b40490613b59adc42829f" and "5c97c721ad040714cceb41b989eb15fd7bf521be" have entirely different histories.
1303ee7c51
...
5c97c721ad
|
|
@ -746,8 +746,6 @@ class broker:
|
||||||
|
|
||||||
order_to_send = self.exchange.create_order(pair,"market",side,amount)
|
order_to_send = self.exchange.create_order(pair,"market",side,amount)
|
||||||
time.sleep(self.wait_time)
|
time.sleep(self.wait_time)
|
||||||
# Wait a bit more when dealing with Kucoin
|
|
||||||
|
|
||||||
return self.get_order(order_to_send["id"],pair)
|
return self.get_order(order_to_send["id"],pair)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.log_this(f"Exception in new_market_order: {e}",1,pair)
|
self.logger.log_this(f"Exception in new_market_order: {e}",1,pair)
|
||||||
|
|
|
||||||
7
main.py
7
main.py
|
|
@ -1687,6 +1687,7 @@ def unwrapped_last_call(base,quote):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if f"{base}{quote}" in broker.get_pairs():
|
if f"{base}{quote}" in broker.get_pairs():
|
||||||
|
#read_config["pairs"].remove(base+quote)
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
if f"{base}/{quote}"==x.pair:
|
if f"{base}/{quote}"==x.pair:
|
||||||
x.stop_when_profit = not x.stop_when_profit
|
x.stop_when_profit = not x.stop_when_profit
|
||||||
|
|
@ -1763,7 +1764,7 @@ def unwrapped_global_last_call():
|
||||||
'''
|
'''
|
||||||
try:
|
try:
|
||||||
if broker.get_pairs!=[]:
|
if broker.get_pairs!=[]:
|
||||||
#broker.clear_pairs()
|
broker.clear_pairs()
|
||||||
for x in running_instances:
|
for x in running_instances:
|
||||||
x.stop_when_profit = True
|
x.stop_when_profit = True
|
||||||
broker.logger.log_this("Modified flag",2,f"{x.base}/{x.quote}")
|
broker.logger.log_this("Modified flag",2,f"{x.base}/{x.quote}")
|
||||||
|
|
@ -1909,11 +1910,11 @@ def unwrapped_toggle_autoswitch(base,quote):
|
||||||
if x.config_dict["autoswitch"]:
|
if x.config_dict["autoswitch"]:
|
||||||
broker.logger.log_this("Autoswitch turned OFF",1,f"{base}/{quote}")
|
broker.logger.log_this("Autoswitch turned OFF",1,f"{base}/{quote}")
|
||||||
x.config_dict["autoswitch"] = False
|
x.config_dict["autoswitch"] = False
|
||||||
return jsonify({"Success": "Autoswitch is now OFF"})
|
return jsonify({"Success": "Autoswitch it's now OFF"})
|
||||||
else:
|
else:
|
||||||
broker.logger.log_this("Autoswitch turned ON",1,f"{base}/{quote}")
|
broker.logger.log_this("Autoswitch turned ON",1,f"{base}/{quote}")
|
||||||
x.config_dict["autoswitch"] = True
|
x.config_dict["autoswitch"] = True
|
||||||
return jsonify({"Success": "Autoswitch is now ON"})
|
return jsonify({"Success": "Autoswitch it's now ON"})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
broker.logger.log_this(f"Exception while toggling autoswitch: {e}",1,f"{base}{quote}")
|
broker.logger.log_this(f"Exception while toggling autoswitch: {e}",1,f"{base}{quote}")
|
||||||
return jsonify({"Error": "Halp"})
|
return jsonify({"Error": "Halp"})
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ cursor.execute("""SELECT strftime('%Y-%m-%d', timestamp, 'unixepoch', '-3 hours'
|
||||||
last_60_days_rows = cursor.fetchall()
|
last_60_days_rows = cursor.fetchall()
|
||||||
|
|
||||||
#Last 30 days query
|
#Last 30 days query
|
||||||
|
#cursor.execute("""SELECT strftime('%Y-%m-%d', timestamp, 'unixepoch', '-3 hours') AS day_utc3,
|
||||||
cursor.execute("""SELECT strftime('%Y-%m-%d', timestamp, 'unixepoch', '-3 hours') AS day_utc3,
|
cursor.execute("""SELECT strftime('%Y-%m-%d', timestamp, 'unixepoch', '-3 hours') AS day_utc3,
|
||||||
SUM(amount) AS total_amount
|
SUM(amount) AS total_amount
|
||||||
FROM profits_table
|
FROM profits_table
|
||||||
|
|
@ -46,15 +47,6 @@ cursor.execute("""SELECT strftime('%Y-%m', timestamp, 'unixepoch', '-3 hours') A
|
||||||
ORDER BY year_month_utc3;""")
|
ORDER BY year_month_utc3;""")
|
||||||
last_n_months_rows = cursor.fetchall()
|
last_n_months_rows = cursor.fetchall()
|
||||||
|
|
||||||
#Last n months query
|
|
||||||
cursor.execute("""SELECT strftime('%Y', timestamp, 'unixepoch', '-3 hours') AS year_utc3,
|
|
||||||
SUM(amount) AS total_amount
|
|
||||||
FROM profits_table
|
|
||||||
WHERE strftime('%s', 'now') - timestamp <= 60 * 30 * 24 * 60 * 60 -- 48 months in seconds
|
|
||||||
GROUP BY year_utc3
|
|
||||||
ORDER BY year_utc3;""")
|
|
||||||
last_n_years_rows = cursor.fetchall()
|
|
||||||
|
|
||||||
#Yearly totals
|
#Yearly totals
|
||||||
cursor.execute("""SELECT strftime('%Y', timestamp, 'unixepoch', '-3 hours') AS year_utc3,
|
cursor.execute("""SELECT strftime('%Y', timestamp, 'unixepoch', '-3 hours') AS year_utc3,
|
||||||
SUM(amount) AS total_amount
|
SUM(amount) AS total_amount
|
||||||
|
|
@ -74,13 +66,7 @@ print("Last 18 months:")
|
||||||
print("-"*line_width)
|
print("-"*line_width)
|
||||||
for row in last_n_months_rows[1:]:
|
for row in last_n_months_rows[1:]:
|
||||||
print(f"{row[0]}: {round(row[1],2)}")
|
print(f"{row[0]}: {round(row[1],2)}")
|
||||||
print("="*line_width)
|
|
||||||
print("Last 5 years:")
|
|
||||||
print("-"*line_width)
|
print("-"*line_width)
|
||||||
for row in last_n_years_rows:
|
|
||||||
print(f"{row[0]}: {round(row[1],2)}")
|
|
||||||
print("-"*line_width)
|
|
||||||
|
|
||||||
print(f"Last 30 days average: {round(last_30_days[0][1]/30,2)}")
|
print(f"Last 30 days average: {round(last_30_days[0][1]/30,2)}")
|
||||||
print(f"Last 7 days average: {round(last_7_days[0][1]/7,2)}")
|
print(f"Last 7 days average: {round(last_7_days[0][1]/7,2)}")
|
||||||
cursor.execute("""SELECT strftime('%Y-%m-%d', timestamp, 'unixepoch', '-3 hours') AS day_utc3,
|
cursor.execute("""SELECT strftime('%Y-%m-%d', timestamp, 'unixepoch', '-3 hours') AS day_utc3,
|
||||||
|
|
@ -139,9 +125,6 @@ for row in by_exchange:
|
||||||
if row[1]=="This Month":
|
if row[1]=="This Month":
|
||||||
okex_amount = row[2]
|
okex_amount = row[2]
|
||||||
|
|
||||||
#Close db
|
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
total_amount = binance_amount+gateio_amount+kucoin_amount+okex_amount
|
total_amount = binance_amount+gateio_amount+kucoin_amount+okex_amount
|
||||||
|
|
||||||
print(f"Binance: {round(binance_amount,2)} USDT ({round(binance_amount/total_amount*100,2)}%)")
|
print(f"Binance: {round(binance_amount,2)} USDT ({round(binance_amount/total_amount*100,2)}%)")
|
||||||
|
|
|
||||||
1
todo.txt
1
todo.txt
|
|
@ -1,5 +1,6 @@
|
||||||
Mandatory:
|
Mandatory:
|
||||||
=========
|
=========
|
||||||
|
0. Mobile app.
|
||||||
1. Stats webpage.
|
1. Stats webpage.
|
||||||
2. Maintain local orderbooks for each trading pair, which enables:
|
2. Maintain local orderbooks for each trading pair, which enables:
|
||||||
2a. Smart order pricing: Prioritization of fill speed over instant profit or vice versa
|
2a. Smart order pricing: Prioritization of fill speed over instant profit or vice versa
|
||||||
|
|
|
||||||
|
|
@ -385,8 +385,6 @@ class trader:
|
||||||
self.status_dict["start_time"]=self.start_time
|
self.status_dict["start_time"]=self.start_time
|
||||||
self.status_dict["deal_start_time"]=self.deal_start_time
|
self.status_dict["deal_start_time"]=self.deal_start_time
|
||||||
self.status_dict["stop_when_profit"]=self.stop_when_profit
|
self.status_dict["stop_when_profit"]=self.stop_when_profit
|
||||||
self.status_dict["autoswitch"]=False
|
|
||||||
if "autoswitch" in self.config_dict:
|
|
||||||
self.status_dict["autoswitch"]=self.config_dict["autoswitch"]
|
self.status_dict["autoswitch"]=self.config_dict["autoswitch"]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.broker.logger.log_this(f"Can't update status dictionary. Exception: {e}",1,self.pair)
|
self.broker.logger.log_this(f"Can't update status dictionary. Exception: {e}",1,self.pair)
|
||||||
|
|
@ -1691,8 +1689,10 @@ class trader:
|
||||||
if old_target-self.status_dict["quote_spent"]>0 and base_left>0 and minimum_switch_price<low_price:
|
if old_target-self.status_dict["quote_spent"]>0 and base_left>0 and minimum_switch_price<low_price:
|
||||||
low_boundary_color = bright_green
|
low_boundary_color = bright_green
|
||||||
low_boundary = '{:.20f}'.format(minimum_switch_price)[:decimals].center(decimals)
|
low_boundary = '{:.20f}'.format(minimum_switch_price)[:decimals].center(decimals)
|
||||||
if self.status_dict["price"]!=0:
|
#Logic for multiplier
|
||||||
multiplier = int(self.status_dict["old_long"]["tp_price"]/self.status_dict["price"])
|
#When adding a trader, this line always throws an exception since status_dict["price"] is not yet populated
|
||||||
|
percentage_to_switch = (self.status_dict["old_long"]["tp_price"]-self.status_dict["price"])*100/self.status_dict["price"]
|
||||||
|
multiplier = int(percentage_to_switch/100)+1
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import json
|
||||||
import credentials
|
import credentials
|
||||||
|
|
||||||
try:
|
try:
|
||||||
earn_api_key = credentials.get_credentials("earn_api_key")["key"]
|
|
||||||
if sys.argv[1]=="--testnet":
|
if sys.argv[1]=="--testnet":
|
||||||
is_testnet = True
|
is_testnet = True
|
||||||
string_to_add = "TESTNET "
|
string_to_add = "TESTNET "
|
||||||
|
|
@ -26,8 +25,6 @@ except Exception as e:
|
||||||
|
|
||||||
headers = {'X-API-KEY': api_key}
|
headers = {'X-API-KEY': api_key}
|
||||||
|
|
||||||
earn_headers = {'X-API-KEY': earn_api_key}
|
|
||||||
|
|
||||||
command_list = f'''{string_to_add}COMMANDS:
|
command_list = f'''{string_to_add}COMMANDS:
|
||||||
|
|
||||||
INSTANCE
|
INSTANCE
|
||||||
|
|
@ -38,14 +35,6 @@ INSTANCE
|
||||||
13) paused_traders 14) fetch_log 15) edit_cooldown_multiplier
|
13) paused_traders 14) fetch_log 15) edit_cooldown_multiplier
|
||||||
16) backtests 17) get_balance
|
16) backtests 17) get_balance
|
||||||
|
|
||||||
EARN
|
|
||||||
31) toggle_pause 32) get_step_size 33) set_step_size
|
|
||||||
34) get_percentage 35) set_percentage 36) get_time_between_subscriptions
|
|
||||||
37) set_time_between_subscriptions 38) get_time_between_redemptions
|
|
||||||
39) set_time_between_redemptions 40) get_minimum_amount_in_trading_account
|
|
||||||
41) set_minimum_amount_in_trading_account 42) get_last_subscription
|
|
||||||
43) get_last_redemption 44) get_total_balance
|
|
||||||
|
|
||||||
TRADERS
|
TRADERS
|
||||||
51) worker_status 52) get_all_worker_status
|
51) worker_status 52) get_all_worker_status
|
||||||
53) add_pair 54) remove_pair 55) restart_pair
|
53) add_pair 54) remove_pair 55) restart_pair
|
||||||
|
|
@ -110,10 +99,6 @@ if __name__=="__main__":
|
||||||
#print("Invalid input")
|
#print("Invalid input")
|
||||||
#sys.exit()
|
#sys.exit()
|
||||||
port = exchanges[selection]
|
port = exchanges[selection]
|
||||||
earn_broker = port[1:]
|
|
||||||
if earn_broker=="okex":
|
|
||||||
earn_broker="okx"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print("DCAv2 COMMANDER")
|
print("DCAv2 COMMANDER")
|
||||||
|
|
@ -147,9 +132,6 @@ if __name__=="__main__":
|
||||||
# break
|
# break
|
||||||
selection = select_exchange(exchanges)
|
selection = select_exchange(exchanges)
|
||||||
port = exchanges[selection]
|
port = exchanges[selection]
|
||||||
earn_broker = port[1:]
|
|
||||||
if earn_broker=="okex":
|
|
||||||
earn_broker="okx"
|
|
||||||
print(f"New exchange selected: {selection}")
|
print(f"New exchange selected: {selection}")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -326,128 +308,6 @@ if __name__=="__main__":
|
||||||
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 ")
|
||||||
|
|
||||||
|
|
||||||
######################
|
|
||||||
######## EARN ########
|
|
||||||
######################
|
|
||||||
|
|
||||||
elif command==31:
|
|
||||||
print("toggle_pause interrupts or resume the subcription and redemption of funds")
|
|
||||||
if input(f"This will toggle the subscription and redemption of funds on {port}. Are you sure? (Y/n) ") in ["Y","y",""]:
|
|
||||||
url = f"{base_url}/earn/toggle_pause"
|
|
||||||
parameters = {"broker": earn_broker}
|
|
||||||
print(json.loads(requests.post(url,headers=earn_headers, json=parameters).content))
|
|
||||||
input("Press ENTER to continue ")
|
|
||||||
|
|
||||||
elif command==32:
|
|
||||||
print("get_step_size returns the step size")
|
|
||||||
url = f"{base_url}/earn/get_step_size?broker={earn_broker}"
|
|
||||||
print(json.loads(requests.get(url,headers=earn_headers).content))
|
|
||||||
input("Press ENTER to continue ")
|
|
||||||
|
|
||||||
elif command==33:
|
|
||||||
print("set_step_size sets the step size")
|
|
||||||
new_step_size = input("New step size? ")
|
|
||||||
if not validate_float_or_int(new_step_size):
|
|
||||||
print("Invalid step size")
|
|
||||||
break
|
|
||||||
if input(f"This will set the step size to {new_step_size}. Are you sure? (Y/n) ") in ["Y","y",""]:
|
|
||||||
url = f"{base_url}/earn/set_step_size"
|
|
||||||
parameters = {"broker": earn_broker, "new_step_size": new_step_size}
|
|
||||||
print(json.loads(requests.post(url,headers=earn_headers, json=parameters).content))
|
|
||||||
input("Press ENTER to continue ")
|
|
||||||
|
|
||||||
elif command==34:
|
|
||||||
print("get_percentage displays the percentage of funds to be allocated to earn")
|
|
||||||
url = f"{base_url}/earn/get_percentage?broker={earn_broker}"
|
|
||||||
print(json.loads(requests.get(url,headers=earn_headers).content))
|
|
||||||
input("Press ENTER to continue ")
|
|
||||||
|
|
||||||
elif command==35:
|
|
||||||
print("set_percentage sets the percentage of funds to be allocated to earn")
|
|
||||||
new_percentage = input("New percentage? ")
|
|
||||||
if not validate_float_or_int(new_percentage):
|
|
||||||
print("Invalid percentage")
|
|
||||||
break
|
|
||||||
if input(f"This will set the percentage to {new_percentage}. Are you sure? (Y/n) ") in ["Y","y",""]:
|
|
||||||
url = f"{base_url}/earn/set_percentage"
|
|
||||||
parameters = {"broker": earn_broker, "new_percentage": new_percentage}
|
|
||||||
print(json.loads(requests.post(url,headers=earn_headers, json=parameters).content))
|
|
||||||
input("Press ENTER to continue ")
|
|
||||||
|
|
||||||
elif command==36:
|
|
||||||
print("get_time_between_subscriptions displays the time to wait between subscriptions")
|
|
||||||
url = f"{base_url}/earn/get_time_between_subscriptions?broker={earn_broker}"
|
|
||||||
print(json.loads(requests.get(url,headers=earn_headers).content))
|
|
||||||
input("Press ENTER to continue ")
|
|
||||||
|
|
||||||
elif command==37:
|
|
||||||
print("set_time_between_subscriptions sets the time to wait between subscriptions")
|
|
||||||
new_time_between_subscriptions = input("New time between subscriptions? ")
|
|
||||||
if not validate_int(new_time_between_subscriptions):
|
|
||||||
print("Invalid time")
|
|
||||||
break
|
|
||||||
if input(f"This will set the time to wait between subscriptions to {new_time_between_subscriptions}. Are you sure? (Y/n) ") in ["Y","y",""]:
|
|
||||||
url = f"{base_url}/earn/set_time_between_subscriptions"
|
|
||||||
parameters = {"broker": earn_broker, "new_time_between_subscriptions": new_time_between_subscriptions}
|
|
||||||
print(json.loads(requests.post(url,headers=earn_headers, json=parameters).content))
|
|
||||||
input("Press ENTER to continue ")
|
|
||||||
|
|
||||||
elif command==38:
|
|
||||||
print("get_time_between_redemptions displays the time to wait between redemptions")
|
|
||||||
url = f"{base_url}/earn/get_time_between_redemptions?broker={earn_broker}"
|
|
||||||
print(json.loads(requests.get(url,headers=earn_headers).content))
|
|
||||||
input("Press ENTER to continue ")
|
|
||||||
|
|
||||||
elif command==39:
|
|
||||||
print("set_time_between_redemptions sets the time to wait between redemptions")
|
|
||||||
new_time_between_redemptions = input("New time between redemptions? ")
|
|
||||||
if not validate_int(new_time_between_redemptions):
|
|
||||||
print("Invalid time")
|
|
||||||
break
|
|
||||||
if input(f"This will set the time to wait between redemptions to {new_time_between_redemptions}. Are you sure? (Y/n) ") in ["Y","y",""]:
|
|
||||||
url = f"{base_url}/earn/set_time_between_redemptions"
|
|
||||||
parameters = {"broker": earn_broker, "new_time_between_redemptions": new_time_between_redemptions}
|
|
||||||
print(json.loads(requests.post(url,headers=earn_headers, json=parameters).content))
|
|
||||||
input("Press ENTER to continue ")
|
|
||||||
|
|
||||||
elif command==40:
|
|
||||||
print("get_minimum_amount_in_trading_account displays the minimum amount of funds that always have to exist in the trading account")
|
|
||||||
url = f"{base_url}/earn/get_minimum_amount_in_trading_account?broker={earn_broker}"
|
|
||||||
print(json.loads(requests.get(url,headers=earn_headers).content))
|
|
||||||
input("Press ENTER to continue ")
|
|
||||||
|
|
||||||
elif command==41:
|
|
||||||
print("set_minimum_amount_in_trading_account sets the minimum amount of funds that always have to exist in the trading account")
|
|
||||||
new_minimum_amount_in_trading_account = input("New minimum amount in trading account? ")
|
|
||||||
if not validate_int(new_minimum_amount_in_trading_account):
|
|
||||||
print("Invalid amount")
|
|
||||||
break
|
|
||||||
if input(f"This will set the minimum amount of funds that always have to exist in the trading account to {new_minimum_amount_in_trading_account}. Are you sure? (Y/n) ") in ["Y","y",""]:
|
|
||||||
url = f"{base_url}/earn/set_minimum_amount_in_trading_account"
|
|
||||||
parameters = {"broker": earn_broker, "new_minimum_amount_in_trading_account": new_minimum_amount_in_trading_account}
|
|
||||||
print(json.loads(requests.post(url,headers=earn_headers, json=parameters).content))
|
|
||||||
input("Press ENTER to continue ")
|
|
||||||
|
|
||||||
elif command==42:
|
|
||||||
print("get_last_subscription display the last subscription")
|
|
||||||
url = f"{base_url}/earn/get_last_subscription?broker={earn_broker}"
|
|
||||||
print(json.loads(requests.get(url,headers=earn_headers).content))
|
|
||||||
input("Press ENTER to continue ")
|
|
||||||
|
|
||||||
elif command==43:
|
|
||||||
print("get_last_redemptions displays the last redemption")
|
|
||||||
url = f"{base_url}/earn/get_last_redemption?broker={earn_broker}"
|
|
||||||
print(json.loads(requests.get(url,headers=earn_headers).content))
|
|
||||||
input("Press ENTER to continue ")
|
|
||||||
|
|
||||||
elif command==44:
|
|
||||||
print("get_total_balance displays the trading account balance and the earning account balance")
|
|
||||||
url = f"{base_url}/earn/get_total_balance?broker={earn_broker}"
|
|
||||||
print(json.loads(requests.get(url,headers=earn_headers).content))
|
|
||||||
input("Press ENTER to continue ")
|
|
||||||
|
|
||||||
|
|
||||||
######################
|
######################
|
||||||
####### TRADER #######
|
####### TRADER #######
|
||||||
######################
|
######################
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import datetime
|
||||||
import time
|
import time
|
||||||
import ccxt
|
import ccxt
|
||||||
import credentials
|
import credentials
|
||||||
import calendar
|
|
||||||
import requests
|
import requests
|
||||||
import logging
|
import logging
|
||||||
from flask import Flask, jsonify, request
|
from flask import Flask, jsonify, request
|
||||||
|
|
@ -60,126 +59,6 @@ def load_keys_from_db(file_name):
|
||||||
return valid_keys
|
return valid_keys
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def profit_report():
|
|
||||||
##Queries
|
|
||||||
connection = sqlite3.connect(profits_database)
|
|
||||||
cursor = connection.cursor()
|
|
||||||
#Last 60 days query
|
|
||||||
cursor.execute("""SELECT strftime('%Y-%m-%d', timestamp, 'unixepoch', '-3 hours') AS day_utc3,
|
|
||||||
SUM(amount) AS total_amount
|
|
||||||
FROM profits_table
|
|
||||||
WHERE strftime('%s', 'now') - timestamp <= 60 * 24 * 60 * 60 -- 60 days in seconds
|
|
||||||
GROUP BY day_utc3
|
|
||||||
ORDER BY day_utc3;""")
|
|
||||||
last_60_days_rows = cursor.fetchall()
|
|
||||||
#Last 30 days query
|
|
||||||
#cursor.execute("""SELECT strftime('%Y-%m-%d', timestamp, 'unixepoch', '-3 hours') AS day_utc3,
|
|
||||||
cursor.execute("""SELECT strftime('%Y-%m-%d', timestamp, 'unixepoch', '-3 hours') AS day_utc3,
|
|
||||||
SUM(amount) AS total_amount
|
|
||||||
FROM profits_table
|
|
||||||
WHERE strftime('%s', 'now') - timestamp <= 30 * 24 * 60 * 60 -- 30 days in seconds;""")
|
|
||||||
last_30_days = cursor.fetchall()
|
|
||||||
#Last 7 days query
|
|
||||||
cursor.execute("""SELECT strftime('%Y-%m-%d', timestamp, 'unixepoch', '-3 hours') AS day_utc3,
|
|
||||||
SUM(amount) AS total_amount
|
|
||||||
FROM profits_table
|
|
||||||
WHERE strftime('%s', 'now') - timestamp <= 7 * 24 * 60 * 60 -- 7 days in seconds;""")
|
|
||||||
last_7_days = cursor.fetchall()
|
|
||||||
#Last n months query
|
|
||||||
cursor.execute("""SELECT strftime('%Y-%m', timestamp, 'unixepoch', '-3 hours') AS year_month_utc3,
|
|
||||||
SUM(amount) AS total_amount
|
|
||||||
FROM profits_table
|
|
||||||
WHERE strftime('%s', 'now') - timestamp <= 18 * 30 * 24 * 60 * 60 -- 18 months in seconds
|
|
||||||
GROUP BY year_month_utc3
|
|
||||||
ORDER BY year_month_utc3;""")
|
|
||||||
last_n_months_rows = cursor.fetchall()
|
|
||||||
#Yearly totals
|
|
||||||
cursor.execute("""SELECT strftime('%Y', timestamp, 'unixepoch', '-3 hours') AS year_utc3,
|
|
||||||
SUM(amount) AS total_amount
|
|
||||||
FROM profits_table
|
|
||||||
WHERE strftime('%s', 'now') - timestamp <= 24 * 365 * 60 * 60 -- 365 days in seconds
|
|
||||||
GROUP BY year_utc3
|
|
||||||
ORDER BY year_utc3;""")
|
|
||||||
yearly_totals = cursor.fetchall()
|
|
||||||
#Per exchange
|
|
||||||
cursor.execute("""SELECT
|
|
||||||
exchange_name,
|
|
||||||
CASE
|
|
||||||
WHEN strftime('%Y-%m', timestamp, 'unixepoch', '-3 hours') = strftime('%Y-%m', 'now', 'localtime') THEN 'This Month'
|
|
||||||
WHEN strftime('%Y-%m', timestamp, 'unixepoch', '-3 hours') = strftime('%Y-%m', 'now', 'localtime', '-1 month') THEN 'Last Month'
|
|
||||||
ELSE 'Other Months'
|
|
||||||
END AS month_group,
|
|
||||||
SUM(amount) AS total_amount
|
|
||||||
FROM
|
|
||||||
profits_table
|
|
||||||
WHERE
|
|
||||||
strftime('%s', 'now') - timestamp <= 60 * 24 * 60 * 60 -- 60 days in seconds
|
|
||||||
GROUP BY
|
|
||||||
exchange_name, month_group
|
|
||||||
ORDER BY
|
|
||||||
exchange_name, month_group;""")
|
|
||||||
per_exchange = cursor.fetchall()
|
|
||||||
|
|
||||||
#Close db
|
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
|
|
||||||
#Projection calculation
|
|
||||||
days_in_month = calendar.monthrange(datetime.date.today().year, datetime.date.today().month)[1]
|
|
||||||
daily_combined_media = (last_30_days[0][1]/30+last_7_days[0][1]/7)/2
|
|
||||||
current_amount = last_n_months_rows[-1][1]
|
|
||||||
days_past_this_month = int(last_60_days_rows[-1][0][8:10])
|
|
||||||
|
|
||||||
#Per exchange
|
|
||||||
binance_amount = 0
|
|
||||||
gateio_amount = 0
|
|
||||||
kucoin_amount = 0
|
|
||||||
okex_amount = 0
|
|
||||||
|
|
||||||
for row in per_exchange:
|
|
||||||
if row[0]=="binance":
|
|
||||||
if row[1]=="This Month":
|
|
||||||
binance_amount = row[2]
|
|
||||||
elif row[0]=="gateio":
|
|
||||||
if row[1]=="This Month":
|
|
||||||
gateio_amount = row[2]
|
|
||||||
elif row[0]=="kucoin":
|
|
||||||
if row[1]=="This Month":
|
|
||||||
kucoin_amount = row[2]
|
|
||||||
elif row[0]=="okex":
|
|
||||||
if row[1]=="This Month":
|
|
||||||
okex_amount = row[2]
|
|
||||||
|
|
||||||
total_amount = binance_amount+gateio_amount+kucoin_amount+okex_amount
|
|
||||||
|
|
||||||
last_60_days_result = {row[0]: round(row[1],2) for row in last_60_days_rows}
|
|
||||||
last_18_months_result = {row[0]: round(row[1],2) for row in last_n_months_rows}
|
|
||||||
last_30_days_average = last_30_days[0][1]/30
|
|
||||||
last_7_days_average = last_7_days[0][1]/7
|
|
||||||
this_month_projection = current_amount + daily_combined_media*(days_in_month-days_past_this_month)
|
|
||||||
binance_percentage = binance_amount/total_amount*100
|
|
||||||
gateio_percentage = gateio_amount/total_amount*100
|
|
||||||
kucoin_percentage = kucoin_amount/total_amount*100
|
|
||||||
okex_percentage = okex_amount/total_amount*100
|
|
||||||
|
|
||||||
return {"Last 60 days": last_60_days_result,
|
|
||||||
"Last 18 months": last_18_months_result,
|
|
||||||
"Last 30 days average": last_30_days_average,
|
|
||||||
"Last 7 days average": last_7_days_average,
|
|
||||||
"This month projection": this_month_projection,
|
|
||||||
"Binance": binance_amount,
|
|
||||||
"Binance percentage": binance_percentage,
|
|
||||||
"Gateio": gateio_amount,
|
|
||||||
"Gateio percentage": gateio_percentage,
|
|
||||||
"Kucoin": kucoin_amount,
|
|
||||||
"Kucoin percentage": kucoin_percentage,
|
|
||||||
"OKX": okex_amount,
|
|
||||||
"OKX percentage": okex_percentage,
|
|
||||||
"Total profit": total_amount}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def query_total_profit(pair=None):
|
def query_total_profit(pair=None):
|
||||||
'''
|
'''
|
||||||
Returns total profit of the trading pair.
|
Returns total profit of the trading pair.
|
||||||
|
|
@ -441,23 +320,6 @@ def fetch_backtests():
|
||||||
return jsonify({'Error': 'API key invalid'}), 401
|
return jsonify({'Error': 'API key invalid'}), 401
|
||||||
|
|
||||||
|
|
||||||
@stats_api.route("/fetch_profit_report")
|
|
||||||
def fetch_profit_report():
|
|
||||||
'''
|
|
||||||
GET request
|
|
||||||
Parameters: None
|
|
||||||
Returns: JSON object with profit report data
|
|
||||||
'''
|
|
||||||
|
|
||||||
if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys:
|
|
||||||
try:
|
|
||||||
return jsonify(profit_report())
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
return jsonify({"Error": 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():
|
||||||
global hashes_db
|
global hashes_db
|
||||||
|
|
@ -533,8 +395,6 @@ def fetch_full_log():
|
||||||
'''
|
'''
|
||||||
GET request
|
GET request
|
||||||
Parameters: 'exchange_name" -> string
|
Parameters: 'exchange_name" -> string
|
||||||
|
|
||||||
It trims the full log to 200 lines, to avoid sending too much data to the client.
|
|
||||||
'''
|
'''
|
||||||
if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys:
|
if "X-API-KEY" in request.headers and request.headers.get("X-API-KEY") in valid_keys:
|
||||||
try:
|
try:
|
||||||
|
|
@ -542,11 +402,11 @@ def fetch_full_log():
|
||||||
width = 0
|
width = 0
|
||||||
last_lines,amount_of_lines = last_n_lines(f"../logs/{exchange_name}.log",width,0,full_log=True)
|
last_lines,amount_of_lines = last_n_lines(f"../logs/{exchange_name}.log",width,0,full_log=True)
|
||||||
if not cache_requests:
|
if not cache_requests:
|
||||||
return jsonify({"line": last_lines[-200:], "amount_of_lines": amount_of_lines})
|
return jsonify({"line": last_lines, "amount_of_lines": amount_of_lines})
|
||||||
response_hash = hash(str({"line": last_lines, "amount_of_lines": amount_of_lines}))
|
response_hash = hash(str({"line": last_lines, "amount_of_lines": amount_of_lines}))
|
||||||
if hashes_db["fetch_full_log"]!=response_hash:
|
if hashes_db["fetch_full_log"]!=response_hash:
|
||||||
hashes_db["fetch_full_log"] = response_hash
|
hashes_db["fetch_full_log"] = response_hash
|
||||||
return jsonify({"line": last_lines[-200:], "amount_of_lines": amount_of_lines})
|
return jsonify({"line": last_lines, "amount_of_lines": amount_of_lines})
|
||||||
return jsonify({"no_changes": True})
|
return jsonify({"no_changes": True})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue