├── README.md ├── pybot_bollinger_binance.py ├── pybot_macd_binance.py └── pybot_sma_binance.py /README.md: -------------------------------------------------------------------------------- 1 | # PythonBinanceTradingBots 2 | In this tutorial, Yogesh, the course author, explains the basics of the python-binance trading API that allows you to trade cryptocurrencies programmatically in your own Python scripts. 3 | Here's the full course: 4 | https://academy.finxter.com/university/binance-trading-api-creating-your-first-simple-crypto-trading-bot/ 5 | -------------------------------------------------------------------------------- /pybot_bollinger_binance.py: -------------------------------------------------------------------------------- 1 | # Author: Yogesh K for finxter.com 2 | # python script: trading with Bollinger bands for Binance 3 | 4 | 5 | import os 6 | from binance.client import Client 7 | import pprint 8 | import pandas as pd # needs pip install 9 | import numpy as np 10 | import matplotlib.pyplot as plt # needs pip install 11 | 12 | def get_data_frame(): 13 | # valid intervals - 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M 14 | # request historical candle (or klines) data using timestamp from above, interval either every min, hr, day or month 15 | # starttime = '30 minutes ago UTC' for last 30 mins time 16 | # e.g. client.get_historical_klines(symbol='ETHUSDTUSDT', '1m', starttime) 17 | # starttime = '1 Dec, 2017', '1 Jan, 2018' for last month of 2017 18 | # e.g. client.get_historical_klines(symbol='BTCUSDT', '1h', "1 Dec, 2017", "1 Jan, 2018") 19 | starttime = '1 day ago UTC' # to start for 1 day ago 20 | interval = '5m' 21 | bars = client.get_historical_klines(symbol, interval, starttime) 22 | pprint.pprint(bars) 23 | 24 | for line in bars: # Keep only first 5 columns, "date" "open" "high" "low" "close" 25 | del line[5:] 26 | 27 | df = pd.DataFrame(bars, columns=['date', 'open', 'high', 'low', 'close']) # 2 dimensional tabular data 28 | return df 29 | 30 | def plot_graph(df): 31 | df=df.astype(float) 32 | df[['close', 'sma','upper', 'lower']].plot() 33 | plt.xlabel('Date',fontsize=18) 34 | plt.ylabel('Close price',fontsize=18) 35 | x_axis = df.index 36 | plt.fill_between(x_axis, df['lower'], df['upper'], color='grey',alpha=0.30) 37 | 38 | plt.scatter(df.index,df['buy'], color='purple',label='Buy', marker='^', alpha = 1) # purple = buy 39 | plt.scatter(df.index,df['sell'], color='red',label='Sell', marker='v', alpha = 1) # red = sell 40 | 41 | 42 | plt.show() 43 | 44 | 45 | def buy_or_sell(df): 46 | 47 | buy_list = pd.to_numeric(df['buy'], downcast='float') 48 | sell_list = pd.to_numeric(df['sell'], downcast='float') 49 | 50 | for i in range(len(buy_list)): 51 | # get current price of the symbol 52 | current_price = client.get_symbol_ticker(symbol =symbol) 53 | if float(current_price['price']) >= sell_list[i]: # sell order 54 | print("sell sell sell...") 55 | sell_order = client.order_market_sell(symbol=symbol, quantity=0.01) 56 | print(sell_order) 57 | elif float(current_price['price']) <= buy_list[i]: # buy order 58 | print("buy buy buy...") 59 | buy_order = client.order_market_buy(symbol=symbol, quantity=0.001) 60 | print(buy_order) 61 | else: 62 | print("...do nothing...") 63 | 64 | 65 | 66 | 67 | def bollinger_trade_logic(): 68 | symbol_df = get_data_frame() 69 | period = 20 70 | # small time Moving average. calculate 20 moving average using Pandas over close price 71 | symbol_df['sma'] = symbol_df['close'].rolling(period).mean() 72 | # Get standard deviation 73 | symbol_df['std'] = symbol_df['close'].rolling(period).std() 74 | 75 | # Calculate Upper Bollinger band 76 | symbol_df['upper'] = symbol_df['sma'] + (2 * symbol_df['std']) 77 | # Calculate Lower Bollinger band 78 | symbol_df['lower'] = symbol_df['sma'] - (2 * symbol_df['std']) 79 | 80 | # To print in human readable date and time (from timestamp) 81 | symbol_df.set_index('date', inplace=True) 82 | symbol_df.index = pd.to_datetime(symbol_df.index, unit='ms') # index set to first column = date_and_time 83 | 84 | # prepare buy and sell signals. The lists prepared are still panda dataframes with float nos 85 | close_list = pd.to_numeric(symbol_df['close'], downcast='float') 86 | upper_list = pd.to_numeric(symbol_df['upper'], downcast='float') 87 | lower_list = pd.to_numeric(symbol_df['lower'], downcast='float') 88 | 89 | symbol_df['buy'] = np.where(close_list < lower_list, symbol_df['close'], np.NaN ) 90 | symbol_df['sell'] = np.where(close_list > upper_list, symbol_df['close'], np.NaN ) 91 | 92 | with open('output.txt', 'w') as f: 93 | f.write( 94 | symbol_df.to_string() 95 | ) 96 | 97 | # plot_graph(symbol_df) 98 | 99 | buy_or_sell(symbol_df) 100 | 101 | 102 | 103 | 104 | 105 | 106 | def main(): 107 | bollinger_trade_logic() 108 | 109 | 110 | if __name__ == "__main__": 111 | 112 | api_key = os.environ.get('BINANCE_TESTNET_KEY') # passkey (saved in bashrc for linux) 113 | api_secret = os.environ.get('BINANCE_TESTNET_PASSWORD') # secret (saved in bashrc for linux) 114 | 115 | client = Client(api_key, api_secret, testnet=True) 116 | print("Using Binance TestNet Server") 117 | 118 | pprint.pprint(client.get_account()) 119 | 120 | symbol = 'BTCUSDT' # Change symbol here e.g. BTCUSDT, BNBBTC, ETHUSDT, NEOBTC 121 | main() 122 | -------------------------------------------------------------------------------- /pybot_macd_binance.py: -------------------------------------------------------------------------------- 1 | # Author: Yogesh K for finxter academy 2 | # MACD - Moving average convergence divergence 3 | import os 4 | from binance.client import Client 5 | import pprint 6 | import pandas as pd # needs pip install 7 | import numpy as np 8 | import matplotlib.pyplot as plt # needs pip install 9 | 10 | 11 | def get_data_frame(): 12 | # valid intervals - 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M 13 | # request historical candle (or klines) data using timestamp from above, interval either every min, hr, day or month 14 | # starttime = '30 minutes ago UTC' for last 30 mins time 15 | # e.g. client.get_historical_klines(symbol='ETHUSDTUSDT', '1m', starttime) 16 | # starttime = '1 Dec, 2017', '1 Jan, 2018' for last month of 2017 17 | # e.g. client.get_historical_klines(symbol='BTCUSDT', '1h', "1 Dec, 2017", "1 Jan, 2018") 18 | starttime = '1 day ago UTC' 19 | interval = '1m' 20 | bars = client.get_historical_klines(symbol, interval, starttime) 21 | 22 | for line in bars: # Keep only first 5 columns, "date" "open" "high" "low" "close" 23 | del line[5:] 24 | 25 | df = pd.DataFrame(bars, columns=['date', 'open', 'high', 'low', 'close']) # 2 dimensional tabular data 26 | return df 27 | 28 | def plot_graph(df): 29 | 30 | df=df.astype(float) 31 | df[['close', 'MACD','signal']].plot() 32 | plt.xlabel('Date',fontsize=18) 33 | plt.ylabel('Close price',fontsize=18) 34 | x_axis = df.index 35 | 36 | plt.scatter(df.index,df['Buy'], color='purple',label='Buy', marker='^', alpha = 1) # purple = buy 37 | plt.scatter(df.index,df['Sell'], color='red',label='Sell', marker='v', alpha = 1) # red = sell 38 | 39 | plt.show() 40 | 41 | 42 | 43 | def buy_or_sell(df, buy_sell_list): 44 | for index, value in enumerate(buy_sell_list): 45 | current_price = client.get_symbol_ticker(symbol =symbol) 46 | print(current_price['price']) # Output is in json format, only price needs to be accessed 47 | if value == 1.0 : # signal to buy (either compare with current price to buy/sell or use limit order with close price) 48 | if current_price['price'] < df['Buy'][index]: 49 | print("buy buy buy....") 50 | buy_order = client.order_market_buy(symbol=symbol, quantity=1) 51 | print(buy_order) 52 | 53 | elif value == -1.0: # signal to sell 54 | if current_price['price'] > df['Sell'][index]: 55 | print("sell sell sell....") 56 | sell_order = client.order_market_sell(symbol=symbol, quantity=1) 57 | print(sell_order) 58 | else: 59 | print("nothing to do...") 60 | 61 | 62 | 63 | def macd_trade_logic(): 64 | symbol_df = get_data_frame() 65 | 66 | # calculate short and long EMA mostly using close values 67 | shortEMA = symbol_df['close'].ewm(span=12, adjust=False).mean() 68 | longEMA = symbol_df['close'].ewm(span=26, adjust=False).mean() 69 | 70 | # Calculate MACD and signal line 71 | MACD = shortEMA - longEMA 72 | signal = MACD.ewm(span=9, adjust=False).mean() 73 | 74 | symbol_df['MACD'] = MACD 75 | symbol_df['signal'] = signal 76 | 77 | # To print in human readable date and time (from timestamp) 78 | symbol_df.set_index('date', inplace=True) 79 | symbol_df.index = pd.to_datetime(symbol_df.index, unit='ms') # index set to first column = date_and_time 80 | 81 | symbol_df['Trigger'] = np.where(symbol_df['MACD'] > symbol_df['signal'], 1, 0) 82 | symbol_df['Position'] = symbol_df['Trigger'].diff() 83 | 84 | # Add buy and sell columns 85 | symbol_df['Buy'] = np.where(symbol_df['Position'] == 1,symbol_df['close'], np.NaN ) 86 | symbol_df['Sell'] = np.where(symbol_df['Position'] == -1,symbol_df['close'], np.NaN ) 87 | 88 | 89 | with open('output.txt', 'w') as f: 90 | f.write( 91 | symbol_df.to_string() 92 | ) 93 | 94 | 95 | # plot_graph(symbol_df) 96 | 97 | # get the column=Position as a list of items. 98 | buy_sell_list = symbol_df['Position'].tolist() 99 | 100 | buy_or_sell(symbol_df, buy_sell_list) 101 | 102 | 103 | 104 | 105 | def main(): 106 | macd_trade_logic() 107 | 108 | 109 | 110 | 111 | 112 | if __name__ == "__main__": 113 | 114 | api_key = os.environ.get('BINANCE_TESTNET_KEY') # passkey (saved in bashrc for linux) 115 | api_secret = os.environ.get('BINANCE_TESTNET_PASSWORD') # secret (saved in bashrc for linux) 116 | 117 | client = Client(api_key, api_secret, testnet=True) 118 | print("Using Binance TestNet Server") 119 | 120 | pprint.pprint(client.get_account()) 121 | 122 | symbol = 'BNBUSDT' # Change symbol here e.g. BTCUSDT, BNBBTC, ETHUSDT, NEOBTC 123 | main() 124 | -------------------------------------------------------------------------------- /pybot_sma_binance.py: -------------------------------------------------------------------------------- 1 | # Author : Yogesh K for finxter.com 2 | # SMA(simple moving average) using python-binance 3 | 4 | 5 | import os 6 | from binance.client import Client 7 | from binance import ThreadedWebsocketManager # This import can be removed. not needed 8 | import pprint 9 | import datetime # This import can be removed, not needed 10 | import pandas as pd # needs pip install 11 | import numpy as np 12 | import matplotlib.pyplot as plt # needs pip install 13 | 14 | 15 | def get_hourly_dataframe(): # we want hourly data and for past 1 week. 16 | # valid intervals - 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M 17 | # request historical candle (or klines) data using timestamp from above, interval either every min, hr, day or month 18 | # starttime = '30 minutes ago UTC' for last 30 mins time 19 | # e.g. client.get_historical_klines(symbol='ETHUSDTUSDT', '1m', starttime) 20 | # starttime = '1 Dec, 2017', '1 Jan, 2018' for last month of 2017 21 | # e.g. client.get_historical_klines(symbol='BTCUSDT', '1h', "1 Dec, 2017", "1 Jan, 2018") 22 | 23 | starttime = '1 week ago UTC' # to start for 1 week ago 24 | interval = '1h' 25 | bars = client.get_historical_klines(symbol, interval, starttime) 26 | 27 | for line in bars: # Keep only first 5 columns, "date" "open" "high" "low" "close" 28 | del line[5:] 29 | 30 | df = pd.DataFrame(bars, columns=['date', 'open', 'high', 'low', 'close']) # 2 dimensional tabular data 31 | return df 32 | 33 | 34 | def plot_graph(df): 35 | df=df.astype(float) 36 | df[['close', '5sma','15sma']].plot() 37 | plt.xlabel('Date',fontsize=18) 38 | plt.ylabel('Close price',fontsize=18) 39 | 40 | plt.scatter(df.index,df['Buy'], color='purple',label='Buy', marker='^', alpha = 1) # purple = buy 41 | plt.scatter(df.index,df['Sell'], color='red',label='Sell', marker='v', alpha = 1) # red = sell 42 | 43 | plt.show() 44 | 45 | 46 | def buy_or_sell(buy_sell_list, df): 47 | for index, value in enumerate(buy_sell_list): 48 | current_price = client.get_symbol_ticker(symbol =symbol) 49 | print(current_price['price']) # Output is in json format, only price needs to be accessed 50 | if value == 1.0 : # signal to buy (either compare with current price to buy/sell or use limit order with close price) 51 | if current_price['price'] < df['Buy'][index]: 52 | print("buy buy buy....") 53 | buy_order = client.order_market_buy(symbol=symbol, quantity=2) 54 | print(buy_order) 55 | elif value == -1.0: # signal to sell 56 | if current_price['price'] > df['Sell'][index]: 57 | print("sell sell sell....") 58 | sell_order = client.order_market_sell(symbol=symbol, quantity=10) 59 | print(sell_order) 60 | else: 61 | print("nothing to do...") 62 | 63 | 64 | 65 | def sma_trade_logic(): 66 | symbol_df = get_hourly_dataframe() 67 | 68 | # small time Moving average. calculate 5 moving average using Pandas over close price 69 | symbol_df['5sma'] = symbol_df['close'].rolling(5).mean() 70 | # long time moving average. calculate 15 moving average using Pandas 71 | symbol_df['15sma'] = symbol_df['close'].rolling(15).mean() 72 | 73 | # To print in human readable date and time (from timestamp) 74 | symbol_df.set_index('date', inplace=True) 75 | symbol_df.index = pd.to_datetime(symbol_df.index, unit='ms') 76 | 77 | # Calculate signal column 78 | symbol_df['Signal'] = np.where(symbol_df['5sma'] > symbol_df['15sma'], 1, 0) 79 | # Calculate position column with diff 80 | symbol_df['Position'] = symbol_df['Signal'].diff() 81 | 82 | # Add buy and sell columns 83 | symbol_df['Buy'] = np.where(symbol_df['Position'] == 1,symbol_df['close'], np.NaN ) 84 | symbol_df['Sell'] = np.where(symbol_df['Position'] == -1,symbol_df['close'], np.NaN ) 85 | 86 | 87 | with open('output.txt', 'w') as f: 88 | f.write( 89 | symbol_df.to_string() 90 | ) 91 | 92 | #plot_graph(symbol_df) 93 | 94 | # get the column=Position as a list of items. 95 | buy_sell_list = symbol_df['Position'].tolist() 96 | 97 | buy_or_sell(buy_sell_list, symbol_df) 98 | 99 | 100 | 101 | 102 | def main(): 103 | sma_trade_logic() 104 | 105 | 106 | 107 | 108 | 109 | if __name__ == "__main__": 110 | 111 | api_key = os.environ.get('BINANCE_TESTNET_KEY') # passkey (saved in bashrc for linux) 112 | api_secret = os.environ.get('BINANCE_TESTNET_PASSWORD') # secret (saved in bashrc for linux) 113 | 114 | client = Client(api_key, api_secret, testnet=True) 115 | print("Using Binance TestNet Server") 116 | 117 | pprint.pprint(client.get_account()) 118 | 119 | symbol = 'BNBUSDT' # Change symbol here e.g. BTCUSDT, BNBBTC, ETHUSDT, NEOBTC 120 | main() 121 | --------------------------------------------------------------------------------