diff --git a/API.py b/API.py new file mode 100644 index 00000000..47a12fe1 --- /dev/null +++ b/API.py @@ -0,0 +1,39 @@ +import requests +import json +import time +import os + + +def cls(): os.system('cls' if os.name == 'nt' else 'clear') + + +def calculateDiff(sell_price, buy_price): + if sell_price == None or buy_price == None: + return -1 + return (float(sell_price) - float(buy_price)) / float(buy_price)*100 + + +def loadFromApi(): + url = 'https://api.bitbay.net/rest/trading/ticker' + headers = {'content-type': 'application/json'} + response = requests.request("GET", url, headers=headers) + return json.loads(response.text) + + +def currencyMonitor(markets): + while True: + response_dict = loadFromApi() + cls() + for market in markets: + diff = calculateDiff(response_dict['items'][market]['lowestAsk'], response_dict['items'][market]['highestBid']) + print("Market: {0:15} Bid: {1:15}\tAsk: {2:15}Difference: {3:.2f} %". + format(market, str(response_dict['items'][market]['highestBid']), str(response_dict['items'][market]['lowestAsk']), diff)) + time.sleep(5) + +def main(): + markets_list = ("BTC-PLN","BTC-USD","ETH-USD","LTC-USD","LSK-USD","BCC-USD","DASH-USD") + currencyMonitor(markets_list) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/API_trade_sim.py b/API_trade_sim.py new file mode 100644 index 00000000..c15d0f38 --- /dev/null +++ b/API_trade_sim.py @@ -0,0 +1,280 @@ +import requests +import json +import time +from datetime import datetime, timedelta +import os +import csv +import sys +import numpy as np + +markets = ("USD-BTC", "USD-ETH", "BTC-LTC", "USD-LTC") +markets_bitfinex = list('t' + market[4:] + market[:3] for market in markets) +markets_binance = list(market[4:] + market[:3] +'T' if market[:3] == 'USD' else market[4:] + market[:3] for market in markets) +markets_bitbay = list((market[4:]+'-'+market[:3] for market in markets)) + +MARKETS_NUM = 4 +bittrexFee = 0.0025 +bitbayFee = 0.0041 +binanceFee = 0.001 +bitfinexFee = 0.002 + +# 0 - USD-BTC +# 1 - USD-ETH +# 2 - BTC-LTC +# 3 - USD-LTC +bittrex_data = np.zeros(shape=(4,2)) +binance_data = np.zeros(shape=(4,2)) +bitfinex_data = np.zeros(shape=(4,2)) +bitbay_data = np.zeros(shape=(4,2)) + +exchanges_data = [bittrex_data, binance_data, bitfinex_data, bitbay_data] +exchanges_labels = ['Bittrex', 'Binance', 'Bitfinex', 'Bitbay'] + +def cls(): os.system('cls' if os.name == 'nt' else 'clear') + + +def calculateDiff(sell_price, buy_price): + if sell_price == None or buy_price == None: + return -1 + return (float(sell_price) - float(buy_price)) / float(buy_price)*100 + + +def loadFromApiBittrex(market, market_number): + url = 'https://api.bittrex.com/api/v1.1/public/getticker?market='+market + response = requests.get(url) + data = response.json() + bittrex_data[market_number][0] = data['result']['Bid'] + bittrex_data[market_number][1] = data['result']['Ask'] + return data['result']['Bid'], data['result']['Ask'] + + +def printDataBittrex(markets): + data = [] + market_number = 0 + for market in markets: + data.append(loadFromApiBittrex(market, market_number)) + market_number+=1 + output = "BITTREX\n" + for i in range(len(markets)): + diff = calculateDiff(data[i][1], data[i][0]) + output += ("Market: {0:15} Bid: {1:15}\tAsk: {2:15}Difference: {3:.2f} %\n". + format(markets[i], str(data[i][0]), str(data[i][1]), diff)) + return output + + +def loadFromApiBinance(market, market_number): + response = requests.get(f'https://api.binance.com/api/v3/depth?symbol={market}&limit=5') + data = response.json() + binance_data[market_number][0] = data['bids'][0][0] + binance_data[market_number][1] = data['asks'][0][0] + return data['bids'][0][0], data['asks'][0][0] + + +def printDataBinance(markets): + data = [] + market_number = 0 + for market in markets_binance: + data.append(loadFromApiBinance(market, market_number)) + market_number+=1 + output = "BINANCE\n" + for i in range(len(markets)): + diff = calculateDiff(data[i][1], data[i][0]) + output += ("Market: {0:15} Bid: {1:15}\tAsk: {2:15}Difference: {3:.2f} %\n". + format(markets[i], str(data[i][0]), str(data[i][1]), diff)) + return output + + +def loadFromApiBitfinex(market, market_number): + response = requests.get(f'https://api-pub.bitfinex.com/v2/book/{market}/P0?len=1') + data = response.json() + bitfinex_data[market_number][0] = data[0][0] + bitfinex_data[market_number][1] = data[1][0] + return data[1][0], data[0][0] + + +def printDataBitfinex(markets): + data = [] + market_number = 0 + for market in markets_bitfinex: + data.append(loadFromApiBitfinex(market, market_number)) + market_number+=1 + output = "BITFINEX\n" + for i in range(len(markets)): + diff = calculateDiff(data[i][0], data[i][1]) + output += ("Market: {0:15} Bid: {1:15}\tAsk: {2:15}Difference: {3:.2f} %\n". + format(markets[i], str(data[i][1]), str(data[i][0]), diff)) + return output + + +def loadFromApiBitBay(): + url = 'https://api.bitbay.net/rest/trading/ticker' + headers = {'content-type': 'application/json'} + response = requests.request("GET", url, headers=headers) + response_dict = json.loads(response.text) + for i in range(len(markets)): + bitbay_data[i][0] = response_dict['items'][markets_bitbay[i]]['highestBid'] + bitbay_data[i][1] = response_dict['items'][markets_bitbay[i]]['lowestAsk'] + return response_dict + + +def printDataBitBay(markets): + response_dict = loadFromApiBitBay() + output = "BITBAY\n" + for i in range(len(markets)): + diff = calculateDiff(response_dict['items'][markets_bitbay[i]]['lowestAsk'], response_dict['items'][markets_bitbay[i]]['highestBid']) + output += ("Market: {0:15} Bid: {1:15}\tAsk: {2:15}Difference: {3:.2f} %\n". + format(markets[i], str(response_dict['items'][markets_bitbay[i]]['highestBid']), str(response_dict['items'][markets_bitbay[i]]['lowestAsk']), diff)) + return output + + + +def trader(investedSum, taxesOn): + while True: + bestDeal = searchProfit(markets, investedSum, taxesOn) + print(bestDeal) + if bestDeal[-1] > investedSum: investedSum = bestDeal[-1] + print("Money sum = ", bestDeal[-1]) + + +def decreaseByFee(market, moneyAmount): + if market == 'Bittrex': + return moneyAmount - moneyAmount*bittrexFee + elif market == 'Binance': + return moneyAmount - moneyAmount*binanceFee + elif market == 'Bitfinex': + return moneyAmount - moneyAmount*bitfinexFee + elif market == 'Bitbay': + return moneyAmount - moneyAmount*bitbayFee + else: + print("Error") + return -1 + + + +def searchProfit(markets, moneyAmount, taxesOn = True, specifiedIndex = -1): + lowestAsk = [float('inf') for x in range(4)] + highestBid = [-1*float('inf') for x in range(4)] + askExchange = ['','','',''] + bidExchange = ['','','',''] + interval = timedelta(seconds=1) + startTime = datetime.now() + control_iter = 0 + + while datetime.now() - startTime < interval: + control_iter+=1 + for i in range(4): + loadFromApiBinance(markets_binance[i], i) + loadFromApiBitfinex(markets_bitfinex[i], i) + loadFromApiBittrex(markets[i], i) + loadFromApiBitBay() + for market in range(len(markets)): + for exchange in range(len(markets)): + testAsk = exchanges_data[exchange][market][1].item() + if testAsk < lowestAsk[market]: + lowestAsk[market] = testAsk + askExchange[market] = exchanges_labels[exchange] + + startTime = datetime.now() + control_iter = 0 + while datetime.now() - startTime < interval: + control_iter+=1 + for i in range(4): + loadFromApiBinance(markets_binance[i], i) + loadFromApiBitfinex(markets_bitfinex[i], i) + loadFromApiBittrex(markets[i], i) + loadFromApiBitBay() + for market in range(len(markets)): + for exchange in range(len(markets)): + testBid = exchanges_data[exchange][market][0].item() + if testBid > highestBid[market]: + highestBid[market] = testBid + bidExchange[market] = exchanges_labels[exchange] + + print(highestBid, "\t", lowestAsk) + diff = [calculateDiff(highestBid[i], lowestAsk[i]) for i in range(4)] + moneyAmount = [moneyAmount for i in range(4)] + print("diff = ", diff) + if specifiedIndex == -1: + for i in range(4): + if diff[i] > 0.0: + if markets[i] != "BTC-LTC": + if taxesOn: moneyAmount[i] = decreaseByFee(askExchange[i], moneyAmount[i]) + currencyAmount = moneyAmount[i]/lowestAsk[i] + if taxesOn: currencyAmount = decreaseByFee(bidExchange[i], currencyAmount) + moneyAmount[i] = currencyAmount*highestBid[i] + else: + moneyAmount[i] = moneyAmount[i]/(exchanges_data[1][0][1].item()) + if taxesOn: moneyAmount[i] = decreaseByFee(askExchange[i], moneyAmount[i]) + currencyAmount = moneyAmount[i]/lowestAsk[i] + if taxesOn: currencyAmount = decreaseByFee(bidExchange[i], currencyAmount) + moneyAmount[i] = currencyAmount*highestBid[i]*(exchanges_data[1][0][0].item()) + print(markets[i]," Buy: ", askExchange[i], " - ", lowestAsk[i], "\tSell: ", bidExchange[i], " - ", highestBid[i],"\tDifference: {0:.2f} %".format(diff[i]), "\t Cash: ", moneyAmount[i]) + outputToCsv([markets[i], askExchange[i], lowestAsk[i], bidExchange[i], highestBid[i], diff[i], moneyAmount[i]]) + else: + print(markets[i], " No profitable pairs") + outputToCsv([markets[i], '-', '-', '-', '-', '-', '-']) + else: + if markets[specifiedIndex] != "BTC-LTC": + if taxesOn: moneyAmount[specifiedIndex] = decreaseByFee(askExchange[specifiedIndex], moneyAmount[specifiedIndex]) + currencyAmount = moneyAmount[specifiedIndex]/lowestAsk[specifiedIndex] + if taxesOn: currencyAmount = decreaseByFee(bidExchange[specifiedIndex], currencyAmount) + moneyAmount[specifiedIndex] = currencyAmount*highestBid[specifiedIndex] + else: + moneyAmount[specifiedIndex] = moneyAmount[specifiedIndex]/(exchanges_data[1][0][1].item()) + if taxesOn: moneyAmount[specifiedIndex] = decreaseByFee(askExchange[specifiedIndex], moneyAmount[specifiedIndex]) + currencyAmount = moneyAmount[specifiedIndex]/lowestAsk[specifiedIndex] + if taxesOn: currencyAmount = decreaseByFee(bidExchange[specifiedIndex], currencyAmount) + moneyAmount[specifiedIndex] = currencyAmount*highestBid[specifiedIndex]*(exchanges_data[1][0][0].item()) + print(markets[specifiedIndex]," Buy: ", askExchange[specifiedIndex], " - ", lowestAsk[specifiedIndex], "\tSell: ", bidExchange[specifiedIndex], " - ", highestBid[specifiedIndex],"\tDifference: {0:.2f} %".format(diff[specifiedIndex]), "\t Cash: ", moneyAmount[specifiedIndex]) + outputToCsv([markets[specifiedIndex], askExchange[specifiedIndex], lowestAsk[specifiedIndex], bidExchange[specifiedIndex], highestBid[specifiedIndex], diff[specifiedIndex], moneyAmount[specifiedIndex]]) + return (markets[specifiedIndex], askExchange[specifiedIndex], lowestAsk[specifiedIndex], bidExchange[specifiedIndex], highestBid[specifiedIndex], diff[specifiedIndex], moneyAmount[specifiedIndex]) + + record_iter = moneyAmount.index(max(moneyAmount)) + return (markets[record_iter], askExchange[record_iter], lowestAsk[record_iter], bidExchange[record_iter], highestBid[record_iter], diff[record_iter], moneyAmount[record_iter]) + + +def outputToCsv(output): + f = open('C:/Users/ashig/Documents/Python Scripts/MSiD/profitOutput.csv', 'a+', newline='') + with f: + writer = csv.writer(f) + writer.writerow(output) + f.close() + + +def learnFromFile(): + markets_average = [0 for i in range(4)] + f = open('C:/Users/ashig/Documents/Python Scripts/MSiD/profitOutput.csv', 'r', newline='') + counter = 0 + with f: + reader = csv.reader(f) + for row in reader: + counter += 1 + if row[-2] != '-': markets_average[counter%4] = row[-2] + counter /= 4 + markets_average = [float(market) / counter for market in markets_average] + return markets_average.index(max(markets_average)) + + +def currencyMonitor(markets): + investedSum = 1000 + learntIndex = learnFromFile() + while True: + output = printDataBittrex(markets) + output += printDataBinance(markets) + output += printDataBitfinex(markets) + output += printDataBitBay(markets) + print(output) + trade = searchProfit(markets, investedSum, False, specifiedIndex = learntIndex) + if trade[-1] > investedSum: investedSum = trade[-1] + print("Money sum = ", trade[-1]) + print("\n\n") + time.sleep(5) + cls() + + +def main(): + currencyMonitor(markets) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/exchange_sim/exchangeSimulator.py b/exchange_sim/exchangeSimulator.py new file mode 100644 index 00000000..fa3e8be0 --- /dev/null +++ b/exchange_sim/exchangeSimulator.py @@ -0,0 +1,158 @@ +from datetime import datetime +from datetime import timezone +from datetime import timedelta +from pprint import pprint +from random import choices +from random import randint +import tensorflow +from sklearn.preprocessing import MinMaxScaler +from keras.models import Sequential +from keras.layers import Dense, Dropout, LSTM +import pandas as pd +import matplotlib.pyplot as plt +import numpy as np +import requests +import time + +currency_pairs = ["btcusd", "ltcusd", "ethusd"] +scaler = MinMaxScaler(feature_range=(0, 1)) + + +def convert_date_to_utc(year, month, day, hour=0, minutes=0, seconds=0): + dt = datetime(year, month, day, hour, minutes, seconds) + timestamp = dt.replace(tzinfo=timezone.utc).timestamp() + return int(timestamp) + + +def getData(currency_pair, start, end, step): + limit = (end - start) // step + 1 + if limit > 1000: + limit = 1000 + bitstamp_data = requests.get("https://www.bitstamp.net/api/v2/ohlc/{0}/".format(currency_pair), + params={'start': start, 'end': end, 'step': step, 'limit': limit}) + if bitstamp_data.status_code == 200: + bitstamp_data_json = bitstamp_data.json() + return True, bitstamp_data_json['data']['ohlc'] + else: + return False, None + + +def prepareData(oldData): + data = pd.json_normalize(oldData) + previous_data_len = len(data) + for i in range(previous_data_len): + data.loc[i, 'timestamp'] = datetime.fromtimestamp(int(data.loc[i, 'timestamp'])) + data.rename(columns={'timestamp':'date'}, inplace=True) + + new_data = pd.DataFrame(index=range(0,len(data)), columns=['Date', 'Close']) + data_simulated = pd.DataFrame(index=range(0,len(data)), columns=['Date', 'Predicted_Close']) + for i in range(len(data)): + new_data['Date'][i] = data['date'][i] + new_data['Close'][i] = float(data['close'][i]) + data_simulated['Date'][i] = data['date'][i] + timedelta(days=len(data)) + data_simulated['Predicted_Close'][i] = 0.0 + + new_data.index = new_data.Date + data_simulated.index = data_simulated.Date + new_data.drop('Date', axis=1, inplace=True) + data_simulated.drop('Date', axis=1, inplace=True) + dataset = new_data.values + dataset_simulated = data_simulated.values + return dataset, data_simulated, new_data + + +def makeModel(dataset, dataset_simulated): + x_train, y_train = [], [] + train_index = int(len(dataset)/5*4) + train = dataset + valid = dataset_simulated + scaled_data = scaler.fit_transform(dataset) + + for i in range(60, len(train)): + x_train.append(scaled_data[i-60:i,0]) + y_train.append(scaled_data[i,0]) + x_train, y_train = np.array(x_train), np.array(y_train) + x_train = np.reshape(x_train, (x_train.shape[0],x_train.shape[1],1)) + + model = Sequential() + model.add(LSTM(units=50, return_sequences=True, input_shape=(x_train.shape[1],1))) + model.add(LSTM(units=50)) + model.add(Dense(1)) + + model.compile(loss='mean_squared_error', optimizer='adam') + model.fit(x_train, y_train, epochs=5, batch_size=1, verbose=2) + return model, train, valid + + +def simulate(model, new_data, valid, data_simulated): + inputs = new_data[len(new_data) - len(valid) - 60:].values + inputs = inputs.reshape(-1,1) + inputs = scaler.transform(inputs) + + X_test = [] + X_test.append(inputs) + X_test = np.array(X_test) + X_test = np.reshape(X_test, (X_test.shape[0],X_test.shape[1],1)) + + simulation_output = [] + + for i in range(len(new_data)): + if i % randint(3,6) == 0: + predicted_price = differenceFunc(X_test) + else: + predicted_price = model.predict(X_test) + for j in range(1, 60): + X_test[0,j-1] = X_test[0,j] + X_test[0,59] = predicted_price + simulation_output.append(predicted_price) + + train = new_data + valid = data_simulated + + converted_output = [] + for i in range(len(simulation_output)): + converted_output.append([simulation_output[i].item()]) + + converted_output = scaler.inverse_transform(converted_output) + valid['Predicted_Close'] = converted_output + return train, valid + + +def differenceFunc(array): + diff = 0.0 + for i in (30, len(array)): + diff += array[0,i]/array[0,i+1] - 1 + diff /= (len(array) - 30) + diff_mults = [10,20,25,30,35,40,45,50,60] + mult_weights = [0.3, 0.2, 0.15, 0.1, 0.1, 0.05, 0.04, 0.04, 0.02] + if diff > 0.003: + return array[0,-1] - array[0,-1]*0.005*choices(diff_mults, mult_weights) + return array[0,-1] + array[0,-1]*0.005*choices(diff_mults, mult_weights) + + +def plotResults(x, y, currency_index): + plt.figure(figsize=(14,10)) + plt.plot(x['Close']) #train + plt.plot(y['Predicted_Close']) #valid + plt.title(currency_pairs[currency_index]) + plt.gcf().autofmt_xdate() + plt.show() + + +def getParameters(): + currency = int(input("Please, enter the number of currency [0 - BTC-USD, 1 - LTC-USD, 2 - ETH-USD]: ")) + date1 = input("Please, enter -date from- in format YYYY-MM-DD: ") + date2 = input("Please, enter -date to- in format YYYY-MM-DD: ") + return currency, convert_date_to_utc(int(date1[0:4]), int(date1[5:7]), int(date1[8:10])), convert_date_to_utc(int(date2[0:4]), int(date2[5:7]), int(date2[8:10])) + +def main(): + currency_index, date_from, date_to = getParameters() + passed, oldData = getData(currency_pairs[currency_index], start=date_from, end=date_to, step=86400) + dataset, data_simulated, new_data = prepareData(oldData) + model, train, valid = makeModel(dataset, data_simulated) + train, valid = simulate(model, new_data, valid, data_simulated) + plotResults(train, valid, currency_index) + + +if __name__ == "__main__": + main() \ No newline at end of file