ChatGPT is a fascinating tool, and once you know how to use prompts correctly it opens endless opportunities for Developers like me.
And I’ve set myself a task to use ChatGPT to write a Crypto Trading Bot for Binance from scratch.
I’ve started with a basic question:
Write a Python script that uses Binance API to trade BTCUSDT.
And here is ChatGPT’s response:
Photo by Dominik Scythe on Unsplash
To write a Python script that uses the Binance API to trade BTCUSDT, you will first need to install the binance
library. You can do this by running the following pip command:
pip install binance
Once the binance
library is installed, you can use the following code to trade BTCUSDT:
from binance.client import Client
# Replace with your Binance API key and secret
api_key = '<your-api-key>'
api_secret = '<your-api-secret>'# Initialize the Binance client
client = Client(api_key, api_secret)# Place a market buy order for 1 BTC of BTCUSDT
order = client.order_market_buy(
symbol='BTCUSDT',
quantity=1
)# Print the order ID
print(order['id'])Pyh
This code will place a market buy order for 1 BTC of BTCUSDT. You can adjust the quantity
parameter to trade a different amount of BTC.
Not bad heh?
But if you worked with Binance trading API you have probably encountered an issue with minimum order size. So let’s ChatGPT take car of it as well.
Question:
Can you validate if the quantity value is greater than min value requested by Binance?
To validate the quantity value is greater than the minimum value required by Binance, you can use the client.get_min_notional()
method. This method returns the minimum notional value allowed for a trade on a specific symbol. You can use this method to check the minimum notional value for BTCUSDT and ensure that the quantity you are trying to trade is greater than or equal to this minimum value.
Here is an example of how you can use the client.get_min_notional()
method to validate the quantity value in your Python script:
from binance.client import Client
# Replace with your Binance API key and secret
api_key = '<your-api-key>'
api_secret = '<your-api-secret>'# Initialize the Binance client
client = Client(api_key, api_secret)
# Get the minimum notional value for BTCUSDT
min_notional = client.get_min_notional(symbol='BTCUSDT')
# Place a market buy order for 1 BTC of BTCUSDT if the quantity is greater than or equal to the minimum notional value
quantity = 1
if quantity >= min_notional:
order = client.order_market_buy(
symbol='BTCUSDT',
quantity=quantity
)
# Print the order ID
print(order['id'])
else:
print('Quantity must be greater than or equal to the minimum notional value of {} BTCUSDT'.format(min_notional))
In this code, we first use the client.get_min_notional()
method to get the minimum notional value for BTCUSDT. We then check if the quantity
variable is greater than or equal to this minimum value, and if it is, we place a market buy order for the specified quantity of BTCUSDT. If the quantity
is less than the minimum notional value, we print an error message.
That’s looks already pretty cool, but I would like this code to be packaged as a function, so I can reuse it.
Question:
Can you make function out of this code and use “symbol”, “quantity” as input variable and return order_id as output variable. ap_key and api_secret are declared globally?
Here is an example of how you can turn the code from the previous answer into a function that takes the symbol
and quantity
as input variables, and uses the global api_key
and api_secret
values:
from binance.client import Client
# Replace with your Binance API key and secret
api_key = '<your-api-key>'
api_secret = '<your-api-secret>'# Initialize the Binance client
client = Client(api_key, api_secret)def buy_order(symbol, quantity):
# Get the minimum notional value for the specified symbol
min_notional = client.get_min_notional(symbol=symbol) # Place a market buy order for the specified quantity of the symbol if the quantity is greater than or equal to the minimum notional value
if quantity >= min_notional:
order = client.order_market_buy(
symbol=symbol,
quantity=quantity
) # Return the order ID
return order['id']
else:
print('Quantity must be greater than or equal to the minimum notional value of {} {}'.format(min_notional, symbol))
return None# Trade 1 BTC of BTCUSDT
order_id = buy_order('BTCUSDT', 1)
print(order_id)
In this code, we first define a function called buy_order()
that takes the symbol
and quantity
as input arguments. Inside the function, we use the client.get_min_notional()
method to get the minimum notional value for the specified symbol
, and then check if the quantity
is greater than or equal to this minimum value. If it is, we place a market buy order for the specified quantity
of the symbol
. If the quantity
is less than the minimum notional value, we print an error message.
You can then call the buy_order()
function to trade a specific quantity of BTCUSDT or any other symbol that is supported by the Binance API.
Ok, that’s looks pretty decent to me. The script will execute a Market Buy order on Binance and gives order ID as an output variable. But I’d like to check the status of my order as well.
Question:
Add a function that checks status of the purchase order.
To add a function that checks the status of a purchase order, you can use the client.get_order()
method from the binance
library. This method takes the symbol
and orderId
as input arguments, and returns the details of the order with the specified orderId
for the specified symbol
.
Here is an example of how you can add a function called check_order_status()
that uses the client.get_order()
method to check the status of a purchase order:
def check_order_status(symbol, order_id):
# Get the order details for the specified symbol and order ID
order = client.get_order(
symbol=symbol,
orderId=order_id
)
# Print the order status
print('Order status: {}'.format(order['status']))# Trade 1 BTC of BTCUSDT
order_id = buy_order('BTCUSDT', 1)# Check the status of the order
check_order_status('BTCUSDT', order_id)
In this code, we have added a function called check_order_status()
that takes the symbol
and order_id
as input arguments. Inside the function, we use the client.get_order()
method to get the details of the order with the specified order_id
for the specified symbol
. We then print the status
field from the order
dictionary, which contains the status of the order.
You can then call the check_order_status()
function to check the status of a purchase order that was placed using the buy_order()
function.
That’s looks sleek to me. Now I need to a function that can place a market sell order as well. And my next prompt will be a bit more complex. Let’s see how OpenGPT can handle that…
Question:
Write a function that places a sell order as well, validate the selling quantity with required chunk size from Binance, reduce the selling quantity to the required chunk size if required.
To write a function that places a sell order, you can use the client.order_market_sell()
method from the binance
library. This method takes the symbol
, quantity
, and other parameters as input arguments, and places a market sell order for the specified quantity
of the symbol
.
To validate the selling quantity and reduce it to the required chunk size if necessary, you can use the client.get_symbol_info()
method. This method returns information about a symbol, including the stepSize
field, which contains the minimum quantity that can be traded for the symbol. You can use this stepSize
value to calculate the required chunk size and adjust the quantity
of the sell order if necessary.
Here is an example of how you can write a function called sell_order()
that places a market sell order for a specified quantity
of a symbol
, and validates and adjusts the quantity
if necessary:
def sell_order(symbol, quantity):
# Get the symbol information
symbol_info = client.get_symbol_info(symbol=symbol)
# Calculate the required chunk size
chunk_size = symbol_info['filters'][2]['stepSize'] # Adjust the quantity to the required chunk size if necessary
if quantity % chunk_size != 0:
quantity = int(quantity / chunk_size) * chunk_size # Place a market sell order for the specified quantity of the symbol
order = client.order_market_sell(
symbol=symbol,
quantity=quantity
) # Return the order ID
return order['id']# Sell 1 BTC of BTCUSDT
order_id = sell_order('BTCUSDT', 1)
print(order_id)
In this code, we have defined a function called sell_order()
that takes the symbol
and quantity
as input arguments. Inside the function, we use the client.get_symbol_info()
method to get the symbol information, and then calculate the required chunk size using the stepSize
field. If the quantity
is not a multiple of the chunk size, we adjust the quantity
to the required chunk size. We then use the client.order_market_sell()
method to place a market sell order for the adjusted quantity
of the symbol
, and return the order ID.
You can then call the sell_order()
function to place a market sell order for a specified quantity
of a symbol
, and the function will validate and adjust the quantity
if necessary before placing the order.
Honestly I’m super impressed! I couldn’t write it better. Nice work OpenGPT!
So we’ve got 3 functions so far:
These are the engine functions for the trading bot, but to make it fully autonomous, we need some trading indicators which can be used as trigger for buying and selling activities.
Question:
Let’s add a function that reads candles data from Binance, make period, interval as input. and output is a panda dataframe with close,open,high, low and volume values in numerical format.
To read candles data from Binance and return it as a Pandas DataFrame, you will need to install the pandas
library. You can do this by running the following pip command:
pip install pandas
Once the pandas
library is installed, you can use the following code to read candles data from Binance and return it as a Pandas DataFrame:
from binance.client import Client
import pandas as pd
# Replace with your Binance API key and secret
api_key = '<your-api-key>'
api_secret = '<your-api-secret>'# Initialize the Binance client
client = Client(api_key, api_secret)def get_candles(symbol, period, interval):
# Get the candles data for the specified symbol, period, and interval
candles = client.get_klines(
symbol=symbol,
interval=interval,
limit=period
) # Create a Pandas DataFrame from the candles data
df = pd.DataFrame(candles, columns=[
'open_time',
'open',
'high',
'low',
'close',
'volume',
'close_time',
'quote_asset_volume',
'number_of_trades',
'taker_buy_base_asset_volume',
'taker_buy_quote_asset_volume',
'ignore'
]) # Convert the column values to numerical values
df = df.apply(pd.to_numeric) # Return the Pandas DataFrame
return df# Get the candles data for BTCUSDT for the past 1 hour with a 1 minute interval
df = get_candles('BTCUSDT', 60, '1m')
print(df)
In this code, we have defined a function called get_candles()
that takes the symbol
, period
, and interval
as input arguments. Inside the function, we use the client.get_klines()
method to get the candles data for the specified symbol
, period
, and interval
. We then create a Pandas DataFrame from the candles data, and convert the column values to numerical values using the pd.to_numeric()
method. Finally, we return the Pandas DataFrame.
You can then call the get_candles()
function to get the candles data for a specific symbol
, period
, and interval
, and the function will return the candles data as a Pandas DataFrame. You can use the returned DataFrame to perform various operations on the candles data, such as calculating moving averages, plotting the data, and more.
That worked nicely too, well done ChatGPT!
Let’s get RSI indicator as a function, shall we?
Question:
Add a function that calculates RSI based on the pandas dataframe, make RSI length as input variable and return RSI results as a dataframe
To calculate the relative strength index (RSI) based on a Pandas DataFrame, you can use the talib.RSI()
function from the TA-Lib
library. This library provides a wide range of technical analysis indicators, including the RSI.
To install the TA-Lib
library, you can run the following pip command:
pip install TA-Lib
Once the TA-Lib
library is installed, you can use the following code to calculate the RSI for a Pandas DataFrame and return the results as a new DataFrame:
import talib
def get_rsi(df, length):
# Calculate the RSI
rsi = talib.RSI(df['close'], timeperiod=length) # Create a Pandas DataFrame with the RSI values
rsi_df = pd.DataFrame(rsi, columns=['RSI']) # Return the RSI DataFrame
return rsi_df# Get the candles data for BTCUSDT for the past 1 hour with a 1 minute interval
df = get_candles('BTCUSDT', 60, '1m')# Calculate the RSI for the candles data with a length of 14
rsi = get_rsi(df, 14)
print(rsi)
Let’s combine all functions together, so that we have a nice view of what ChatGPT has created
from binance.client import Client
import pandas as pd
import talib
# Replace with your Binance API key and secret
api_key = '<your-api-key>'
api_secret = '<your-api-secret>'# Initialize the Binance client
client = Client(api_key, api_secret)def buy_order(symbol, quantity):
# Get the minimum notional value for the specified symbol
min_notional = client.get_min_notional(symbol=symbol) # Place a market buy order for the specified quantity of the symbol if the quantity is greater than or equal to the minimum notional value
if quantity >= min_notional:
order = client.order_market_buy(
symbol=symbol,
quantity=quantity
) # Return the order ID
return order['id']
else:
print('Quantity must be greater than or equal to the minimum notional value of {} {}'.format(min_notional, symbol))
return Nonedef sell_order(symbol, quantity):
# Get the symbol information
symbol_info = client.get_symbol_info(symbol=symbol) # Calculate the required chunk size
chunk_size = symbol_info['filters'][2]['stepSize'] # Adjust the quantity to the required chunk size if necessary
if quantity % chunk_size != 0:
quantity = int(quantity / chunk_size) * chunk_size # Place a market sell order for the specified quantity of the symbol
order = client.order_market_sell(
symbol=symbol,
quantity=quantity
) # Return the order ID
return order['id']def check_order_status(symbol, order_id):
# Get the order details for the specified symbol and order ID
order = client.get_order(
symbol=symbol,
orderId=order_id
) # Print the order status
print('Order status: {}'.format(order['status']))def get_candles(symbol, period, interval):
# Get the candles data for the specified symbol, period, and interval
candles = client.get_klines(
symbol=symbol,
interval=interval,
limit=period
) # Create a Pandas DataFrame from the candles data
df = pd.DataFrame(candles, columns=[
'open_time',
'open',
'high',
'low',
'close',
'volume',
'close_time',
'quote_asset_volume',
'number_of_trades',
'taker_buy_base_asset_volume',
'taker_buy_quote_asset_volume',
'ignore'
]) # Convert the column values to numerical values
df = df.apply(pd.to_numeric) # Return the Pandas DataFrame
return dfdef get_rsi(df, length):
# Calculate the RSI
rsi = talib.RSI(df['close'], timeperiod=length) # Create a Pandas DataFrame with the RSI values
rsi_df = pd.DataFrame(rsi, columns=['RSI']) # Return the RSI DataFrame
return rsi_df
So what do we have so far?
Now we need to tie everything together and let’s see how ChatGPT can handle that.
Question:
write a script that executes a buy_order if RSI raises over 60, store purchase price in a variable and calculate profit against it, and executes sell order if profit is greater than 5% or loss is greater than 2%
To write a script that executes a buy order if the RSI value is greater than 60, and then stores the purchase price in a variable and calculates the profit, you can use the buy_order()
function that we defined earlier, along with the get_candles()
and get_rsi()
functions. You can then use a simple while
loop to continuously check the RSI value and execute a buy order if the RSI is greater than 60.
Here is an example of how you can write a script that executes a buy order when the RSI is greater than 60, calculates the profit, and then executes a sell order if the profit is greater than 5% or the loss is greater than 2%:
# Replace with your symbol, period, and interval
symbol = 'BTCUSDT'
period = 60
interval = '1m'
# Get the candles data
df = get_candles(symbol, period, interval)# Calculate the RSI
rsi_df = get_rsi(df, 14)# Initialize the purchase price
purchase_price = 0# Continuously check the RSI value and execute a buy order if the RSI is greater than 60
while True:
# Get the latest RSI value
rsi = rsi_df['RSI'].iloc[-1] # Check if the RSI is greater than 60
if rsi > 60 and purchase_price == 0:
# Place a buy order
order_id = buy_order(symbol, 1) # Get the latest candles data
df = get_candles(symbol, period, interval) # Get the latest close price
close = df['close'].iloc[-1] # Set the purchase price
purchase_price = close # Print the purchase price
print('Purchase price: {}'.format(purchase_price))
else:
# Check if the purchase price is set
if purchase_price > 0:
# Get the latest candles data
df = get_candles(symbol, period, interval) # Get the latest close price
close = df['close'].iloc[-1] # Calculate the profit
profit = (close - purchase_price) / purchase_price * 100 # Check if the profit is greater than 5% or the loss is greater than 2%
if profit > 5 or profit < -2:
# Place a sell order
order_id = sell_order(symbol, 1) # Reset the purchase price
purchase_price = 0 # Print the profit
print('Profit: {}%'.format(profit))
In this code, we have added the code to calculate the profit and execute a sell order if the profit is greater than 5% or the loss is greater than 2%. Inside the while
loop, we check if the RSI value is greater than 60, and if it is, we execute a buy order and set the purchase_price
variable to the current close price. If the RSI value is not greater than 60, we check if the purchase_price
variable is set, and if it