diff --git a/json_instrukcja.txt b/json_instrukcja.txt new file mode 100644 index 00000000..9a0c3861 --- /dev/null +++ b/json_instrukcja.txt @@ -0,0 +1,13 @@ +Aplikacja automatycznie generuje i zapisuje dane posiadanych walut portfela jako json. +Można także jednak wgrać do niego dane z zewnątrz mając na uwadze poniższy format: + +{"base_currency": "", +"data": + {"": + {"amount': 0.0, "value": 0.0}}, + "": + {"amount': 0.0, "value": 0.0}} +} + +np.: +{"base_currency": "USD", "data": {"BTC": {"amount": 2.3, "value": 22467.187803234367}, "LTC": {"amount": 0.1, "value": 4.5919}}} \ No newline at end of file diff --git a/wallet.json b/wallet.json new file mode 100644 index 00000000..5055b0bb --- /dev/null +++ b/wallet.json @@ -0,0 +1 @@ +{"base_currency": "USD", "data": {"BTC": {"amount": 2.3, "value": 22467.187803234367}, "LTC": {"amount": 0.1, "value": 4.5919}}} \ No newline at end of file diff --git a/wallet_model.py b/wallet_model.py new file mode 100644 index 00000000..78591856 --- /dev/null +++ b/wallet_model.py @@ -0,0 +1,111 @@ +import requests +import json + +wallet_data = {'base_currency': "", 'data': {}} +database_path = "wallet.json" + +currency_hierarchy = ["USD", "BTC"] + +markets = { + 'bitbay': 'https://api.bitbay.net/rest/trading/ticker', + 'bittrex': 'https://api.bittrex.com/v3/markets', +} + +exchanges = { + 'bitbay': 'https://bitbay.net/API/Public/{0}{1}/orderbook.json', + 'bittrex': 'https://api.bittrex.com/api/v1.1/public/getorderbook?market={1}-{0}&type=both', +} + +def calculate_currency_value(bids, amount): + value = 0.0 + for bid in bids: + rate = min(amount, bid['amount']) + value += rate * bid['value'] + amount -= rate + if amount == 0: + return value + +def update_currencies_values(data=wallet_data): + for currency, cur_info in data['data'].items(): + cur_info['value'] = calculate_currency_value(get_bids(data['base_currency'], currency), cur_info['amount']) + +def check_currency_availability(currency): + for exchange, url in markets.items(): + headers = {'content-type': 'application/json'} + response = requests.request("GET", url, headers=headers) + dic = response.json() + if exchange is "bitbay" and dic['status'] is "Ok": + for market in dic['items']: + if market['market']['first']['currency'] == currency or market['market']['second']['currency'] == currency: + return True + elif exchange is 'bittrex': + for market in dic: + if market['baseCurrencySymbol'] == currency or market['quoteCurrencySymbol'] == currency: + return True + return False + +def get_bids(base_currency, currency): + for exchange, url in exchanges.items(): + formated_url = url.format(currency, base_currency) + headers = {'content-type': 'application/json'} + response = requests.request("GET", formated_url, headers=headers) + dic = response.json() + bids = [] + if exchange is 'bitbay' and 'bids' in dic.keys(): + for bid in dic['bids']: + bids.append({'amount': bid[1], 'value': bid[0]}) + return bids + elif exchange is 'bittrex' and dic['success'] == True: + for bid in dic['result']['sell']: + bids.append({'amount': bid['Quantity'], 'value': bid['Rate']}) + return bids + return None + +def add_currency(currency, amount): + bids = get_bids(wallet_data['base_currency'], currency) + if bids is not None: + value = calculate_currency_value(bids, amount) + wallet_data['data'][currency] = {'amount': amount, 'value': value} + print(wallet_data) + return True + return False + +def remove_currency(currency): + if currency in wallet_data['data']: + del wallet_data['data'][currency] + return True + return False + +def change_currency_amount(currency, amount): + if currency in wallet_data['data']: + wallet_data['data'][currency]['amount'] += amount + if wallet_data['data'][currency]['amount'] < 0.0: + wallet_data['data'][currency]['amount'] = 0.0 + calculate_currency_value(get_bids(wallet_data['base_currency'], wallet_data['data'][currency]['amount'])) + return True + return False + +def set_base_currency(currency): + if check_currency_availability(currency): + wallet_data['base_currency'] = currency + return True + return False + +def get_wallet_data(): + return wallet_data + +def load_database(): + global wallet_data + try: + with open(database_path) as json_file: + wallet_data = json.load(json_file) + if wallet_data['base_currency'] != "": + return True + except OSError: + update_database() + return False + return False + +def update_database(data=wallet_data): + with open(database_path, 'w') as json_file: + json.dump(data, json_file) diff --git a/wallet_presenter.py b/wallet_presenter.py new file mode 100644 index 00000000..f36ceef8 --- /dev/null +++ b/wallet_presenter.py @@ -0,0 +1,64 @@ +import threading +import time +import wallet_viewer as viewer +import wallet_model as wallet + +def add_currency(currency, amount): + if wallet.add_currency(currency, float(amount)): + update_view_display() + else: + viewer.error_display("Currency doesn't exist in this exchange") + +def set_currency(currency, amount): + add_currency(currency, amount) + +def remove_currency(currency): + if wallet.remove_currency(currency): + update_view_display() + else: + viewer.error_display("You don't have such currency") + +def change_currency_amount(currency, amount): + if wallet.change_currency_amount(currency, float(amount)): + update_view_display() + else: + viewer.error_display("You don't have such currency") + +def set_base_currency(currency): + if wallet.set_base_currency(currency): + update_view_display() + else: + viewer.error_display("Currency doesn't exist in this exchange") + viewer.get_base_currency_dialog() + +def update_data(): + wallet.update_database() + +def update_view_display(): + wallet_data = wallet.get_wallet_data() + wallet_display_text = "" + sum = 0 + for currency, info in wallet_data['data'].items(): + wallet_display_text += "{}: {:.4f} | {:.4f} {}\n".format(currency, info['amount'], info['value'], wallet_data['base_currency']) + sum += info['value'] + wallet_display_text += "\n\nIn total: {:.4f} {}".format(sum, wallet_data['base_currency']) + viewer.update_display(wallet_display_text) + +def run(wallet_data): + while True: + time.sleep(5) + wallet.update_database(wallet_data) + wallet.update_currencies_values(wallet_data) + update_view_display() + +def main(): + if wallet.load_database() == True: + wallet.update_currencies_values() + update_view_display() + else: + viewer.get_base_currency_dialog() + threading.Thread(target=run, args=(wallet.get_wallet_data(),)).start() + viewer.create_main_window() + +if __name__ == "__main__": + main() diff --git a/wallet_viewer.py b/wallet_viewer.py new file mode 100644 index 00000000..65111f07 --- /dev/null +++ b/wallet_viewer.py @@ -0,0 +1,59 @@ +from tkinter import simpledialog, messagebox +import wallet_presenter as presenter +import tkinter as tk + + +window = tk.Tk() +wallet_info = tk.StringVar(value="") + +def simple_dialog(msg, function): + output = [] + for request in msg: + output.append(simpledialog.askstring('Data', request, parent=window)) + if output[-1] == None: + return False + function(*output) + return True + +def add_currency_dialog(): + simple_dialog(['Enter the currency you want to add', 'Enter currency amount'], presenter.add_currency) + +def set_currency_dialog(): + simple_dialog(['Enter the currency you want to modify', 'Enter new currency amount'], presenter.set_currency) + +def change_currency_amount_dialog(): + simple_dialog(['Enter the currency you want to modify', 'Enter currency modification amount'], presenter.change_currency_amount) + +def remove_currency_dialog(): + simple_dialog(['Enter the currency u want to remove'], presenter.remove_currency) + +def get_base_currency_dialog(): + currency = simpledialog.askstring('Data', 'Enter the base currency', parent=window) + if currency is not None and currency != '': + presenter.set_base_currency(currency) + +def update_display(wallet_display_text): + basic_info = "Currency: Amount | Value\n" + wallet_info.set(basic_info + wallet_display_text) + +def error_display(error_info): + messagebox.showerror(title="Error", message=error_info) + +def create_main_window(): + window.title("Crypto wallet") + window.geometry("250x250") + + lb_wallet_info = tk.Label(window, textvariable=wallet_info) + btn_add_currency = tk.Button(window, text='Add currency', command=add_currency_dialog) + btn_set_currency = tk.Button(window, text='Set currency amount', command=set_currency_dialog) + btn_change_currency_amount =tk.Button(window, text='Change currency amount', command=change_currency_amount_dialog) + btn_remove_currency = tk.Button(window, text='Remove currency', command=remove_currency_dialog) + btn_change_base_currency = tk.Button(window, text='Change base currency', command=get_base_currency_dialog) + btn_add_currency.pack() + btn_set_currency.pack() + btn_change_currency_amount.pack() + btn_remove_currency.pack() + btn_change_base_currency.pack() + lb_wallet_info.pack() + + window.mainloop()