From b28ef40e284b0300459af2943368c6a89ea6cc4c Mon Sep 17 00:00:00 2001 From: Elunniva Date: Sat, 25 Apr 2020 21:12:21 +0200 Subject: [PATCH 1/8] added stockApi --- StockApi/stockApi.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 StockApi/stockApi.py diff --git a/StockApi/stockApi.py b/StockApi/stockApi.py new file mode 100644 index 00000000..a5d75503 --- /dev/null +++ b/StockApi/stockApi.py @@ -0,0 +1,38 @@ +import requests +from time import sleep + +markets = ["BTC-LTC", "BTC-DGB", "BTC-HIVE"] + + +def get_buy_sell_list(market): + url = "https://api.bittrex.com/api/v1.1/public/getticker?market="+market + resp = requests.get(url) + data = resp.json() + return data['result']['Bid'], data['result']['Ask'] + + +def print_buy_sell_list(): + for market in markets: + data = get_buy_sell_list(market) + print(market, 'Buy', data[1], 'Sell', data[0]) + + +def get_buy_sell_percent_diff(data): + return 1-(data[1]-data[0])/data[0] + + +def print_buy_sell_percent(): + for market in markets: + percent = get_buy_sell_percent_diff(get_buy_sell_list(market)) + print(market, percent) + + +def update_percent_list(): + while True: + print_buy_sell_percent() + sleep(5) + + +# print_buy_sell_list() +# print_buy_sell_percent() +update_percent_list() From bb0a6076399ea9209ba88fb055e242f3c7ba8469 Mon Sep 17 00:00:00 2001 From: Elunniva Date: Fri, 8 May 2020 21:02:23 +0200 Subject: [PATCH 2/8] changed to 4 apis --- StockApi/stockApi.py | 60 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/StockApi/stockApi.py b/StockApi/stockApi.py index a5d75503..a45ac1c3 100644 --- a/StockApi/stockApi.py +++ b/StockApi/stockApi.py @@ -1,16 +1,63 @@ import requests from time import sleep -markets = ["BTC-LTC", "BTC-DGB", "BTC-HIVE"] +markets = [ + ('BTC', 'USD'), + ('LTC', 'BTC'), + ('XRP', 'BTC'), + ('ETH', 'BTC'), +] +apis = [ + 'bittrex', + 'bitbay', + 'bitfinex', + 'bitstamp', +] -def get_buy_sell_list(market): - url = "https://api.bittrex.com/api/v1.1/public/getticker?market="+market +taker = { + +} + +urls = { + 'bittrex': 'https://api.bittrex.com/api/v1.1/public/getorderbook?market={1}-{0}&type=both', + 'bitbay': 'https://bitbay.net/API/Public/{0}{1}/orderbook.json', + 'bitfinex': 'https://api-pub.bitfinex.com/v2/book/t{0}{1}/P0?len=1', + 'bitstamp': 'https://www.bitstamp.net/api/v2/order_book/{0}{1}', +} + + +def get_buy_sell_list(api, market): + if api == 'bitstamp': + url = urls[api].format(market[0].lower(), market[1].lower()) + else: + url = urls[api].format(market[0], market[1]) resp = requests.get(url) data = resp.json() - return data['result']['Bid'], data['result']['Ask'] + if api == 'bittrex': + return ((data['result']['buy'][0]['Rate'], data['result']['buy'][0]['Quantity']), (data['result']['sell'][0]['Rate'],data['result']['sell'][0]['Quantity'])) + if api == 'bitbay': + return ((data['bids'][0][0], data['bids'][0][1]),( data['asks'][0][0],data['asks'][0][1])) + if api == 'bitfinex': + return ((data[0][0], data[0][2]), (data[1][0], -data[1][2])) + if api == 'bitstamp': + return ((data['bids'][0][0], data['bids'][0][1]), (data['asks'][0][0],data['asks'][0][1])) + + +#def get_best_arbitrage(data): +def arb(): + buy = [] + sell = [] + for market in markets: + for api in apis: + data = get_buy_sell_list(api, market) + buy.append(data[0]) + sell.append(data[1]) + + +#list 3 def print_buy_sell_list(): for market in markets: data = get_buy_sell_list(market) @@ -35,4 +82,7 @@ def update_percent_list(): # print_buy_sell_list() # print_buy_sell_percent() -update_percent_list() +# update_percent_list() +arb() + + From ad9e6007e7e6265d4c6b765407f03c99d881db70 Mon Sep 17 00:00:00 2001 From: Elunniva Date: Sat, 9 May 2020 14:22:27 +0200 Subject: [PATCH 3/8] added arbitrage --- StockApi/stockApi.py | 52 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/StockApi/stockApi.py b/StockApi/stockApi.py index a45ac1c3..df52b7a3 100644 --- a/StockApi/stockApi.py +++ b/StockApi/stockApi.py @@ -16,6 +16,10 @@ ] taker = { + 'bittrex': 0.002, + 'bitbay': 0.001, + 'bitfinex': 0.002, + 'bitstamp': 0.005, } @@ -26,6 +30,14 @@ 'bitstamp': 'https://www.bitstamp.net/api/v2/order_book/{0}{1}', } +budget = { + 'USD': 1000.0, + 'BTC': 0.1, + 'LTC': 20.0, + 'XRP': 4500.0, + 'ETH': 5.0 +} + def get_buy_sell_list(api, market): if api == 'bitstamp': @@ -34,30 +46,46 @@ def get_buy_sell_list(api, market): url = urls[api].format(market[0], market[1]) resp = requests.get(url) data = resp.json() + if api == 'bittrex': - return ((data['result']['buy'][0]['Rate'], data['result']['buy'][0]['Quantity']), (data['result']['sell'][0]['Rate'],data['result']['sell'][0]['Quantity'])) + return (data['result']['buy'][0]['Rate'], data['result']['buy'][0]['Quantity']), (data['result']['sell'][0]['Rate'],data['result']['sell'][0]['Quantity']) if api == 'bitbay': - return ((data['bids'][0][0], data['bids'][0][1]),( data['asks'][0][0],data['asks'][0][1])) + return (data['bids'][0][0], data['bids'][0][1]),( data['asks'][0][0],data['asks'][0][1]) if api == 'bitfinex': - return ((data[0][0], data[0][2]), (data[1][0], -data[1][2])) + return (data[0][0], data[0][2]), (data[1][0], -data[1][2]) if api == 'bitstamp': - return ((data['bids'][0][0], data['bids'][0][1]), (data['asks'][0][0],data['asks'][0][1])) + return (float(data['bids'][0][0]), float(data['bids'][0][1])), (float(data['asks'][0][0]),float(data['asks'][0][1])) -#def get_best_arbitrage(data): +def get_best_arbitrage(buy, sell, market): + buy.sort(reverse=True) + sell.sort() + quantity = min(buy[0][1], sell[0][1]) + profit = quantity * (buy[0][0]-sell[0][0]) + if buy[0][0] > sell[0][0]: + print(f'You can buy {quantity} of {market} on {sell[0][2]} for {sell[0][0]} ' + f'and sell on {buy[0][2]} for {buy[0][0]} ' + f'gaining {profit}') -def arb(): - buy = [] - sell = [] +def calculate_best_arbitrage(): for market in markets: + buy = [] + sell = [] for api in apis: data = get_buy_sell_list(api, market) - buy.append(data[0]) - sell.append(data[1]) + buy.append(data[0]+(api,)) + sell.append(data[1]+(api,)) + get_best_arbitrage(buy, sell, market) + + +def update_best_arbitrage(): + while True: + calculate_best_arbitrage() + sleep(5) -#list 3 +# list 3 def print_buy_sell_list(): for market in markets: data = get_buy_sell_list(market) @@ -83,6 +111,6 @@ def update_percent_list(): # print_buy_sell_list() # print_buy_sell_percent() # update_percent_list() -arb() +update_best_arbitrage() From 0edf3e471b2ef8da1675e1a4c1fd59029dbce91f Mon Sep 17 00:00:00 2001 From: Elunniva Date: Sat, 9 May 2020 14:34:06 +0200 Subject: [PATCH 4/8] added taker fees --- StockApi/stockApi.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/StockApi/stockApi.py b/StockApi/stockApi.py index df52b7a3..7c18d502 100644 --- a/StockApi/stockApi.py +++ b/StockApi/stockApi.py @@ -61,8 +61,8 @@ def get_best_arbitrage(buy, sell, market): buy.sort(reverse=True) sell.sort() quantity = min(buy[0][1], sell[0][1]) - profit = quantity * (buy[0][0]-sell[0][0]) - if buy[0][0] > sell[0][0]: + profit = quantity * (buy[0][0] - sell[0][0] - buy[0][0] * taker[buy[0][2]] - sell[0][0] * taker[sell[0][2]]) + if profit > 0: print(f'You can buy {quantity} of {market} on {sell[0][2]} for {sell[0][0]} ' f'and sell on {buy[0][2]} for {buy[0][0]} ' f'gaining {profit}') From 8fcdf63da0fd98d41efaac659b7eb559cb3100bf Mon Sep 17 00:00:00 2001 From: Elunniva Date: Sat, 9 May 2020 15:08:39 +0200 Subject: [PATCH 5/8] added budget --- StockApi/stockApi.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/StockApi/stockApi.py b/StockApi/stockApi.py index 7c18d502..e9815f98 100644 --- a/StockApi/stockApi.py +++ b/StockApi/stockApi.py @@ -61,11 +61,14 @@ def get_best_arbitrage(buy, sell, market): buy.sort(reverse=True) sell.sort() quantity = min(buy[0][1], sell[0][1]) + if quantity * sell[0][0] > budget[market[1]]: + quantity = budget[market[1]] / sell[0][0] profit = quantity * (buy[0][0] - sell[0][0] - buy[0][0] * taker[buy[0][2]] - sell[0][0] * taker[sell[0][2]]) if profit > 0: - print(f'You can buy {quantity} of {market} on {sell[0][2]} for {sell[0][0]} ' + print(f'You can buy {quantity} of {market[0]} in {market[1]} on {sell[0][2]} for {sell[0][0]} ' f'and sell on {buy[0][2]} for {buy[0][0]} ' - f'gaining {profit}') + f'gaining {profit} {market[1]}') + budget[market[1]] += profit def calculate_best_arbitrage(): @@ -77,6 +80,7 @@ def calculate_best_arbitrage(): buy.append(data[0]+(api,)) sell.append(data[1]+(api,)) get_best_arbitrage(buy, sell, market) + print(budget) def update_best_arbitrage(): @@ -108,9 +112,7 @@ def update_percent_list(): sleep(5) -# print_buy_sell_list() -# print_buy_sell_percent() -# update_percent_list() -update_best_arbitrage() +if __name__ == "__main__": + update_best_arbitrage() From 39d070109b9cd72e9080bb107077d4db08714b27 Mon Sep 17 00:00:00 2001 From: Elunniva Date: Sat, 9 May 2020 15:45:35 +0200 Subject: [PATCH 6/8] improved finding best arbitrage --- StockApi/stockApi.py | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/StockApi/stockApi.py b/StockApi/stockApi.py index e9815f98..2c680d06 100644 --- a/StockApi/stockApi.py +++ b/StockApi/stockApi.py @@ -57,16 +57,34 @@ def get_buy_sell_list(api, market): return (float(data['bids'][0][0]), float(data['bids'][0][1])), (float(data['asks'][0][0]),float(data['asks'][0][1])) +def find_best_buy(buy): + max_b = buy[0] + for b in buy: + if b[0] - b[0] * taker[b[2]] > max_b[0] - max_b[0] * taker[max_b[2]]: + max_b = b + + return max_b + + +def find_best_sell(sell): + min_b = sell[0] + for s in sell: + if s[0] - s[0] * taker[s[2]] < min_b[0] - min_b[0] * taker[min_b[2]]: + min_b = s + + return min_b + + def get_best_arbitrage(buy, sell, market): - buy.sort(reverse=True) - sell.sort() - quantity = min(buy[0][1], sell[0][1]) - if quantity * sell[0][0] > budget[market[1]]: - quantity = budget[market[1]] / sell[0][0] - profit = quantity * (buy[0][0] - sell[0][0] - buy[0][0] * taker[buy[0][2]] - sell[0][0] * taker[sell[0][2]]) + buy = find_best_buy(buy) + sell = find_best_sell(sell) + quantity = min(buy[1], sell[1]) + if quantity * sell[0] > budget[market[1]]: + quantity = budget[market[1]] / sell[0] + profit = quantity * (buy[0] - sell[0] - buy[0] * taker[buy[2]] - sell[0] * taker[sell[2]]) if profit > 0: - print(f'You can buy {quantity} of {market[0]} in {market[1]} on {sell[0][2]} for {sell[0][0]} ' - f'and sell on {buy[0][2]} for {buy[0][0]} ' + print(f'You can buy {quantity} of {market[0]} in {market[1]} on {sell[2]} for {sell[0]} ' + f'and sell on {buy[2]} for {buy[0]} ' f'gaining {profit} {market[1]}') budget[market[1]] += profit From 67f947cd9e1e6cf015352f9393292e7b4063d899 Mon Sep 17 00:00:00 2001 From: Elunniva Date: Sat, 6 Jun 2020 18:23:15 +0200 Subject: [PATCH 7/8] added simple app --- StockApi/database.db | Bin 0 -> 28672 bytes StockApi/stockApi.py | 125 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 117 insertions(+), 8 deletions(-) create mode 100644 StockApi/database.db diff --git a/StockApi/database.db b/StockApi/database.db new file mode 100644 index 0000000000000000000000000000000000000000..0f9ca0202da73c9959da1886ebea25b59d6b37fb GIT binary patch literal 28672 zcmeI)(QDH{9Ki9rT$`?iHiDEsxQAA;1Kl1^8JxZFS-6MmrwE%$mR5;Gnz;G<#aY4&UHiF5mJiB zS_>hzP05+Eij1iwWfgK&x#f3TJb3h>=v)iCcqK|7o%hb$(!1hS>D4VcG$DWh0tg_0 z00IagfB*sr{2PHdo2!(|^3tCVpPxsqVZ1DMyX!SWPlwG`$J1`I+tsx~-u2H~Zr%?< z@4)No;3(8VuhY@TUH`Dz?dzvrUpIT%%&raj zMq_Paj=pO$>z6f|t5mD<&Anxx?Zs?nIvYiCTC>)Aa?^$tLHn->Qo0nVIi4;i^PgQ8 z>J4RA4ywOXN{2OgnAS55>kpIm(j;YWrLE+4Dw-mlFTyMY0tg_000IagfB*srAb&dLbKieCB&i=Qyq$ Date: Sat, 6 Jun 2020 21:03:29 +0200 Subject: [PATCH 8/8] added calculating arbitrage, values, printing data from and saving in db --- StockApi/database.db | Bin 28672 -> 45056 bytes StockApi/stockApi.py | 126 ++++++++++++++++++++++++++++++++----------- 2 files changed, 96 insertions(+), 30 deletions(-) diff --git a/StockApi/database.db b/StockApi/database.db index 0f9ca0202da73c9959da1886ebea25b59d6b37fb..1fb9dc73abe22bb10afb3efee4d41f2371b36cba 100644 GIT binary patch delta 1055 zcmd5)&ubGw6rS02lby|GUqXs06ib>AsI}TQf(36$T(wv=wp*!s2%Eaa#by(e4b+p> z-ld`b751co9=wX4dhk%B;3Za(ico}VDB{64DVR;`AK+o$kMDi&eKT)&sY#cb!b)Fw zh!7IM!|({)*N4vz43RUV=Yz0MWOa>bpWrn-)#|}L?VkEsT~kwP>c!({%5Akq`=cWx zblGyv!h%(Ouu#amR7O$F>`<9!HGee&>JV2_0q|5fSCo7g}j*Eb22r@E<83=e7xk{;L z-gf_D%1KAza5*1guoUN9_Z5^NCo3E$u&yoZfOIP?lG%Ip}4 zP~Es3XEH{@>{O24lKmWZ?7%k8dIzJD zNGW67$}+cpKes*~w~}1pL-PcagVZ65LHFk zB+!B{u!+5IAaOh-ib?AI3W6qx12kK!R4ixCwyLbrx~{~0yqSa=;n-KGuk=b3Gx;FP z1yo)XV4c7RSjV}~;buZm2#rMg=m|;{yaehOY}c(=iz@ng+p!h{!36D)db&solB%v* ZEHj0_T7VXT-_U9c1_)n=Ac!Jke*jO{7IXjr delta 142 zcmZp8z|`=7ae}m<3=0D8e$2XDpGhfDL zMS*JG&7XM%nb;WlzccWE-z-@0mY budget[market[1]]: - quantity = budget[market[1]] / sell[0] - profit = quantity * (buy[0] - sell[0] - buy[0] * taker[buy[2]] - sell[0] * taker[sell[2]]) - if profit > 0: - print(f'You can buy {quantity} of {market[0]} in {market[1]} on {sell[2]} for {sell[0]} ' - f'and sell on {buy[2]} for {buy[0]} ' - f'gaining {profit} {market[1]}') - budget[market[1]] += profit -""" -""" + budget = [m for m in wallet if m[1] == market[1]] + if budget: + budget_value = budget[0][2] + if quantity * sell[0] > budget_value: + quantity = budget_value / sell[0] + profit = quantity * (buy[0] - sell[0] - buy[0] * taker[buy[2]] - sell[0] * taker[sell[2]]) + if profit > 0: + messagebox.showinfo('Transaction info', f'You can buy {quantity} of {market[0]} in {market[1]} on {sell[2]} for {sell[0]} ' + f'and sell on {buy[2]} for {buy[0]} ' + f'gaining {profit} {market[1]}') + c.execute("INSERT INTO Transactions (Quantity, MarketC, MarketC2, ApiS, AmountS, ApiB, AmountB, Profit)" + " VALUES (?, ?, ?, ?, ?, ?, ?, ?)", + (quantity, market[0], market[1], sell[2], sell[0], buy[2], buy[0], profit)) + c.execute("UPDATE Currencies SET Amount = ? WHERE Name = ?", (budget_value+profit, market[1])) + conn.commit() + + def calculate_best_arbitrage(): for market in markets: buy = [] @@ -108,14 +116,13 @@ def calculate_best_arbitrage(): buy.append(data[0]+(api,)) sell.append(data[1]+(api,)) get_best_arbitrage(buy, sell, market) - print(budget) -""" -""" + + + def update_best_arbitrage(): while True: calculate_best_arbitrage() sleep(5) -""" # list 3 @@ -150,6 +157,10 @@ def get_wallet(): return fetchall("SELECT * FROM Currencies") +def get_transactions(): + return fetchall("SELECT * FROM Transactions") + + def get_base_currency(): return fetchall("SELECT * FROM Base") @@ -158,6 +169,10 @@ def change_base_currency(labelText): base_currency = simpledialog.askstring("Input", "In which base currency you want your wallet?", parent=window) if not base_currency: return + if base_currency not in availableCurr: + messagebox.showerror('Error', f'No such currency, choose from {availableCurr}') + change_base_currency() + return if get_base_currency(): c.execute("UPDATE Base SET Name = ? WHERE IdB = ?", (base_currency, 1)) else: @@ -179,6 +194,10 @@ def add_currency(): currency = simpledialog.askstring("Input", "What currency you want to add?", parent=window) if not currency: return + if currency not in availableCurr: + messagebox.showerror('Error', f'No such currency, choose from {availableCurr}') + add_currency() + return currency_amount = simpledialog.askinteger("Input", "How much you want to add?", parent=window) if not currency_amount: return @@ -206,11 +225,57 @@ def update_currency(): def calculate_values(): - return + c.execute("SELECT * FROM Transactions ORDER BY IdT DESC LIMIT 1") + result = c.fetchone() + result = list(result) + if result: + base = get_base_currency() + base = base[0][1] + if base == 'USD': + if result[3] == 'BTC': + result[7] = cur.convert_btc_to_cur(result[7], 'USD') + result[8] = cur.convert_btc_to_cur(result[8], 'USD') + if result[2] == 'BTC': + result[5] = cur.convert_btc_to_cur(result[5], 'USD') + elif base == 'BTC': + if result[3] == 'USD': + result[7] = cur.convert_to_btc(result[7], 'USD') + result[8] = cur.convert_to_btc(result[8], 'USD') + if result[2] == 'USD': + result[5] = cur.convert_to_btc(result[5], 'USD') + else: + messagebox.showinfo('Info', 'Only converting currency USD BTC, values shown without converting') + messagebox.showinfo(f'Last transaction values in {base}', f'You can buy {result[1]} of {result[2]} in {result[3]} on {result[4]} for {result[5]} ' + f'and sell on {result[6]} for {result[7]} ' + f'gaining {result[8]} {base}') + else: + messagebox.showerror('Error', 'No transactions available') + + +def print_wallet(): + print_window = tkinter.Tk() + print_window.title('Wallet') + data = get_wallet() + data_labels = [[tkinter.Label(print_window, text=str(y)) for y in x] for x in data] + for i, labels in enumerate(data_labels): + for j, label in enumerate(labels): + label.grid(row=i, column=j, padx=5, pady=1) + +def print_transactions(): + data = get_transactions() + if data: + print_window = tkinter.Tk() + print_window.title('Wallet') + data_labels = [[tkinter.Label(print_window, text=str(y)) for y in x] for x in data] + for i, labels in enumerate(data_labels): + for j, label in enumerate(labels): + label.grid(row=i, column=j, padx=5, pady=1) + else: + messagebox.showerror('Error', 'List of transactions empty') def create_main_window(): - window.title('Wallet') + window.title('Manage your wallet') labelText = tkinter.StringVar() base_currency = get_base_currency() @@ -221,24 +286,25 @@ def create_main_window(): label = tkinter.Label(window, textvariable=labelText) buttons_data = [ ('Change base currency', lambda: change_base_currency(labelText)), + ('Show your wallet', print_wallet), + ('Calculate best arbitrage', calculate_best_arbitrage()), ('New wallet', lambda: create_new_wallet(labelText)), ('Add currency', add_currency), ('Delete currency', delete_currency), ('Change currency amount', update_currency), - ('Calculate values', calculate_values), + ('Show all transactions', print_transactions), + ('Calculate values of last transaction', calculate_values), ('Quit', window.quit), ] label.grid(pady=10) - buttons = [tkinter.Button(window, text=b[0], command=b[1]) - for b in buttons_data] + buttons = [tkinter.Button(window, text=b[0], command=b[1]) for b in buttons_data] for button in buttons: button.grid(sticky='nesw', padx=5) if __name__ == "__main__": - # list 4 update_best_arbitrage() create_main_window() window.mainloop()