From b9013095e0d275d386c9ef24b9919539c3b4d88f Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Sat, 11 Apr 2020 21:30:49 +0200 Subject: [PATCH 01/18] l3 done --- .gitignore | 2 ++ Stocks.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 .gitignore create mode 100644 Stocks.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..1c406eb8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/.idea +/.__pycache__ \ No newline at end of file diff --git a/Stocks.py b/Stocks.py new file mode 100644 index 00000000..73a6ed20 --- /dev/null +++ b/Stocks.py @@ -0,0 +1,49 @@ +import requests +from time import sleep + + +def get_markets(): + markets = [] + url = f"https://api.bitbay.net/rest/trading/ticker" + headers = {'content-type': 'application/json'} + + data = requests.request("GET", url, headers=headers).json() + for item in data['items']: + markets.append(item) + return markets + + +def get_data(market): + url = f"https://api.bitbay.net/rest/trading/ticker/{market}" + headers = {'content-type': 'application/json'} + + response = requests.request("GET", url, headers=headers) + return response.json() + + +def get_sells_and_buys_market(market): + data = get_data(market) + return float(data['ticker']['highestBid']), float(data['ticker']['lowestAsk']) + + +def print_sells_and_buys_market(market): + print(get_sells_and_buys_market(market)) + + +def print_sells_and_buys_(markets): + for market in markets: + print("{0}: {1}".format(market, get_sells_and_buys_market(market))) + + +def calc_diff(bid, ask): + return 1 - abs(bid - ask) / ask + + +def print_current_diff(market): + while True: + (bid, ask) = get_sells_and_buys_market(market) + print(calc_diff(bid, ask)) + sleep(5) + + +print_current_diff('BTC-PLN') From 6ae9a1999d898b0c399624caddcb494c6e14e69d Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Wed, 15 Apr 2020 15:02:11 +0200 Subject: [PATCH 02/18] l3 done --- .gitignore | 2 +- Stocks.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1c406eb8..d67c89a2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ /.idea -/.__pycache__ \ No newline at end of file +/__pycache__ \ No newline at end of file diff --git a/Stocks.py b/Stocks.py index 73a6ed20..ce37d699 100644 --- a/Stocks.py +++ b/Stocks.py @@ -13,6 +13,14 @@ def get_markets(): return markets +def get_all_data(): + url = "https://api.bitbay.net/rest/trading/ticker" + headers = {'content-type': 'application/json'} + + response = requests.request("GET", url, headers=headers) + return response.json() + + def get_data(market): url = f"https://api.bitbay.net/rest/trading/ticker/{market}" headers = {'content-type': 'application/json'} @@ -30,6 +38,13 @@ def print_sells_and_buys_market(market): print(get_sells_and_buys_market(market)) +def print_all_sells_and_buys_(): + data = get_all_data() + for market in data['items']: + (bid, ask) = (data['items'][market]['highestBid'], data['items'][market]['lowestAsk']) + print("{0}: {1}".format(market, (bid, ask))) + + def print_sells_and_buys_(markets): for market in markets: print("{0}: {1}".format(market, get_sells_and_buys_market(market))) @@ -46,4 +61,6 @@ def print_current_diff(market): sleep(5) +print_all_sells_and_buys_() + print_current_diff('BTC-PLN') From 2d45f0131eb2d749176e499ce0ebb7d49f4d845d Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Mon, 27 Apr 2020 20:00:29 +0200 Subject: [PATCH 03/18] l4 task 1 done --- Stocks.py | 150 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 93 insertions(+), 57 deletions(-) diff --git a/Stocks.py b/Stocks.py index ce37d699..1ac76e3a 100644 --- a/Stocks.py +++ b/Stocks.py @@ -1,66 +1,102 @@ import requests +import sys from time import sleep - -def get_markets(): - markets = [] - url = f"https://api.bitbay.net/rest/trading/ticker" - headers = {'content-type': 'application/json'} - - data = requests.request("GET", url, headers=headers).json() - for item in data['items']: - markets.append(item) - return markets - - -def get_all_data(): - url = "https://api.bitbay.net/rest/trading/ticker" - headers = {'content-type': 'application/json'} - - response = requests.request("GET", url, headers=headers) - return response.json() - - -def get_data(market): - url = f"https://api.bitbay.net/rest/trading/ticker/{market}" +exchanges = [ + 'bitbay', + 'bitfinex', + 'bittrex', + 'bitstamp' +] + +exchange_urls = { + 'bitbay': "https://api.bitbay.net/rest/trading/ticker/", + 'bitfinex': "https://api-pub.bitfinex.com/v2/ticker/", + 'bittrex': "https://api.bittrex.com/api/v1.1/public/getticker?market=", + 'bitstamp': "https://www.bitstamp.net/api/v2/ticker/" +} + +trading_pairs = [ + "BTC for USD", + "LTC for USD", + "ETH for USD", + "XRP for USD" +] + +exchange_pairs = { + 'bitbay': [ + "BTC-USD", + "LTC-USD", + "ETH-USD", + "XRP-USD" + ], + 'bitfinex': [ + "tBTCUSD", + "tLTCUSD", + "tETHUSD", + "tXRPUSD" + ], + 'bittrex': [ + "USD-BTC", + "USD-LTC", + "USD-ETH", + "USD-XRP" + ], + 'bitstamp': [ + "btcusd", + "ltcusd", + "ethusd", + "xrpusd" + ] +} + + +def get_data(url): headers = {'content-type': 'application/json'} response = requests.request("GET", url, headers=headers) return response.json() -def get_sells_and_buys_market(market): - data = get_data(market) - return float(data['ticker']['highestBid']), float(data['ticker']['lowestAsk']) - - -def print_sells_and_buys_market(market): - print(get_sells_and_buys_market(market)) - - -def print_all_sells_and_buys_(): - data = get_all_data() - for market in data['items']: - (bid, ask) = (data['items'][market]['highestBid'], data['items'][market]['lowestAsk']) - print("{0}: {1}".format(market, (bid, ask))) - - -def print_sells_and_buys_(markets): - for market in markets: - print("{0}: {1}".format(market, get_sells_and_buys_market(market))) - - -def calc_diff(bid, ask): - return 1 - abs(bid - ask) / ask - - -def print_current_diff(market): - while True: - (bid, ask) = get_sells_and_buys_market(market) - print(calc_diff(bid, ask)) - sleep(5) - - -print_all_sells_and_buys_() - -print_current_diff('BTC-PLN') +def get_sells_and_buys(exchange, pair_index): + data = get_data(exchange_urls[exchange] + exchange_pairs[exchange][pair_index]) + bid_ask_pair = None + if exchange == 'bitbay': + bid_ask_pair = float(data['ticker']['highestBid']), float(data['ticker']['lowestAsk']) + if exchange == 'bitfinex': + bid_ask_pair = data[0], data[2] + if exchange == 'bittrex': + bid_ask_pair = data['result']['Bid'], data['result']['Ask'] + if exchange == 'bitstamp': + bid_ask_pair = float(data['bid']), float(data['ask']) + return bid_ask_pair + +def look_for_arbitration(): + for pair_index in range(4): + highestBid = 0 + lowestAsk = sys.maxsize + bid_exchange = None + ask_exchange = None + for exchange in exchanges: + (bid, ask) = get_sells_and_buys(exchange, pair_index) + if bid > highestBid: + highestBid = bid + bid_exchange = exchange + if ask < lowestAsk: + lowestAsk = ask + ask_exchange = exchange + if lowestAsk < highestBid: + print(f"On exchange {ask_exchange} you can buy {trading_pairs[pair_index]} for {lowestAsk} and sell " + f"on exchange {bid_exchange} for {highestBid} making profit of total {highestBid - lowestAsk} " + f"USD") + + + +def printstuff(): + for exchange in exchanges: + for pair in range(0, 4): + print(f"{exchange}, {exchange_pairs[exchange][pair]}:") + print(get_sells_and_buys(exchange, pair)) + +while True: + look_for_arbitration() \ No newline at end of file From d9201215c16c2e0463a0c62a4faccff09360d9b2 Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Fri, 1 May 2020 15:58:24 +0200 Subject: [PATCH 04/18] added market fees and virtualBudget --- .gitignore | 3 ++- Stocks.py | 47 ++++++++++++++++++++++++++++++++++++----------- virualBuget.py | 11 +++++++++++ 3 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 virualBuget.py diff --git a/.gitignore b/.gitignore index d67c89a2..475612bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /.idea -/__pycache__ \ No newline at end of file +/__pycache__ +/.gitingnore \ No newline at end of file diff --git a/Stocks.py b/Stocks.py index 1ac76e3a..4281fcff 100644 --- a/Stocks.py +++ b/Stocks.py @@ -1,7 +1,10 @@ import requests import sys +import virualBuget from time import sleep +budget = virualBuget.VirtualBudget(100) + exchanges = [ 'bitbay', 'bitfinex', @@ -17,10 +20,10 @@ } trading_pairs = [ - "BTC for USD", - "LTC for USD", - "ETH for USD", - "XRP for USD" + "BTC for USD", + "LTC for USD", + "ETH for USD", + "XRP for USD" ] exchange_pairs = { @@ -50,6 +53,13 @@ ] } +fees = { + 'bitbay': 0.001, + 'bitfinex': 0.002, + 'bittrex': 0.002, + 'bitstamp': 0.005 +} + def get_data(url): headers = {'content-type': 'application/json'} @@ -71,25 +81,38 @@ def get_sells_and_buys(exchange, pair_index): bid_ask_pair = float(data['bid']), float(data['ask']) return bid_ask_pair -def look_for_arbitration(): + + +def consider_commisons(exchange, bid_ask): + bid, ask = bid_ask + bid_ask = bid*(1 - fees[exchange]), ask*(1 + fees[exchange]) + return bid_ask + + +def look_for_arbitration(commisions=True): for pair_index in range(4): highestBid = 0 lowestAsk = sys.maxsize bid_exchange = None ask_exchange = None for exchange in exchanges: - (bid, ask) = get_sells_and_buys(exchange, pair_index) + if commisions: + (bid, ask) = consider_commisons(exchange, get_sells_and_buys(exchange, pair_index)) + else: + (bid, ask) = get_sells_and_buys(exchange, pair_index) if bid > highestBid: highestBid = bid bid_exchange = exchange if ask < lowestAsk: lowestAsk = ask ask_exchange = exchange - if lowestAsk < highestBid: - print(f"On exchange {ask_exchange} you can buy {trading_pairs[pair_index]} for {lowestAsk} and sell " - f"on exchange {bid_exchange} for {highestBid} making profit of total {highestBid - lowestAsk} " - f"USD") + diff = round(highestBid - lowestAsk, 2) + if diff > 0: + budget.make_transaction(lowestAsk, highestBid) + print(f"On exchange {ask_exchange} you can buy 1 {trading_pairs[pair_index]} for {lowestAsk} and sell " + f"on exchange {bid_exchange} for {highestBid} making total profit of {diff} " + f"USD") def printstuff(): @@ -98,5 +121,7 @@ def printstuff(): print(f"{exchange}, {exchange_pairs[exchange][pair]}:") print(get_sells_and_buys(exchange, pair)) + while True: - look_for_arbitration() \ No newline at end of file + look_for_arbitration(commisions=True) + print(budget.currentMoney) diff --git a/virualBuget.py b/virualBuget.py new file mode 100644 index 00000000..6fb12248 --- /dev/null +++ b/virualBuget.py @@ -0,0 +1,11 @@ + + +class VirtualBudget: + def __init__(self, money): + self.startingMoney = money + self.currentMoney = money + + def make_transaction(self, buy_price, sell_price): + amount_bought = self.currentMoney / buy_price + money_earned = (amount_bought * sell_price) - (amount_bought * buy_price) + self.currentMoney += money_earned From cdb4756fb031c02a8734ba9ef9ee6e15cafd93c9 Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Fri, 1 May 2020 22:46:07 +0200 Subject: [PATCH 05/18] inital idea for speculation algorythm --- Stocks.py | 13 +++++-- algoritm.py | 18 +++++++++ createdb.py | 14 +++++++ data.db | Bin 0 -> 8192 bytes datagatherer.py | 32 ++++++++++++++++ decision_agent.py | 92 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 algoritm.py create mode 100644 createdb.py create mode 100644 data.db create mode 100644 datagatherer.py create mode 100644 decision_agent.py diff --git a/Stocks.py b/Stocks.py index 4281fcff..5dec37aa 100644 --- a/Stocks.py +++ b/Stocks.py @@ -82,10 +82,14 @@ def get_sells_and_buys(exchange, pair_index): return bid_ask_pair +def get_current_currency_value(exchange, pair_index): + (bid, ask) = get_sells_and_buys(exchange, pair_index) + return (bid + ask) / 2 + def consider_commisons(exchange, bid_ask): bid, ask = bid_ask - bid_ask = bid*(1 - fees[exchange]), ask*(1 + fees[exchange]) + bid_ask = bid * (1 - fees[exchange]), ask * (1 + fees[exchange]) return bid_ask @@ -122,6 +126,7 @@ def printstuff(): print(get_sells_and_buys(exchange, pair)) -while True: - look_for_arbitration(commisions=True) - print(budget.currentMoney) +if __name__ == '__main__': + while True: + look_for_arbitration(commisions=True) + print(budget.currentMoney) diff --git a/algoritm.py b/algoritm.py new file mode 100644 index 00000000..dad43744 --- /dev/null +++ b/algoritm.py @@ -0,0 +1,18 @@ + +fee = 0.002 + +def avg(data): + sum = 0 + for item in data: + sum += item + return sum / len(data) + + +def decide_if_buy_or_sell(data, current_price): + diff = current_price - avg(data) + if current_price < avg(data) + current_price * fee: + return 'BUY' + elif current_price > avg(data) + current_price * fee: + return 'SELL' + else: + return None diff --git a/createdb.py b/createdb.py new file mode 100644 index 00000000..1a8396ca --- /dev/null +++ b/createdb.py @@ -0,0 +1,14 @@ +import sqlite3 +import os + + +if os.path.exists("data.db"): + os.remove("data.db") + print("Old database removed.") +connection = sqlite3.connect("data.db") +cursor = connection.cursor() +cursor.execute('''CREATE TABLE data + (date text, price real, pair text)''') +connection.commit() +connection.close() +print("New database created.") diff --git a/data.db b/data.db new file mode 100644 index 0000000000000000000000000000000000000000..3baedf2d8a0b45baa7b4cae20825cec9f0a974d4 GIT binary patch literal 8192 zcmeH~Jxmi(9Ki1i0{2~&3W}EJS1nrPdatGB67>L^GBlBoY8V)(T4EcBwYh=BMF$e% zq9cjMn7A+*#*W3w!NE;N-AHtBG4X5g6}d$JyuZ#S@1I_J_wq~g>#w=K+{{#=;+M(7 z?fO#5CsYbcvMhOoNRl+jju1P7k=aRmaKYYN*Z-P9>3oV9jFPQ&iM_;#0-}H@APR^A zqJStM3Wx%tfG8jehytR(UkY54J9{D#`M%|st}m8vmi$ud2#rtYMvFO8933m?rrKzkb zHD!W*uozK56c7bO0Z~8{5C#6T0;@k+EY^)c`}&F9iy^BdEPHUhs>9L{!W8v30?IOul*w^om=Wm04M>$;9r4;)0AsqBOf^op_FvbDDUJjRWsRR9b z5YDSEv2Uwh4DOFZ7zg|!7zg~iIoz;IlhE%V!a=_S7zh0JV_ft5)7A|f{Jvohmv*TQ z{VaroekR5NKLg`{pU&Y@t}_DtG=zhGD#ignh0kTZO?k4lhXnn)I2?7IEcEL{IOx}b xalmgMpUW`6D|76hJn(DhaE|Nj*+1G4&a2+} 0: + self.buy(pair_index, buy_amount) + print(f"Current richness {self.get_current_richness_estimate()}") + elif decision == 'SELL' and sell_amount > 0: + self.sell(pair_index, sell_amount) + print(f"Current richness {self.get_current_richness_estimate()}") + + + def go(self): + print(f"Current richness {self.get_current_richness_estimate()}") + while True: + self.make_transaction() + time.sleep(60) + + +if __name__ == '__main__': + ag = DecisionAgent() + ag.go() From 5a61c377270760a78ec76673b67c40de115d2910 Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Sat, 2 May 2020 22:06:03 +0200 Subject: [PATCH 06/18] minor tweaks --- Stocks.py | 8 +------- algoritm.py | 20 +++++++++++++++----- data.db | Bin 8192 -> 16384 bytes datagatherer.py | 15 +++++++++------ decision_agent.py | 42 +++++++++++++++++++++++++++--------------- virualBuget.py | 3 +++ 6 files changed, 55 insertions(+), 33 deletions(-) diff --git a/Stocks.py b/Stocks.py index 5dec37aa..7dfc71af 100644 --- a/Stocks.py +++ b/Stocks.py @@ -114,19 +114,13 @@ def look_for_arbitration(commisions=True): diff = round(highestBid - lowestAsk, 2) if diff > 0: budget.make_transaction(lowestAsk, highestBid) + budget.print_budget() print(f"On exchange {ask_exchange} you can buy 1 {trading_pairs[pair_index]} for {lowestAsk} and sell " f"on exchange {bid_exchange} for {highestBid} making total profit of {diff} " f"USD") -def printstuff(): - for exchange in exchanges: - for pair in range(0, 4): - print(f"{exchange}, {exchange_pairs[exchange][pair]}:") - print(get_sells_and_buys(exchange, pair)) - if __name__ == '__main__': while True: look_for_arbitration(commisions=True) - print(budget.currentMoney) diff --git a/algoritm.py b/algoritm.py index dad43744..a7102595 100644 --- a/algoritm.py +++ b/algoritm.py @@ -1,6 +1,6 @@ - fee = 0.002 + def avg(data): sum = 0 for item in data: @@ -8,11 +8,21 @@ def avg(data): return sum / len(data) -def decide_if_buy_or_sell(data, current_price): - diff = current_price - avg(data) - if current_price < avg(data) + current_price * fee: +def decide_if_buy_or_sell(data, current_value): + avg_val = avg(data) + #buy if value of currency is less than avg value + fee you would get from it + if current_value < avg_val + avg_val * fee: return 'BUY' - elif current_price > avg(data) + current_price * fee: + # sell if value of currency is greater than avg value + fee you would get from it + elif current_value > avg_val + avg_val * fee: return 'SELL' else: return None + + +def get_diff_percent(data, current_price): + diff = current_price - avg(data) + if diff < 0: + return -diff / 100 + else: + return diff / 100 diff --git a/data.db b/data.db index 3baedf2d8a0b45baa7b4cae20825cec9f0a974d4..d8091645c1a40060042f281e0e0543771b5ec3be 100644 GIT binary patch literal 16384 zcmeI2UvN~_9mn_oy?c|*MhX>+#VwU3ScSWL_a>V|!3!kZTa6k>q|u^fgJQ=3r^nT`V?uH(h)T;1?=cds+}p;sWO6{p0jrkW`Do)(}zyq z?hZQ%$!FLPzkBaF=XbtmU}N9T@!`UbC&qTy#tT-gJrYDQ`p5~t!&tDavoXTI#Z_QWp?QOGdr`wLUjkbAhh1`|gx!j4| zq1;f;%;~L{S|?kNw2rhotqWT&w@kGhZ<%Q6Z|P`>88gO74*s)_TuNz!{$Nd96#jOgii*t8Qcl`UE7q%=P z+SFg?eob)B;}_qYzyBkzchIYI4^y1`r)L*WZv01I<8vRPxWMDsXU|H%Eefual}ga> zR|E(B9;7%g?(+Z0-=yCI6c>0)Uf9y{rSuz8a5gKM(C?Q72mLlv9PqoJ;sURJ;iTW7 zf~zpI8~P0p9Q4~naqib2@d6%@_1j2sfww~3FVe4H!CB0#LcjY64*K0oaqbrue^sR4 zJroysg0rMwpMonhvkUs&O>offE{bz!>(86?`vt`XUYD_Y^fl?{DYz0dJE5OTaL{i9 z#km*wWpm$@e!UbIc&kTW{m_tpJqpfL_^nrSHuPIZaqfAcH(&a#rMSRbEACV2=U~q2 zW~L46cc+@GK)*E<=bmYLK2}p);BDB!U()aA3a-k`3iMm0<}B#PD9*iBA2($Ex+yO3 z`lhF+&q}|lg6m?Y1^v1R4*GSfxv~Ss7n|Y&Z(#28TTyVG%tZ5>MR3rstmaCND<0pD zFJ=8oYR=^I?+~Bf7R&mX3eILGnm<+&9Q0eE;3~}ScHDn%;TQOb^t*%N0 zN^yZVEY>-)ezz*P60_0#@l%3>eoNF`r{n%bly8&t`w7Jb-iWwUrC&k8naoD>$1Mcs zJT}RPgXyz!{kK@n*^WEaG{60r;sS5a-1WiDm@9WP8;#G42oC!FNX=CoF#g>{ae=p2 z6k67Ap@OS28;#F55*+mVp_;QC_bWc_zxtuPz6&TW@b=AJAIw*9UCc(~^AFTq8T!qm zIQR3W`|k#d3%vR~E$i2=;5wO&#^=16D?z_DiUaGb9K{9RK`{VIzg7ijGaL0EEo#n$ zeg?(4m-z6qdat~`S&9q1XE--1{d5J#$9pt?XiBcq4gE3{=gu^Z&uNMaYRS3tZ%V;g ztb*o`q?)TjzXZj(e{P!J;uIIuG|{lG8{`dhvL>?m8gHKSGx?MG!%_cV-zSLr|DIyh z|FeqNCxGjZsQ+h`sQ>RNM*Tk%`vg({kLOt{>i>I+QUA{@u}=W!kEs7=R@DFZ6r=v1 zmBl^*>~Es}pOvHjzo!`W|E$dS3I31$e?9*e{r^DXz5lKMUuOKrc;9%#c*c0pC>eV8 zV)m`(~6mIGUqd|XP(YHkTEk_`a=3t z`uX&>G)v#W)Bm?qFQ#^ znT?M^uMjNrMVr`Td`)iZ`zZC2AlTLS(Xv;9fqQZ8wyKYEuMkB0mOcu;>R?GMESnus z@+Cp&h@vkELPwN+g&@jqd=!2)K;(#4zahxeo91-HNAZ^gp(Dz_LJ;K-J_^7ZAaXy9W33qgE8qA;uhB1e>lg&@8kQ5+^g z=!o*L5XAQ*3d9;9azra)33_R9QtUaInD{6X3qi|)jwlo3AU`vMGAAE}Vj)=Kj?H5a zO2s7TUaP00*BwzTCc(h{RGbgFeyve1#zCITqTIws!B_)Cjwl(EAV@xa6pe*omDjP^ z5oKc`i0?-fj)h<+azyEv1fe5Z9!n59qI@g_@z{d`vIdA8Q9>p`=!haR2|`Ddk%b`2 z7=09yg`kNXQA#F3aEiu9F_{FRV+`)|)xionXK|3=pyE?%j-Rvmy6K$MlN1L8{{T6@ z$->WxqH_!f2#)(TO)>k`96!e(p8Rif_}^1p;9eHzMdSlLq2|!IxR2nV-|r|6`2CjR z0{8Q|=V->&9C}WELvYYT zf`fjKQJnjMI3Bn|&L}%64)~2IIG*pJ_06LSPPLD_gW}w&rgH+r6c@Nx#d#(9d~C;@ UIIoWGzik8u>-Px7HJ=mxFT$7iUjP6A literal 8192 zcmeH~Jxmi(9Ki1i0{2~&3W}EJS1nrPdatGB67>L^GBlBoY8V)(T4EcBwYh=BMF$e% zq9cjMn7A+*#*W3w!NE;N-AHtBG4X5g6}d$JyuZ#S@1I_J_wq~g>#w=K+{{#=;+M(7 z?fO#5CsYbcvMhOoNRl+jju1P7k=aRmaKYYN*Z-P9>3oV9jFPQ&iM_;#0-}H@APR^A zqJStM3Wx%tfG8jehytR(UkY54J9{D#`M%|st}m8vmi$ud2#rtYMvFO8933m?rrKzkb zHD!W*uozK56c7bO0Z~8{5C#6T0;@k+EY^)c`}&F9iy^BdEPHUhs>9L{!W8v30?IOul*w^om=Wm04M>$;9r4;)0AsqBOf^op_FvbDDUJjRWsRR9b z5YDSEv2Uwh4DOFZ7zg|!7zg~iIoz;IlhE%V!a=_S7zh0JV_ft5)7A|f{Jvohmv*TQ z{VaroekR5NKLg`{pU&Y@t}_DtG=zhGD#ignh0kTZO?k4lhXnn)I2?7IEcEL{IOx}b xalmgMpUW`6D|76hJn(DhaE|Nj*+1G4&a2+} 0: self.buy(pair_index, buy_amount) - print(f"Current richness {self.get_current_richness_estimate()}") + print(f"Current wealthness {self.get_current_wealthness_estimate()}") elif decision == 'SELL' and sell_amount > 0: self.sell(pair_index, sell_amount) - print(f"Current richness {self.get_current_richness_estimate()}") - + print(f"Current wealthness {self.get_current_wealthness_estimate()}") - def go(self): - print(f"Current richness {self.get_current_richness_estimate()}") + def run(self): + print(f"Current wealthness {self.get_current_wealthness_estimate()}") while True: self.make_transaction() - time.sleep(60) + time.sleep(1200) if __name__ == '__main__': ag = DecisionAgent() - ag.go() + #buy some starting cryptos + ag.buy(0, 2000) + ag.buy(1, 2000) + ag.buy(2, 2000) + ag.buy(3, 2000) + ag.run() diff --git a/virualBuget.py b/virualBuget.py index 6fb12248..f24ec65e 100644 --- a/virualBuget.py +++ b/virualBuget.py @@ -9,3 +9,6 @@ def make_transaction(self, buy_price, sell_price): amount_bought = self.currentMoney / buy_price money_earned = (amount_bought * sell_price) - (amount_bought * buy_price) self.currentMoney += money_earned + + def print_budget(self): + print(f"My current budget state: {self.currentMoney}") \ No newline at end of file From 5550b327a87fbcd6c8e9dd891e8e2aa4873940bb Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Sat, 2 May 2020 22:12:53 +0200 Subject: [PATCH 07/18] remove .gitignore from remote --- .gitignore | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 475612bd..00000000 --- a/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/.idea -/__pycache__ -/.gitingnore \ No newline at end of file From 6ab058a2e6d2afe51319b558e1dabba09a0d9edb Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Tue, 12 May 2020 00:21:48 +0200 Subject: [PATCH 08/18] started l5 --- Stocks.py | 126 ---------------------------------------------- algoritm.py | 28 ----------- createdb.py | 10 ++-- data.db | Bin 16384 -> 0 bytes datagatherer.py | 35 ------------- decision_agent.py | 104 -------------------------------------- virualBuget.py | 14 ------ wallet.py | 49 ++++++++++++++++++ 8 files changed, 54 insertions(+), 312 deletions(-) delete mode 100644 Stocks.py delete mode 100644 algoritm.py delete mode 100644 data.db delete mode 100644 datagatherer.py delete mode 100644 decision_agent.py delete mode 100644 virualBuget.py create mode 100644 wallet.py diff --git a/Stocks.py b/Stocks.py deleted file mode 100644 index 7dfc71af..00000000 --- a/Stocks.py +++ /dev/null @@ -1,126 +0,0 @@ -import requests -import sys -import virualBuget -from time import sleep - -budget = virualBuget.VirtualBudget(100) - -exchanges = [ - 'bitbay', - 'bitfinex', - 'bittrex', - 'bitstamp' -] - -exchange_urls = { - 'bitbay': "https://api.bitbay.net/rest/trading/ticker/", - 'bitfinex': "https://api-pub.bitfinex.com/v2/ticker/", - 'bittrex': "https://api.bittrex.com/api/v1.1/public/getticker?market=", - 'bitstamp': "https://www.bitstamp.net/api/v2/ticker/" -} - -trading_pairs = [ - "BTC for USD", - "LTC for USD", - "ETH for USD", - "XRP for USD" -] - -exchange_pairs = { - 'bitbay': [ - "BTC-USD", - "LTC-USD", - "ETH-USD", - "XRP-USD" - ], - 'bitfinex': [ - "tBTCUSD", - "tLTCUSD", - "tETHUSD", - "tXRPUSD" - ], - 'bittrex': [ - "USD-BTC", - "USD-LTC", - "USD-ETH", - "USD-XRP" - ], - 'bitstamp': [ - "btcusd", - "ltcusd", - "ethusd", - "xrpusd" - ] -} - -fees = { - 'bitbay': 0.001, - 'bitfinex': 0.002, - 'bittrex': 0.002, - 'bitstamp': 0.005 -} - - -def get_data(url): - headers = {'content-type': 'application/json'} - - response = requests.request("GET", url, headers=headers) - return response.json() - - -def get_sells_and_buys(exchange, pair_index): - data = get_data(exchange_urls[exchange] + exchange_pairs[exchange][pair_index]) - bid_ask_pair = None - if exchange == 'bitbay': - bid_ask_pair = float(data['ticker']['highestBid']), float(data['ticker']['lowestAsk']) - if exchange == 'bitfinex': - bid_ask_pair = data[0], data[2] - if exchange == 'bittrex': - bid_ask_pair = data['result']['Bid'], data['result']['Ask'] - if exchange == 'bitstamp': - bid_ask_pair = float(data['bid']), float(data['ask']) - return bid_ask_pair - - -def get_current_currency_value(exchange, pair_index): - (bid, ask) = get_sells_and_buys(exchange, pair_index) - return (bid + ask) / 2 - - -def consider_commisons(exchange, bid_ask): - bid, ask = bid_ask - bid_ask = bid * (1 - fees[exchange]), ask * (1 + fees[exchange]) - return bid_ask - - -def look_for_arbitration(commisions=True): - for pair_index in range(4): - highestBid = 0 - lowestAsk = sys.maxsize - bid_exchange = None - ask_exchange = None - for exchange in exchanges: - if commisions: - (bid, ask) = consider_commisons(exchange, get_sells_and_buys(exchange, pair_index)) - else: - (bid, ask) = get_sells_and_buys(exchange, pair_index) - if bid > highestBid: - highestBid = bid - bid_exchange = exchange - if ask < lowestAsk: - lowestAsk = ask - ask_exchange = exchange - - diff = round(highestBid - lowestAsk, 2) - if diff > 0: - budget.make_transaction(lowestAsk, highestBid) - budget.print_budget() - print(f"On exchange {ask_exchange} you can buy 1 {trading_pairs[pair_index]} for {lowestAsk} and sell " - f"on exchange {bid_exchange} for {highestBid} making total profit of {diff} " - f"USD") - - - -if __name__ == '__main__': - while True: - look_for_arbitration(commisions=True) diff --git a/algoritm.py b/algoritm.py deleted file mode 100644 index a7102595..00000000 --- a/algoritm.py +++ /dev/null @@ -1,28 +0,0 @@ -fee = 0.002 - - -def avg(data): - sum = 0 - for item in data: - sum += item - return sum / len(data) - - -def decide_if_buy_or_sell(data, current_value): - avg_val = avg(data) - #buy if value of currency is less than avg value + fee you would get from it - if current_value < avg_val + avg_val * fee: - return 'BUY' - # sell if value of currency is greater than avg value + fee you would get from it - elif current_value > avg_val + avg_val * fee: - return 'SELL' - else: - return None - - -def get_diff_percent(data, current_price): - diff = current_price - avg(data) - if diff < 0: - return -diff / 100 - else: - return diff / 100 diff --git a/createdb.py b/createdb.py index 1a8396ca..91a48758 100644 --- a/createdb.py +++ b/createdb.py @@ -2,13 +2,13 @@ import os -if os.path.exists("data.db"): - os.remove("data.db") +if os.path.exists("wallet.db"): + os.remove("wallet.db") print("Old database removed.") -connection = sqlite3.connect("data.db") +connection = sqlite3.connect("wallet.db") cursor = connection.cursor() -cursor.execute('''CREATE TABLE data - (date text, price real, pair text)''') +cursor.execute('''CREATE TABLE wallet + (resource text, amount real)''') connection.commit() connection.close() print("New database created.") diff --git a/data.db b/data.db deleted file mode 100644 index d8091645c1a40060042f281e0e0543771b5ec3be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI2UvN~_9mn_oy?c|*MhX>+#VwU3ScSWL_a>V|!3!kZTa6k>q|u^fgJQ=3r^nT`V?uH(h)T;1?=cds+}p;sWO6{p0jrkW`Do)(}zyq z?hZQ%$!FLPzkBaF=XbtmU}N9T@!`UbC&qTy#tT-gJrYDQ`p5~t!&tDavoXTI#Z_QWp?QOGdr`wLUjkbAhh1`|gx!j4| zq1;f;%;~L{S|?kNw2rhotqWT&w@kGhZ<%Q6Z|P`>88gO74*s)_TuNz!{$Nd96#jOgii*t8Qcl`UE7q%=P z+SFg?eob)B;}_qYzyBkzchIYI4^y1`r)L*WZv01I<8vRPxWMDsXU|H%Eefual}ga> zR|E(B9;7%g?(+Z0-=yCI6c>0)Uf9y{rSuz8a5gKM(C?Q72mLlv9PqoJ;sURJ;iTW7 zf~zpI8~P0p9Q4~naqib2@d6%@_1j2sfww~3FVe4H!CB0#LcjY64*K0oaqbrue^sR4 zJroysg0rMwpMonhvkUs&O>offE{bz!>(86?`vt`XUYD_Y^fl?{DYz0dJE5OTaL{i9 z#km*wWpm$@e!UbIc&kTW{m_tpJqpfL_^nrSHuPIZaqfAcH(&a#rMSRbEACV2=U~q2 zW~L46cc+@GK)*E<=bmYLK2}p);BDB!U()aA3a-k`3iMm0<}B#PD9*iBA2($Ex+yO3 z`lhF+&q}|lg6m?Y1^v1R4*GSfxv~Ss7n|Y&Z(#28TTyVG%tZ5>MR3rstmaCND<0pD zFJ=8oYR=^I?+~Bf7R&mX3eILGnm<+&9Q0eE;3~}ScHDn%;TQOb^t*%N0 zN^yZVEY>-)ezz*P60_0#@l%3>eoNF`r{n%bly8&t`w7Jb-iWwUrC&k8naoD>$1Mcs zJT}RPgXyz!{kK@n*^WEaG{60r;sS5a-1WiDm@9WP8;#G42oC!FNX=CoF#g>{ae=p2 z6k67Ap@OS28;#F55*+mVp_;QC_bWc_zxtuPz6&TW@b=AJAIw*9UCc(~^AFTq8T!qm zIQR3W`|k#d3%vR~E$i2=;5wO&#^=16D?z_DiUaGb9K{9RK`{VIzg7ijGaL0EEo#n$ zeg?(4m-z6qdat~`S&9q1XE--1{d5J#$9pt?XiBcq4gE3{=gu^Z&uNMaYRS3tZ%V;g ztb*o`q?)TjzXZj(e{P!J;uIIuG|{lG8{`dhvL>?m8gHKSGx?MG!%_cV-zSLr|DIyh z|FeqNCxGjZsQ+h`sQ>RNM*Tk%`vg({kLOt{>i>I+QUA{@u}=W!kEs7=R@DFZ6r=v1 zmBl^*>~Es}pOvHjzo!`W|E$dS3I31$e?9*e{r^DXz5lKMUuOKrc;9%#c*c0pC>eV8 zV)m`(~6mIGUqd|XP(YHkTEk_`a=3t z`uX&>G)v#W)Bm?qFQ#^ znT?M^uMjNrMVr`Td`)iZ`zZC2AlTLS(Xv;9fqQZ8wyKYEuMkB0mOcu;>R?GMESnus z@+Cp&h@vkELPwN+g&@jqd=!2)K;(#4zahxeo91-HNAZ^gp(Dz_LJ;K-J_^7ZAaXy9W33qgE8qA;uhB1e>lg&@8kQ5+^g z=!o*L5XAQ*3d9;9azra)33_R9QtUaInD{6X3qi|)jwlo3AU`vMGAAE}Vj)=Kj?H5a zO2s7TUaP00*BwzTCc(h{RGbgFeyve1#zCITqTIws!B_)Cjwl(EAV@xa6pe*omDjP^ z5oKc`i0?-fj)h<+azyEv1fe5Z9!n59qI@g_@z{d`vIdA8Q9>p`=!haR2|`Ddk%b`2 z7=09yg`kNXQA#F3aEiu9F_{FRV+`)|)xionXK|3=pyE?%j-Rvmy6K$MlN1L8{{T6@ z$->WxqH_!f2#)(TO)>k`96!e(p8Rif_}^1p;9eHzMdSlLq2|!IxR2nV-|r|6`2CjR z0{8Q|=V->&9C}WELvYYT zf`fjKQJnjMI3Bn|&L}%64)~2IIG*pJ_06LSPPLD_gW}w&rgH+r6c@Nx#d#(9d~C;@ UIIoWGzik8u>-Px7HJ=mxFT$7iUjP6A diff --git a/datagatherer.py b/datagatherer.py deleted file mode 100644 index 590039e3..00000000 --- a/datagatherer.py +++ /dev/null @@ -1,35 +0,0 @@ -import sqlite3 -import time -from datetime import datetime -import Stocks - -connection = sqlite3.connect('data.db') -cursor = connection.cursor() - -trading_pairs = [ - "BTC-USD", - "LTC-USD", - "ETH-USD", - "XRP-USD" -] - -def gather_data(): - for pair_index in range(4): - (bid, ask) = Stocks.get_sells_and_buys('bitbay', pair_index) - val = (bid + ask) / 2 - cursor.execute("INSERT INTO data VALUES (?,?,?)", - (datetime.now().strftime("%m/%d/%Y %H:%M:%S"), val, trading_pairs[pair_index])) - connection.commit() - -def gather_data_loop(): - while True: - for pair_index in range(4): - (bid, ask) = Stocks.get_sells_and_buys('bitbay', pair_index) - val = (bid + ask) / 2 - cursor.execute("INSERT INTO data VALUES (?,?,?)", (datetime.now().strftime("%m/%d/%Y %H:%M:%S"), val, trading_pairs[pair_index])) - connection.commit() - time.sleep(60) - - -if __name__ == '__main__': - gather_data_loop() diff --git a/decision_agent.py b/decision_agent.py deleted file mode 100644 index 3474448f..00000000 --- a/decision_agent.py +++ /dev/null @@ -1,104 +0,0 @@ -import Stocks -import time -import algoritm -import sqlite3 -import datagatherer - -trading_pairs = [ - "BTC-USD", - "LTC-USD", - "ETH-USD", - "XRP-USD" -] - -cryptos_in_order = [ - "BTC", - "LTC", - "ETH", - "XRP" -] - - -def fetch_data(): - datagatherer.gather_data() - connection = sqlite3.connect('data.db') - cursor = connection.cursor() - cursor.execute('SELECT * FROM data') - data = cursor.fetchall() - return data - - -def extract_prices(data, trading_pair): - prices = [] - for (date, price, exchange) in data: - if exchange == trading_pair: - prices.append(price) - return prices - - -class DecisionAgent: - - def __init__(self): - self.cryptos = { - 'BTC': 0, - 'LTC': 0, - 'ETH': 0, - 'XRP': 0 - } - self.USD = 100000 - self.data = fetch_data() - - #wealthness = current estimated value of cryptos as if they were sold in this moment in USD + USD left - def get_current_wealthness_estimate(self): - crypto_val = 0 - for pair_index in range(4): - crypto_val += self.cryptos[cryptos_in_order[pair_index]] * Stocks.get_current_currency_value('bitbay', - pair_index) - return self.USD + crypto_val - - def buy(self, pair_index, amount_spent): - (bid, ask) = Stocks.consider_commisons('bitbay', Stocks.get_sells_and_buys('bitbay', pair_index)) - amount = amount_spent / ask - self.USD -= amount_spent - self.cryptos[cryptos_in_order[pair_index]] += amount - print(f"Bought {amount} {cryptos_in_order[pair_index]} for {amount_spent} USD") - - def sell(self, pair_index, amount): - (bid, ask) = Stocks.consider_commisons('bitbay', Stocks.get_sells_and_buys('bitbay', pair_index)) - self.cryptos[cryptos_in_order[pair_index]] -= amount - self.USD += amount * bid - print(f"Sold {amount} {cryptos_in_order[pair_index]} for {amount * bid} USD") - - def make_transaction(self): - for pair_index in range(4): - self.data = fetch_data() - decision = algoritm.decide_if_buy_or_sell(extract_prices(self.data, trading_pairs[pair_index]), - Stocks.get_current_currency_value('bitbay', pair_index)) - - diff_percent = algoritm.get_diff_percent(extract_prices(self.data, trading_pairs[pair_index]), - Stocks.get_current_currency_value('bitbay', pair_index)) - - buy_amount = self.USD * diff_percent - sell_amount = self.cryptos[cryptos_in_order[pair_index]] * diff_percent - if decision == 'BUY' and buy_amount > 0: - self.buy(pair_index, buy_amount) - print(f"Current wealthness {self.get_current_wealthness_estimate()}") - elif decision == 'SELL' and sell_amount > 0: - self.sell(pair_index, sell_amount) - print(f"Current wealthness {self.get_current_wealthness_estimate()}") - - def run(self): - print(f"Current wealthness {self.get_current_wealthness_estimate()}") - while True: - self.make_transaction() - time.sleep(1200) - - -if __name__ == '__main__': - ag = DecisionAgent() - #buy some starting cryptos - ag.buy(0, 2000) - ag.buy(1, 2000) - ag.buy(2, 2000) - ag.buy(3, 2000) - ag.run() diff --git a/virualBuget.py b/virualBuget.py deleted file mode 100644 index f24ec65e..00000000 --- a/virualBuget.py +++ /dev/null @@ -1,14 +0,0 @@ - - -class VirtualBudget: - def __init__(self, money): - self.startingMoney = money - self.currentMoney = money - - def make_transaction(self, buy_price, sell_price): - amount_bought = self.currentMoney / buy_price - money_earned = (amount_bought * sell_price) - (amount_bought * buy_price) - self.currentMoney += money_earned - - def print_budget(self): - print(f"My current budget state: {self.currentMoney}") \ No newline at end of file diff --git a/wallet.py b/wallet.py new file mode 100644 index 00000000..48e2d3cc --- /dev/null +++ b/wallet.py @@ -0,0 +1,49 @@ +import sqlite3 + + +def api_supports_resource(): + pass # check if api supports give resource + + +class Wallet: + def __int__(self, base, database): + self.baseCurrency = base + self.database = database + self.wallet = None + self.connection = sqlite3.connect(database) + self.cursor = self.connection.cursor() + self.load_wallet() + + def load_wallet(self): + self.cursor.execute('SELECT * FROM wallet') #or whatever the hell will it be + self.wallet = self.cursor.fetchall() + + def set_base_currency(self, base): + self.baseCurrency = base + + def add_resources(self, resource, amount): + self.wallet[resource] += amount + self.save_wallet_state() + + def remove_resources(self, resource, amount): + self.wallet[resource] -= amount + self.save_wallet_state() + + def set_resource_state(self, resource, amount): + self.wallet[resource] = amount + + def save_wallet(self): + for resource in self.wallet: + self.cursor.execute('''UPDATE wallet + SET amount = ? + WHERE resource = ?''', + self.wallet[resource], resource) + + def add_new_resource(self, resource, base_amount=0): + if api_supports_resource(): + self.save_wallet() + self.cursor.execute("INSERT INTO wallet VALUES (?,?)", resource, base_amount) + self.connection.commit() + self.load_wallet() + else: + print("resource not supported") \ No newline at end of file From e34e23e39333b1694f7b02abe98aaafab5969359 Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Fri, 15 May 2020 22:00:29 +0200 Subject: [PATCH 09/18] begin working on cli --- .gitignore | 3 +++ consoleapp.py | 37 +++++++++++++++++++++++++++++++++++++ createdb.py | 2 +- wallet.db | Bin 0 -> 12288 bytes wallet.py | 23 ++++++++++------------- 5 files changed, 51 insertions(+), 14 deletions(-) create mode 100644 .gitignore create mode 100644 consoleapp.py create mode 100644 wallet.db diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..475612bd --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.idea +/__pycache__ +/.gitingnore \ No newline at end of file diff --git a/consoleapp.py b/consoleapp.py new file mode 100644 index 00000000..f0951704 --- /dev/null +++ b/consoleapp.py @@ -0,0 +1,37 @@ +import click +from wallet import Wallet + +w = Wallet('USD', 'wallet.db') + +w.add_resources('USD', 20) + + +@click.group() +def cli(): + pass + + +@click.command() +def show_state(): + """Show state of the wallet""" + for resource in w.wallet: + click.echo(f"{resource}: {w.wallet[resource]}\n") + + +@click.command() +@click.option('-n', '--new', is_flag=True, help="add completely new resource") +@click.argument('resource') +@click.argument('amount', type=float) +def add_resource(resource, amount, new): + """Add resource to the wallet""" + if new: + w.add_new_resource(resource, base_amount=amount) + else: + w.add_resources(resource, amount) + + +cli.add_command(show_state) +cli.add_command(add_resource) + +if __name__ == '__main__': + cli() diff --git a/createdb.py b/createdb.py index 91a48758..5d636556 100644 --- a/createdb.py +++ b/createdb.py @@ -8,7 +8,7 @@ connection = sqlite3.connect("wallet.db") cursor = connection.cursor() cursor.execute('''CREATE TABLE wallet - (resource text, amount real)''') + (resource text PRIMARY KEY, amount real)''') connection.commit() connection.close() print("New database created.") diff --git a/wallet.db b/wallet.db new file mode 100644 index 0000000000000000000000000000000000000000..616845b43db973e086faa92bec0c38928df80257 GIT binary patch literal 12288 zcmeI$F-yZh6bJCTTuHQ0Pl!-D`9?(%ME9E3fMNwr&d!J!V-=IakIWRWIN<1Rwwb2tWV=5P$##AOHafKwymp`rN5E8vJ=z$NfZ2 z<0MhKyjtzR_d=gSuhsFX+^f=Z>}6__=Gna>t!A2Tg3D_!=+TwmJEVA&=3`Bnij(~V z%dR&YoDIhhYBqUFOkW?xxlaGrQTgTQxU5BAzfpMBObYqI>cuSo>} literal 0 HcmV?d00001 diff --git a/wallet.py b/wallet.py index 48e2d3cc..57c5ca19 100644 --- a/wallet.py +++ b/wallet.py @@ -2,32 +2,33 @@ def api_supports_resource(): - pass # check if api supports give resource + return True # check if api supports give resource class Wallet: - def __int__(self, base, database): + def __init__(self, base, database): self.baseCurrency = base self.database = database - self.wallet = None + self.wallet = dict() self.connection = sqlite3.connect(database) self.cursor = self.connection.cursor() self.load_wallet() def load_wallet(self): self.cursor.execute('SELECT * FROM wallet') #or whatever the hell will it be - self.wallet = self.cursor.fetchall() + self.wallet.update(self.cursor.fetchall()) + def set_base_currency(self, base): self.baseCurrency = base def add_resources(self, resource, amount): self.wallet[resource] += amount - self.save_wallet_state() + # self.save_wallet_state() def remove_resources(self, resource, amount): self.wallet[resource] -= amount - self.save_wallet_state() + # self.save_wallet_state() def set_resource_state(self, resource, amount): self.wallet[resource] = amount @@ -40,10 +41,6 @@ def save_wallet(self): self.wallet[resource], resource) def add_new_resource(self, resource, base_amount=0): - if api_supports_resource(): - self.save_wallet() - self.cursor.execute("INSERT INTO wallet VALUES (?,?)", resource, base_amount) - self.connection.commit() - self.load_wallet() - else: - print("resource not supported") \ No newline at end of file + self.wallet[resource] = base_amount + self.cursor.execute("INSERT INTO wallet VALUES (?,?)", (resource, base_amount)) + self.connection.commit() \ No newline at end of file From 0806032dccc56d7c0429ad898da5be45c8bd02a2 Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Sat, 16 May 2020 19:55:04 +0200 Subject: [PATCH 10/18] manage wallet resources and eval wallet value added --- apiBroker.py | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ consoleapp.py | 52 ++++++++++++++++++++++++++++++------- wallet.db | Bin 12288 -> 12288 bytes wallet.py | 56 ++++++++++++++++++++++++++++------------ 4 files changed, 153 insertions(+), 25 deletions(-) create mode 100644 apiBroker.py diff --git a/apiBroker.py b/apiBroker.py new file mode 100644 index 00000000..a3d0e9b7 --- /dev/null +++ b/apiBroker.py @@ -0,0 +1,70 @@ +import requests + +"""api: https://docs.bitbay.net/v1.0.1-en/reference """ + +baseCurrencies = [ + 'PLN', + 'EUR', + 'USD', + 'BTC', + 'USDC', + 'GBP' +] + + +def get_markets(): + markets = [] + url = f"https://api.bitbay.net/rest/trading/ticker" + headers = {'content-type': 'application/json'} + + data = requests.request("GET", url, headers=headers).json() + for item in data['items']: + markets.append(item) + return markets + + +def api_supports_resource(resource): + markets = get_markets() + for trading_pair in markets: + currency = trading_pair.split('-')[0] + if currency == resource: + return True + return False + + +def getBuyOrders(currency, resource): + url = f"https://api.bitbay.net/rest/trading/orderbook/{resource}-{currency}" + + headers = {'content-type': 'application/json'} + + response = requests.request("GET", url, headers=headers).json() + + if response['status'] == 'Fail': + return None + else: + buys = sorted(response['buy'], key=lambda dict: float(dict['ra']), reverse=True) + return buys + + +def evalValue(currency, resource, amount, consider_fee=True): + orderbook = getBuyOrders(currency, resource) + if orderbook is None: + return None + else: + total_value = 0 + for buys in orderbook: + ca = float(buys['ca']) + ra = float(buys['ra']) + diff = ca if amount - ca >= 0 else amount + amount -= diff + total_value += diff * ra + if amount == 0: + break + if consider_fee: + return total_value * 0.975 + else: + return total_value + + +if __name__ == '__main__': + pass diff --git a/consoleapp.py b/consoleapp.py index f0951704..3bc24ada 100644 --- a/consoleapp.py +++ b/consoleapp.py @@ -1,37 +1,71 @@ import click from wallet import Wallet +import apiBroker w = Wallet('USD', 'wallet.db') -w.add_resources('USD', 20) - @click.group() def cli(): pass -@click.command() +@cli.command() def show_state(): """Show state of the wallet""" for resource in w.wallet: click.echo(f"{resource}: {w.wallet[resource]}\n") -@click.command() +@cli.command() @click.option('-n', '--new', is_flag=True, help="add completely new resource") @click.argument('resource') @click.argument('amount', type=float) def add_resource(resource, amount, new): """Add resource to the wallet""" - if new: - w.add_new_resource(resource, base_amount=amount) + if apiBroker.api_supports_resource(resource): + if new: + w.add_new_resource(resource, base_amount=amount) + else: + w.add_resources(resource, amount) + else: + print(f"resource {resource} not supported") + +@cli.command() +@click.argument('resource') +@click.argument('amount', type=float) +def lower_resource(resource, amount): + """lower an amount of resource in the wallet""" + if resource in w.wallet.keys(): + w.remove_resources(resource, amount) + else: + print("No such resource in the wallet") + + +@cli.command() +@click.argument('resource') +def remove_resource(resource): + """remove resource from the wallet""" + if resource in w.wallet.keys(): + w.remove_resource_from_wallet(resource) else: - w.add_resources(resource, amount) + print("No such resource in the wallet") + +@cli.command() +@click.argument('resource') +@click.argument('amount') +def set_resource(resource, amount): + """set resource to a given amount""" + if resource in w.wallet.keys(): + w.set_resource_state(resource, amount) + +@cli.command() +@click.argument('currency') +def check_value_in(currency): + """Evaluate value of wallet in given currency""" + w.eval_wallet_value(currency) -cli.add_command(show_state) -cli.add_command(add_resource) if __name__ == '__main__': cli() diff --git a/wallet.db b/wallet.db index 616845b43db973e086faa92bec0c38928df80257..a54148afd7b050a3e342e6c1792ff1c3b29ddf1d 100644 GIT binary patch delta 91 zcmZojXh@hK&B#7c#+i|QW5PmyUj82pO#Js5`QP*3=fA&MP~ZeVCs2r!F*Mla+vNN5 p65g@_l&;adt*#VaCv4 h7ZEP7f|m^ZANgPM{{$+y!9V$#zA!r*voI%69sr@l7F_@U diff --git a/wallet.py b/wallet.py index 57c5ca19..898c93c8 100644 --- a/wallet.py +++ b/wallet.py @@ -1,13 +1,9 @@ import sqlite3 - - -def api_supports_resource(): - return True # check if api supports give resource +import apiBroker class Wallet: def __init__(self, base, database): - self.baseCurrency = base self.database = database self.wallet = dict() self.connection = sqlite3.connect(database) @@ -15,32 +11,60 @@ def __init__(self, base, database): self.load_wallet() def load_wallet(self): - self.cursor.execute('SELECT * FROM wallet') #or whatever the hell will it be + self.cursor.execute('SELECT * FROM wallet') self.wallet.update(self.cursor.fetchall()) - - def set_base_currency(self, base): - self.baseCurrency = base - def add_resources(self, resource, amount): self.wallet[resource] += amount - # self.save_wallet_state() + self.save_wallet() def remove_resources(self, resource, amount): self.wallet[resource] -= amount - # self.save_wallet_state() + self.save_wallet() def set_resource_state(self, resource, amount): self.wallet[resource] = amount + self.save_wallet() def save_wallet(self): for resource in self.wallet: self.cursor.execute('''UPDATE wallet SET amount = ? WHERE resource = ?''', - self.wallet[resource], resource) + (self.wallet[resource], resource)) + self.connection.commit() + + def remove_resource_from_wallet(self, resource): + self.cursor.execute( + '''DELETE FROM wallet + WHERE resource = ?''', + [resource] + ) + self.connection.commit() def add_new_resource(self, resource, base_amount=0): - self.wallet[resource] = base_amount - self.cursor.execute("INSERT INTO wallet VALUES (?,?)", (resource, base_amount)) - self.connection.commit() \ No newline at end of file + if apiBroker.api_supports_resource(resource): + self.wallet[resource] = base_amount + self.cursor.execute("INSERT INTO wallet VALUES (?,?)", (resource, base_amount)) + self.connection.commit() + else: + print(f"API does not support cryptocurrency: {resource}") + + def eval_wallet_value(self, currency): + total_value = 0 + print(f"Evaluating wallet value in {currency}:") + for resource in self.wallet: + if resource == currency: + val = self.wallet[resource] + else: + val = apiBroker.evalValue(currency, resource, self.wallet[resource]) + if val is None: + print(f"{resource} : trading for {currency} is not possible on the market") + else: + print(f"{resource} : {val}") + total_value += val + print(f"Total wallet value in {currency}: {total_value}") + + +if __name__ == '__main__': + pass From 651f308a8f25a4744f1cba568fd5c1a5b479130f Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Sun, 17 May 2020 00:41:49 +0200 Subject: [PATCH 11/18] add about and some descriptions --- about.txt | 11 +++++++++++ consoleapp.py => virtualWallet.py | 20 ++++++++++++-------- wallet.db | Bin 12288 -> 12288 bytes wallet.py | 2 +- 4 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 about.txt rename consoleapp.py => virtualWallet.py (76%) diff --git a/about.txt b/about.txt new file mode 100644 index 00000000..deafcab5 --- /dev/null +++ b/about.txt @@ -0,0 +1,11 @@ + +Aplikacja wirtalnego portfela z interfesjem konsolowym. + +Głównym skryptem jest skrypt virtualWallet.py, aby zacząć należy odpalić go w ulubionej konsoli za pomocą interpretera języka pyhton: + +Komendy wyświetlające pomoc: +python virtualWallet.py +albo +pyhton virtualWallet.py --help + +Jeśli chciałbyś zacząć od czystego portfela, uruchom za pomocą pythona skrypt createdb.py \ No newline at end of file diff --git a/consoleapp.py b/virtualWallet.py similarity index 76% rename from consoleapp.py rename to virtualWallet.py index 3bc24ada..2136070d 100644 --- a/consoleapp.py +++ b/virtualWallet.py @@ -2,11 +2,15 @@ from wallet import Wallet import apiBroker -w = Wallet('USD', 'wallet.db') +w = Wallet('wallet.db') @click.group() def cli(): + """ + Virtual wallet app + Try COMMAND --help to see the usage of specific commands + """ pass @@ -19,10 +23,10 @@ def show_state(): @cli.command() @click.option('-n', '--new', is_flag=True, help="add completely new resource") -@click.argument('resource') +@click.argument('resource', type=str) @click.argument('amount', type=float) def add_resource(resource, amount, new): - """Add resource to the wallet""" + """Add an amonunt of resource to the wallet, use option -n or --new if you are adding completly new resource """ if apiBroker.api_supports_resource(resource): if new: w.add_new_resource(resource, base_amount=amount) @@ -32,7 +36,7 @@ def add_resource(resource, amount, new): print(f"resource {resource} not supported") @cli.command() -@click.argument('resource') +@click.argument('resource', type=str) @click.argument('amount', type=float) def lower_resource(resource, amount): """lower an amount of resource in the wallet""" @@ -43,7 +47,7 @@ def lower_resource(resource, amount): @cli.command() -@click.argument('resource') +@click.argument('resource', type=str) def remove_resource(resource): """remove resource from the wallet""" if resource in w.wallet.keys(): @@ -52,8 +56,8 @@ def remove_resource(resource): print("No such resource in the wallet") @cli.command() -@click.argument('resource') -@click.argument('amount') +@click.argument('resource', type=str) +@click.argument('amount', type=float) def set_resource(resource, amount): """set resource to a given amount""" if resource in w.wallet.keys(): @@ -61,7 +65,7 @@ def set_resource(resource, amount): @cli.command() -@click.argument('currency') +@click.argument('currency', type=str) def check_value_in(currency): """Evaluate value of wallet in given currency""" w.eval_wallet_value(currency) diff --git a/wallet.db b/wallet.db index a54148afd7b050a3e342e6c1792ff1c3b29ddf1d..82bb91171e7bf9f3f59a57d2b5ae3a690f0807f8 100644 GIT binary patch delta 70 zcmZojXh@hK&B!!S#+i|6W5PmyP6h@BM*bfR{697eD%{|o*dQjv#>gzp=@jD31(y2B O!2c5}CC<(UkpTdN#Su{e delta 122 zcmZojXh@hK&B#7c#+i|QW5PmyUj82pO#Js5`QP*3=fA&MP~Zf=1yG2SF*Mla8y_>X zFuQArhyBi(ATW!KiCLJ_Da4rp2sk)^D!BN60(HM+;Qz?~lK&@A_icW0c4lElpdMxr N4OGhnRLc%j3ILJ@AWHxM diff --git a/wallet.py b/wallet.py index 898c93c8..160ca48b 100644 --- a/wallet.py +++ b/wallet.py @@ -3,7 +3,7 @@ class Wallet: - def __init__(self, base, database): + def __init__(self, database): self.database = database self.wallet = dict() self.connection = sqlite3.connect(database) From 4b5a7fac2e741c67052679763212c1e7685f8fe6 Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Sun, 17 May 2020 01:35:03 +0200 Subject: [PATCH 12/18] option to omit taker fees added --- virtualWallet.py | 23 +++++++++++++++-------- wallet.db | Bin 12288 -> 12288 bytes wallet.py | 4 ++-- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/virtualWallet.py b/virtualWallet.py index 2136070d..b0bd2eda 100644 --- a/virtualWallet.py +++ b/virtualWallet.py @@ -18,7 +18,7 @@ def cli(): def show_state(): """Show state of the wallet""" for resource in w.wallet: - click.echo(f"{resource}: {w.wallet[resource]}\n") + click.echo(f"{resource}: {w.wallet[resource]}") @cli.command() @@ -26,14 +26,18 @@ def show_state(): @click.argument('resource', type=str) @click.argument('amount', type=float) def add_resource(resource, amount, new): - """Add an amonunt of resource to the wallet, use option -n or --new if you are adding completly new resource """ + """Add an amount of resource to the wallet, see --help for options """ if apiBroker.api_supports_resource(resource): if new: w.add_new_resource(resource, base_amount=amount) else: - w.add_resources(resource, amount) + if resource in w.wallet.keys(): + w.add_resources(resource, amount) + else: + click.echo("no such resource in wallet") else: - print(f"resource {resource} not supported") + click.echo(f"resource {resource} not supported") + @cli.command() @click.argument('resource', type=str) @@ -43,7 +47,7 @@ def lower_resource(resource, amount): if resource in w.wallet.keys(): w.remove_resources(resource, amount) else: - print("No such resource in the wallet") + click.echo("No such resource in the wallet") @cli.command() @@ -53,7 +57,8 @@ def remove_resource(resource): if resource in w.wallet.keys(): w.remove_resource_from_wallet(resource) else: - print("No such resource in the wallet") + click.echo("No such resource in the wallet") + @cli.command() @click.argument('resource', type=str) @@ -66,9 +71,11 @@ def set_resource(resource, amount): @cli.command() @click.argument('currency', type=str) -def check_value_in(currency): +@click.option('-o', '--omit-fee', is_flag=True, help="omit taker fee when calculating value") +def check_value_in(currency, omit_fee): """Evaluate value of wallet in given currency""" - w.eval_wallet_value(currency) + consider_fee = not omit_fee # this exists for clarity's sake + w.eval_wallet_value(currency, consider_fee) if __name__ == '__main__': diff --git a/wallet.db b/wallet.db index 82bb91171e7bf9f3f59a57d2b5ae3a690f0807f8..db352a54ee84c3aeea09744598904c1a132e0c32 100644 GIT binary patch delta 125 zcmZojXh@hK&B!)U#+i|AW5N=CE@u7<4E!JXAMjt;EGTe@-;R%&S(x1?#M!>3>Y@8O zk!n6BAm25_!@;D10R;FMfqW;R{D-fH`eQV{aRJ4c`Cl^d|K$J3{}O1%ZGLffW?@F4 R5zHVOsFjJ0S(p>31pteGAW#4R delta 67 zcmZojXh@hK&B!!S#+i|6W5N=CHb(v*4E#Sf3o6{;pV%NK#Ky=h%;^;3%*DXKz{vlT Of&V8|N}QbyA_D+*M-fo~ diff --git a/wallet.py b/wallet.py index 160ca48b..d0a586ad 100644 --- a/wallet.py +++ b/wallet.py @@ -50,14 +50,14 @@ def add_new_resource(self, resource, base_amount=0): else: print(f"API does not support cryptocurrency: {resource}") - def eval_wallet_value(self, currency): + def eval_wallet_value(self, currency, consider_fee): total_value = 0 print(f"Evaluating wallet value in {currency}:") for resource in self.wallet: if resource == currency: val = self.wallet[resource] else: - val = apiBroker.evalValue(currency, resource, self.wallet[resource]) + val = apiBroker.evalValue(currency, resource, self.wallet[resource], consider_fee=consider_fee) if val is None: print(f"{resource} : trading for {currency} is not possible on the market") else: From 08248fdaa4b2b8fa9d7836483cef010ae87a5ca6 Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Sun, 24 May 2020 00:56:23 +0200 Subject: [PATCH 13/18] start working on l6 --- about.txt | 11 ------- apiBroker.py | 72 +++++------------------------------------ createdb.py | 14 -------- sim.py | 29 +++++++++++++++++ virtualWallet.py | 82 ----------------------------------------------- wallet.db | Bin 12288 -> 0 bytes wallet.py | 70 ---------------------------------------- 7 files changed, 37 insertions(+), 241 deletions(-) delete mode 100644 about.txt delete mode 100644 createdb.py create mode 100644 sim.py delete mode 100644 virtualWallet.py delete mode 100644 wallet.db delete mode 100644 wallet.py diff --git a/about.txt b/about.txt deleted file mode 100644 index deafcab5..00000000 --- a/about.txt +++ /dev/null @@ -1,11 +0,0 @@ - -Aplikacja wirtalnego portfela z interfesjem konsolowym. - -Głównym skryptem jest skrypt virtualWallet.py, aby zacząć należy odpalić go w ulubionej konsoli za pomocą interpretera języka pyhton: - -Komendy wyświetlające pomoc: -python virtualWallet.py -albo -pyhton virtualWallet.py --help - -Jeśli chciałbyś zacząć od czystego portfela, uruchom za pomocą pythona skrypt createdb.py \ No newline at end of file diff --git a/apiBroker.py b/apiBroker.py index a3d0e9b7..712a16dd 100644 --- a/apiBroker.py +++ b/apiBroker.py @@ -1,70 +1,14 @@ import requests -"""api: https://docs.bitbay.net/v1.0.1-en/reference """ -baseCurrencies = [ - 'PLN', - 'EUR', - 'USD', - 'BTC', - 'USDC', - 'GBP' -] - - -def get_markets(): - markets = [] - url = f"https://api.bitbay.net/rest/trading/ticker" - headers = {'content-type': 'application/json'} - - data = requests.request("GET", url, headers=headers).json() - for item in data['items']: - markets.append(item) - return markets - - -def api_supports_resource(resource): - markets = get_markets() - for trading_pair in markets: - currency = trading_pair.split('-')[0] - if currency == resource: - return True - return False - - -def getBuyOrders(currency, resource): - url = f"https://api.bitbay.net/rest/trading/orderbook/{resource}-{currency}" - - headers = {'content-type': 'application/json'} - - response = requests.request("GET", url, headers=headers).json() - - if response['status'] == 'Fail': - return None +def get_all_data(trading_pair): + (fst, snd) = trading_pair.split("-") + url = f"https://min-api.cryptocompare.com/data/v2/histoday?fsym={fst}&tsym={snd}&allData=true" + resp = requests.get(url) + if resp.status_code != 200: + raise ConnectionError('Error during fetching the data, Error code: {}'.format(resp.status_code)) else: - buys = sorted(response['buy'], key=lambda dict: float(dict['ra']), reverse=True) - return buys - - -def evalValue(currency, resource, amount, consider_fee=True): - orderbook = getBuyOrders(currency, resource) - if orderbook is None: - return None - else: - total_value = 0 - for buys in orderbook: - ca = float(buys['ca']) - ra = float(buys['ra']) - diff = ca if amount - ca >= 0 else amount - amount -= diff - total_value += diff * ra - if amount == 0: - break - if consider_fee: - return total_value * 0.975 - else: - return total_value - + return resp.json() if __name__ == '__main__': - pass + print(get_all_data("LTC-USD")) \ No newline at end of file diff --git a/createdb.py b/createdb.py deleted file mode 100644 index 5d636556..00000000 --- a/createdb.py +++ /dev/null @@ -1,14 +0,0 @@ -import sqlite3 -import os - - -if os.path.exists("wallet.db"): - os.remove("wallet.db") - print("Old database removed.") -connection = sqlite3.connect("wallet.db") -cursor = connection.cursor() -cursor.execute('''CREATE TABLE wallet - (resource text PRIMARY KEY, amount real)''') -connection.commit() -connection.close() -print("New database created.") diff --git a/sim.py b/sim.py new file mode 100644 index 00000000..28c84342 --- /dev/null +++ b/sim.py @@ -0,0 +1,29 @@ +import apiBroker +import time + +pairs = [ + "BTC-USD", + "ETH-USD", + "LTC-USD" +] + + +def sim(trading_pair, starting_date, ending_date): + if ending_date >= time.time() or starting_date >= ending_date: + raise ValueError("Wrong date range") + if trading_pair not in pairs: + raise ValueError("Wrong trading pair") + data = apiBroker.get_all_data(trading_pair) + +def check_if_price_has_risen(open, close): + return close > open + +def count_probabilities(data): + a = 0 + total_volume = 0 + for record in data["Data"]: + pass#??? + + +if __name__ == '__main__': + sim("BTC-USD", 1589328000, 1590192000) \ No newline at end of file diff --git a/virtualWallet.py b/virtualWallet.py deleted file mode 100644 index b0bd2eda..00000000 --- a/virtualWallet.py +++ /dev/null @@ -1,82 +0,0 @@ -import click -from wallet import Wallet -import apiBroker - -w = Wallet('wallet.db') - - -@click.group() -def cli(): - """ - Virtual wallet app - Try COMMAND --help to see the usage of specific commands - """ - pass - - -@cli.command() -def show_state(): - """Show state of the wallet""" - for resource in w.wallet: - click.echo(f"{resource}: {w.wallet[resource]}") - - -@cli.command() -@click.option('-n', '--new', is_flag=True, help="add completely new resource") -@click.argument('resource', type=str) -@click.argument('amount', type=float) -def add_resource(resource, amount, new): - """Add an amount of resource to the wallet, see --help for options """ - if apiBroker.api_supports_resource(resource): - if new: - w.add_new_resource(resource, base_amount=amount) - else: - if resource in w.wallet.keys(): - w.add_resources(resource, amount) - else: - click.echo("no such resource in wallet") - else: - click.echo(f"resource {resource} not supported") - - -@cli.command() -@click.argument('resource', type=str) -@click.argument('amount', type=float) -def lower_resource(resource, amount): - """lower an amount of resource in the wallet""" - if resource in w.wallet.keys(): - w.remove_resources(resource, amount) - else: - click.echo("No such resource in the wallet") - - -@cli.command() -@click.argument('resource', type=str) -def remove_resource(resource): - """remove resource from the wallet""" - if resource in w.wallet.keys(): - w.remove_resource_from_wallet(resource) - else: - click.echo("No such resource in the wallet") - - -@cli.command() -@click.argument('resource', type=str) -@click.argument('amount', type=float) -def set_resource(resource, amount): - """set resource to a given amount""" - if resource in w.wallet.keys(): - w.set_resource_state(resource, amount) - - -@cli.command() -@click.argument('currency', type=str) -@click.option('-o', '--omit-fee', is_flag=True, help="omit taker fee when calculating value") -def check_value_in(currency, omit_fee): - """Evaluate value of wallet in given currency""" - consider_fee = not omit_fee # this exists for clarity's sake - w.eval_wallet_value(currency, consider_fee) - - -if __name__ == '__main__': - cli() diff --git a/wallet.db b/wallet.db deleted file mode 100644 index db352a54ee84c3aeea09744598904c1a132e0c32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI$ze~eF6bJCToTOT4PpD8bd1FNp#P0n?P_cs6ECnH?dX_@kV0y)(i-NoViGPHv zi+_TSZgo&}^QEES*17O~@bdERxDYYFroCT+s zrCCEY>F0&bw#zCff0!k^Om^kVyaU*W00bZa0SG_<0uX=z1Rwwb2rRHbhi8h8!|&Hk z&#Yo4pTTD|G2bS Date: Sun, 24 May 2020 21:13:11 +0200 Subject: [PATCH 14/18] added function counting probablilities --- apiBroker.py | 9 ++++++++- sim.py | 28 ++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/apiBroker.py b/apiBroker.py index 712a16dd..d45cd8a0 100644 --- a/apiBroker.py +++ b/apiBroker.py @@ -10,5 +10,12 @@ def get_all_data(trading_pair): else: return resp.json() + +def get_data(trading_pair, timestamp_from, timestamp_to): + data = get_all_data(trading_pair) + return filter(lambda data: data["time"] in range(timestamp_from, timestamp_to + 1), data["Data"]["Data"]) + + if __name__ == '__main__': - print(get_all_data("LTC-USD")) \ No newline at end of file + data = get_data("BTC-USD", 1589328000, 1590192000) + print(data) diff --git a/sim.py b/sim.py index 28c84342..a7b4c5e4 100644 --- a/sim.py +++ b/sim.py @@ -1,5 +1,6 @@ import apiBroker import time +import datetime pairs = [ "BTC-USD", @@ -8,22 +9,37 @@ ] +# YYYY-MM_DD format +def convert_dates(human_readable_date): + (yyyy, mm, dd) = (human_readable_date.split("-")) + date = datetime.datetime(int(yyyy), int(mm), int(dd)) + return int(date.timestamp()) + + def sim(trading_pair, starting_date, ending_date): + starting_date = convert_dates(starting_date) + ending_date = convert_dates(ending_date) if ending_date >= time.time() or starting_date >= ending_date: raise ValueError("Wrong date range") if trading_pair not in pairs: raise ValueError("Wrong trading pair") - data = apiBroker.get_all_data(trading_pair) + data = apiBroker.get_data(trading_pair, starting_date, ending_date) + print(count_rise_probability(data)) -def check_if_price_has_risen(open, close): + +def price_has_risen(open, close): return close > open -def count_probabilities(data): + +def count_rise_probability(data): a = 0 total_volume = 0 - for record in data["Data"]: - pass#??? + for record in data: + if price_has_risen(float(record['open']), float(record['close'])): + a += record['volumefrom'] + total_volume += record['volumefrom'] + return a / total_volume if __name__ == '__main__': - sim("BTC-USD", 1589328000, 1590192000) \ No newline at end of file + sim("BTC-USD", "2020-05-18", "2020-05-24") From be77e92766cc2bd132b5c9b73894a663687cd2b4 Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Mon, 25 May 2020 17:35:04 +0200 Subject: [PATCH 15/18] start working on plots --- apiBroker.py | 6 ++++-- graphs.py | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 graphs.py diff --git a/apiBroker.py b/apiBroker.py index d45cd8a0..f61e7fc3 100644 --- a/apiBroker.py +++ b/apiBroker.py @@ -1,6 +1,7 @@ import requests + def get_all_data(trading_pair): (fst, snd) = trading_pair.split("-") url = f"https://min-api.cryptocompare.com/data/v2/histoday?fsym={fst}&tsym={snd}&allData=true" @@ -13,9 +14,10 @@ def get_all_data(trading_pair): def get_data(trading_pair, timestamp_from, timestamp_to): data = get_all_data(trading_pair) - return filter(lambda data: data["time"] in range(timestamp_from, timestamp_to + 1), data["Data"]["Data"]) + return filter(lambda data: float(timestamp_from) <= float(data["time"]) <= float(timestamp_to), data["Data"]["Data"]) if __name__ == '__main__': data = get_data("BTC-USD", 1589328000, 1590192000) - print(data) + for record in data: + print(record) diff --git a/graphs.py b/graphs.py new file mode 100644 index 00000000..7d9e1489 --- /dev/null +++ b/graphs.py @@ -0,0 +1,23 @@ +import apiBroker +import seaborn as sns +import matplotlib.pyplot as plt +import pandas as pd + + +def draw(data, title): + + fig = plt.figure() + ax1 = fig.add_subplot(211) + ax2 = fig.add_subplot(212) + dataset = pd.DataFrame(data) + dataset['time'] = pd.to_datetime(dataset['time'], unit='s') + print(dataset[['time', 'open', 'close']]) + dataset.plot(kind='line' , x='time', y='open', title=title, ax=ax1) + dataset.plot(kind="bar", x='time', y='volumefrom', stacked=True, ax=ax2) + dataset.info() + + plt.show() + + +if __name__ == '__main__': + draw(apiBroker.get_data("BTC-USD", 1589328000, 1590192000), title="BTC-USD") \ No newline at end of file From 183b93e3dd598c35a5ecfdcb003a36189e5e7746 Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Wed, 27 May 2020 15:06:43 +0200 Subject: [PATCH 16/18] add pandas data computation tests --- apiBroker.py | 2 +- sim.py | 24 ++++++++++-------------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/apiBroker.py b/apiBroker.py index f61e7fc3..c479742e 100644 --- a/apiBroker.py +++ b/apiBroker.py @@ -14,7 +14,7 @@ def get_all_data(trading_pair): def get_data(trading_pair, timestamp_from, timestamp_to): data = get_all_data(trading_pair) - return filter(lambda data: float(timestamp_from) <= float(data["time"]) <= float(timestamp_to), data["Data"]["Data"]) + return list(filter(lambda data: float(timestamp_from) <= float(data["time"]) <= float(timestamp_to), data["Data"]["Data"])) if __name__ == '__main__': diff --git a/sim.py b/sim.py index a7b4c5e4..d7156ca3 100644 --- a/sim.py +++ b/sim.py @@ -1,6 +1,8 @@ import apiBroker import time import datetime +import numpy as np +import pandas as pd pairs = [ "BTC-USD", @@ -23,23 +25,17 @@ def sim(trading_pair, starting_date, ending_date): raise ValueError("Wrong date range") if trading_pair not in pairs: raise ValueError("Wrong trading pair") - data = apiBroker.get_data(trading_pair, starting_date, ending_date) - print(count_rise_probability(data)) - - -def price_has_risen(open, close): - return close > open + data = pd.DataFrame(apiBroker.get_data(trading_pair, starting_date, ending_date)) + count_rise_probability(data) def count_rise_probability(data): - a = 0 - total_volume = 0 - for record in data: - if price_has_risen(float(record['open']), float(record['close'])): - a += record['volumefrom'] - total_volume += record['volumefrom'] - return a / total_volume + data['diff'] = data['open'] - data['close'] + total_change_in_price = np.abs(data['diff']).sum() + print((data['diff'][data['diff'] > 0]).sum()) + print(total_change_in_price) + print((data['diff'][data['diff']]).sum() / total_change_in_price) if __name__ == '__main__': - sim("BTC-USD", "2020-05-18", "2020-05-24") + sim("BTC-USD", "2020-04-18", "2020-05-24") From c3dd85eb8772e9d46551e341b121fd0529ea9d10 Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Sat, 30 May 2020 20:03:07 +0200 Subject: [PATCH 17/18] added simulations and statistics --- apiBroker.py | 4 ++-- graphs.py | 10 ++++---- sim.py | 68 +++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/apiBroker.py b/apiBroker.py index c479742e..e20f3fa8 100644 --- a/apiBroker.py +++ b/apiBroker.py @@ -1,7 +1,6 @@ import requests - def get_all_data(trading_pair): (fst, snd) = trading_pair.split("-") url = f"https://min-api.cryptocompare.com/data/v2/histoday?fsym={fst}&tsym={snd}&allData=true" @@ -14,7 +13,8 @@ def get_all_data(trading_pair): def get_data(trading_pair, timestamp_from, timestamp_to): data = get_all_data(trading_pair) - return list(filter(lambda data: float(timestamp_from) <= float(data["time"]) <= float(timestamp_to), data["Data"]["Data"])) + return list( + filter(lambda data: float(timestamp_from) <= float(data["time"]) <= float(timestamp_to), data["Data"]["Data"])) if __name__ == '__main__': diff --git a/graphs.py b/graphs.py index 7d9e1489..a74b40bb 100644 --- a/graphs.py +++ b/graphs.py @@ -11,10 +11,12 @@ def draw(data, title): ax2 = fig.add_subplot(212) dataset = pd.DataFrame(data) dataset['time'] = pd.to_datetime(dataset['time'], unit='s') - print(dataset[['time', 'open', 'close']]) - dataset.plot(kind='line' , x='time', y='open', title=title, ax=ax1) - dataset.plot(kind="bar", x='time', y='volumefrom', stacked=True, ax=ax2) - dataset.info() + ax1 = dataset.plot(kind='line' , x='time', y='open', title=title, ax=ax1) + ax1.set_xlabel("time") + ax1.set_ylabel("price") + ax2 = dataset.plot(kind="bar", x='time', y='volumefrom', stacked=True, ax=ax2) + ax2.set_xlabel("time") + ax2.set_ylabel("volume") plt.show() diff --git a/sim.py b/sim.py index d7156ca3..179beecd 100644 --- a/sim.py +++ b/sim.py @@ -3,6 +3,7 @@ import datetime import numpy as np import pandas as pd +import graphs pairs = [ "BTC-USD", @@ -18,7 +19,14 @@ def convert_dates(human_readable_date): return int(date.timestamp()) -def sim(trading_pair, starting_date, ending_date): +def sim(trading_pair, starting_date, ending_date, count): + data_list = [] + for i in range(count): + data_list.append(sim_one(trading_pair, starting_date, ending_date)) + return data_list + + +def sim_one(trading_pair, starting_date, ending_date): starting_date = convert_dates(starting_date) ending_date = convert_dates(ending_date) if ending_date >= time.time() or starting_date >= ending_date: @@ -26,16 +34,64 @@ def sim(trading_pair, starting_date, ending_date): if trading_pair not in pairs: raise ValueError("Wrong trading pair") data = pd.DataFrame(apiBroker.get_data(trading_pair, starting_date, ending_date)) - count_rise_probability(data) + data = data[['time', 'open', 'close', 'volumefrom']] + days = int((ending_date - starting_date) / (24 * 60 * 60)) + data['months'] = int(days / 30) + data['months'] = data['months'].clip(lower=1) + for i in range(days): + data = data.append(generate_entry(data), ignore_index=True) + data = data.drop(columns=['months', 'diff']) + return data + + +def generate_entry(data): + price_change = (decide_how_price_changes(data, count_rise_probability(data))) + new_volume = decide_volume_change(data, price_change) + last_entry = data.tail(1) + time = last_entry['time'] + (24 * 60 * 60) # 24 hours in seconds + open = last_entry['close'] + close = open + price_change + diff = np.abs(price_change) + new_entry = pd.DataFrame({'time': time, 'open': open, 'volumefrom': new_volume, 'close': close, 'diff': diff}) + return new_entry + + +def decide_volume_change(data, price_change): + diff = np.abs(price_change) + result_index = data['diff'].sub(diff).abs().idxmin() + return data.iloc[result_index, :]['volumefrom'] def count_rise_probability(data): data['diff'] = data['open'] - data['close'] total_change_in_price = np.abs(data['diff']).sum() - print((data['diff'][data['diff'] > 0]).sum()) - print(total_change_in_price) - print((data['diff'][data['diff']]).sum() / total_change_in_price) + return (data['diff'][data['diff'] > 0]).sum() / total_change_in_price + + +def decide_how_price_changes(data, probability_of_rise): + diffs = data['diff'].abs() + p = np.random.uniform(diffs.min(), diffs.max()) / data.iloc[0]['months'] + if np.random.rand() < probability_of_rise: + return p + else: + a = data.tail(1).iloc[0]['close'] - p + if a - p < 0: + return np.abs(a) + else: + return -p + + +def count_statistics(data): + return {'averages': data.mean(), 'median': data.median(), 'deviation': data.std()} + + +def mean_from_multiple_sims(data_list): + combined = pd.concat(data_list) + means = combined.groupby(combined.index).mean() + return means if __name__ == '__main__': - sim("BTC-USD", "2020-04-18", "2020-05-24") + #datao = sim_one("BTC-USD", "2020-01-01", "2020-05-01") + data = sim("BTC-USD", "2020-01-01", "2020-05-01", 5) + graphs.draw(mean_from_multiple_sims(data), 'Avg') From 8e6bf7175b29efa69f317f1b7bc3accad5fbf901 Mon Sep 17 00:00:00 2001 From: Wi1ku Date: Sat, 30 May 2020 21:36:13 +0200 Subject: [PATCH 18/18] some cleanups --- .gitignore | 3 --- apiBroker.py => src/apiBroker.py | 8 +------- graphs.py => src/graphs.py | 11 +++++------ sim.py => src/simulation.py | 24 +++++++++++++++++++----- 4 files changed, 25 insertions(+), 21 deletions(-) delete mode 100644 .gitignore rename apiBroker.py => src/apiBroker.py (75%) rename graphs.py => src/graphs.py (79%) rename sim.py => src/simulation.py (80%) diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 475612bd..00000000 --- a/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/.idea -/__pycache__ -/.gitingnore \ No newline at end of file diff --git a/apiBroker.py b/src/apiBroker.py similarity index 75% rename from apiBroker.py rename to src/apiBroker.py index e20f3fa8..f88f38d8 100644 --- a/apiBroker.py +++ b/src/apiBroker.py @@ -14,10 +14,4 @@ def get_all_data(trading_pair): def get_data(trading_pair, timestamp_from, timestamp_to): data = get_all_data(trading_pair) return list( - filter(lambda data: float(timestamp_from) <= float(data["time"]) <= float(timestamp_to), data["Data"]["Data"])) - - -if __name__ == '__main__': - data = get_data("BTC-USD", 1589328000, 1590192000) - for record in data: - print(record) + filter(lambda data: float(timestamp_from) <= float(data["time"]) <= float(timestamp_to), data["Data"]["Data"])) \ No newline at end of file diff --git a/graphs.py b/src/graphs.py similarity index 79% rename from graphs.py rename to src/graphs.py index a74b40bb..e7fd2e50 100644 --- a/graphs.py +++ b/src/graphs.py @@ -1,5 +1,4 @@ import apiBroker -import seaborn as sns import matplotlib.pyplot as plt import pandas as pd @@ -7,6 +6,7 @@ def draw(data, title): fig = plt.figure() + plt.style.use('seaborn') ax1 = fig.add_subplot(211) ax2 = fig.add_subplot(212) dataset = pd.DataFrame(data) @@ -14,12 +14,11 @@ def draw(data, title): ax1 = dataset.plot(kind='line' , x='time', y='open', title=title, ax=ax1) ax1.set_xlabel("time") ax1.set_ylabel("price") + ax1.legend(['price']) ax2 = dataset.plot(kind="bar", x='time', y='volumefrom', stacked=True, ax=ax2) + ax2.legend(['volume']) ax2.set_xlabel("time") + ax2.set_xticks([]) ax2.set_ylabel("volume") - plt.show() - - -if __name__ == '__main__': - draw(apiBroker.get_data("BTC-USD", 1589328000, 1590192000), title="BTC-USD") \ No newline at end of file + plt.draw() \ No newline at end of file diff --git a/sim.py b/src/simulation.py similarity index 80% rename from sim.py rename to src/simulation.py index 179beecd..e04b2363 100644 --- a/sim.py +++ b/src/simulation.py @@ -5,6 +5,7 @@ import pandas as pd import graphs + pairs = [ "BTC-USD", "ETH-USD", @@ -21,7 +22,7 @@ def convert_dates(human_readable_date): def sim(trading_pair, starting_date, ending_date, count): data_list = [] - for i in range(count): + for _ in range(count): data_list.append(sim_one(trading_pair, starting_date, ending_date)) return data_list @@ -48,7 +49,7 @@ def generate_entry(data): price_change = (decide_how_price_changes(data, count_rise_probability(data))) new_volume = decide_volume_change(data, price_change) last_entry = data.tail(1) - time = last_entry['time'] + (24 * 60 * 60) # 24 hours in seconds + time = last_entry['time'] + (24 * 60 * 60) open = last_entry['close'] close = open + price_change diff = np.abs(price_change) @@ -92,6 +93,19 @@ def mean_from_multiple_sims(data_list): if __name__ == '__main__': - #datao = sim_one("BTC-USD", "2020-01-01", "2020-05-01") - data = sim("BTC-USD", "2020-01-01", "2020-05-01", 5) - graphs.draw(mean_from_multiple_sims(data), 'Avg') + print('Pick a pair') + for i in range(3): + print(f"{i} - {pairs[i]}") + pair = input() + start_date = input("Enter start date(YYYY-MM-DD): ") + end_date = input("Enter end date(YYYY-MM-DD): ") + one = sim_one(pairs[int(pair)], start_date, end_date) + graphs.draw(one, 'Simulation') + stats = count_statistics(one) + print("Statistics from simulation: ") + for stat in stats: + print(f"{stat}:") + print(stats[stat]) + data = sim(pairs[int(pair)], start_date, end_date, 100) + graphs.draw(mean_from_multiple_sims(data), 'Avg from 100 simulations') + graphs.plt.show()