@

How to code a Stop Loss and Take Profit for your Cryptocurrency Trading Bot using Python and the Binance API

Sat Jul 15 2023

Build your own crypto trading bot in Python

Algorithmic cryptocurrency trading has gained substantial popularity among traders as it automates the trading process, reduces human errors, and potentially increases profits. An integral part of this system is the trading bot---a piece of software designed to analyze and execute trades according to predefined rules. In this article, we’re going to show you how you can build your first algorithmic cryptocurrency trading bot using Python, and demonstrate how to use it to connect to Binance, and place orders based on pre-determined logic. By the end of the article you should have a fully-functional bot that can operate with stop-loss and take-profit logic in mind to enter and exit the market at will.

Algorithmic cryptocurrency trading is becoming more and more popular, with new platforms such as Aesir out there to help retail investors maximize their gains under any market conditions.

This article is a continuation of the previous article where we explored how to build a cryptocurrency trading bot in python from scratchusing the Binance API. In This article we’re going to extend the functionality of the original bot we built. We recommend starting with the previous article if you want to follow the bot-building process from scratch.

Before we start, you’ll need a Binance account so why not use our referral link to create a new one and get 10% off your trading fees.

The codebase for our python crypto trading bot

Let’s start by briefly explaining what our bot currently does, and we’ll be extending its functionality by adding a Stop Loss and Take Profit feature. Bear in mind that this is a minimal example where all of the code is displayed in a single file to easily get an overview of what’s going on. As your bot grows in functionality, you’ll want to adopt a more modular approach with single purpose functions.

In the code below, we’re authenticating with the Binance API, and then fetching some historical data. We then use pandas to put the data inside a Pandas dataframe so we can easily access it at any time. The pandas dataframe makes it easy to perform certain operations on this historical dataset and it’s well suited to work with exactly this kind of data.

Our trading bot then calculates the mean price of the historical data and compares this against the current price. If the current price is greater by 1%, we buy, otherwise, we sell.

from binance.client import Client
import pandas as pd
import time

API_KEY = 'YOUR_API_KEY'
API_SECRET = 'YOUR_API_SECRET'

client = Client(API_KEY, API_SECRET)

def main():
    # Fetch historical candlestick data
    candles = client.get_klines(symbol='BTCUSDT', interval=Client.KLINE_INTERVAL_1MINUTE, limit=500)

    # Prepare a pandas dataframe with ticker data
    df = pd.DataFrame(candles, columns=['time', 'open', 'high', 'low', 'close', 'volume', 'close_time', 'quote_asset_volume', 'num_trades', 'taker_buy_base_asset_volume', 'taker_buy_quote_asset_volume', 'ignore'])

    # Convert the time and prices to float
    df['time'] = pd.to_datetime(df['time'], unit='ms')
    df['open'] = pd.to_numeric(df['open'])
    df['close'] = pd.to_numeric(df['close'])

    df.set_index('time', inplace=True, drop=False)

    # Calculate the mean price and the buy/sell thresholds
    mean_price = df['close'].mean()
    buy_threshold = mean_price * 0.99
    sell_threshold = mean_price * 1.01

    # Fetch the current price of a trading pair
    current_price = float(client.get_symbol_ticker(symbol='BTCUSDT')['price'])

    # Place a buy order if the price drops below the buy threshold, and a sell order if it rises above the sell threshold
    if current_price <= buy_threshold:
        order = client.order_market_buy(symbol='BTCUSDT', quantity=0.001)
        print(order)
    elif current_price >= sell_threshold:
        order = client.order_market_sell(symbol='BTCUSDT', quantity=0.001)
        print(order)

# execute the main function in a loop that triggers every 60 seconds
if __name__ == "__main__":
    while True:
        main()
        time.sleep(60)  # waits 60 seconds


Improving our Python crypto trading bot

We don’t want to complicate this too much for the sake of the example, so we’re going to work with the get_my_trades function provided by the python-binance API.This function will return a list of trades for a symbol of our choice.

The first thing we want to do is save our current order to a local file from which we can read it in future iterations. For now a simple json file should be in order and it will serve us well.

# Save the order response to a JSON file
filename = 'order_response.json'
with open(filename, 'w') as file:
    json.dump(order, file)



The next thing we want to do, at the top of the file, so the start of our loop is check whether this file exists,and if it does we want to store the last order price as a variable. Doing this will enable us to check for a Stop Loss and Take Profit so that we can have a sustainable exit strategy built in.

import json
import os

filename = 'order_response.json'
last_order_price = None

if os.path.isfile(filename):
    with open(filename, 'r') as file:
        orders = json.load(file)
        if orders:
            last_order = orders[-1]  # Assuming the last order is at the end of the list
            last_order_price = float(last_order['price'])
            print(f"Last order price loaded from file: {last_order_price}")
else:
    print(f"The file '{filename}' does not exist.")




The next step is building the stop loss and take profit logic and ensuring that these only trigger when they’re supposed to. Because our cryptocurrency trading bot and both buy and sell assets based on mean reversion, we don’t want to re-buy assets that were already bought. If we already hold Bitcoin in our portfolio, we don’t out our trading bot to place another other on Bitcoin. We want to close this order before placing another trade. To do that, we’re going to check that our local order exists before attempting to check for stop loss, and place an order if it does not exist.


        if last_order_price is not None:
            # Perform stop loss and take profit calculations with last_order_price
            take_profit_price = last_order_price * 1.02  # Example: 2% take profit
            stop_loss_price = last_order_price * 0.98  # Example: 2% stop loss

            if current_price >= take_profit_price:
                # Perform take profit action (e.g., sell)
                # Implement your take profit logic here
                print(f"Take profit triggered at price: {current_price}")

                # Remove the order from the file after selling
                orders.pop()
                with open(filename, 'w') as file:
                    json.dump(orders, file)

            if current_price <= stop_loss_price:
                # Perform stop loss action (e.g., sell)
                # Implement your stop loss logic here
                print(f"Stop loss triggered at price: {current_price}")

                # Remove the order from the file after selling
                orders.pop()
                with open(filename, 'w') as file:
                    json.dump(orders, file)

Adding the stop loss logic to our Python crypto trading bot

Finally we need to put the entire code together. We’ve put the entire logic of the trading bot in a single monolithic code block. Note that in reality you’ll want to break the functionality of the code in smaller pieces so that you can easily expand on it.

Putting it all together we’ll have something like this:

import pandas as pd
import time
import json
import os
from binance import Client

API_KEY = 'YOUR_API_KEY'
API_SECRET = 'YOUR_API_SECRET'

client = Client(API_KEY, API_SECRET)
filename = 'order_response.json'

def main():
    last_order_price = None  # Initialize last_order_price

    # Fetch historical candlestick data
    candles = client.get_klines(symbol='BTCUSDT', interval=Client.KLINE_INTERVAL_1MINUTE, limit=500)

    # Prepare a pandas dataframe
    df = pd.DataFrame(candles, columns=['time', 'open', 'high', 'low', 'close', 'volume', 'close_time', 'quote_asset_volume', 'num_trades', 'taker_buy_base_asset_volume', 'taker_buy_quote_asset_volume', 'ignore'])

    # Convert the time and prices to float
    df['time'] = pd.to_datetime(df['time'], unit='ms')
    df['open'] = pd.to_numeric(df['open'])
    df['close'] = pd.to_numeric(df['close'])

    df.set_index('time', inplace=True, drop=False)

    # Calculate the mean price and the buy/sell thresholds
    mean_price = df['close'].mean()
    buy_threshold = mean_price * 0.99
    sell_threshold = mean_price * 1.01

    # Fetch the current price
    current_price = float(client.get_symbol_ticker(symbol='BTCUSDT')['price'])

    # Check if the order response file exists
    if os.path.isfile(filename):
        with open(filename, 'r') as file:
            orders = json.load(file)
            if orders:
                last_order = orders[-1]  # Assuming the last order is at the end of the list
                last_order_price = float(last_order['price'])
                print(f"Last order price loaded from file: {last_order_price}")
                # Process the last order price as needed

    if not orders:
        # Only buy when the JSON file is empty
        if current_price <= buy_threshold:
            order = client.order_market_buy(symbol='BTCUSDT', quantity=0.001)
            print(order)

            # Update last_order_price with the current order price
            last_order_price = float(order['price'])

            # Store the order response to the file
            with open(filename, 'w') as file:
                json.dump([order], file)

    else:
        # Use last_order_price for stop loss and take profit calculations
        if last_order_price is not None:
            # Perform stop loss and take profit calculations with last_order_price
            take_profit_price = last_order_price * 1.02  # Example: 2% take profit
            stop_loss_price = last_order_price * 0.98  # Example: 2% stop loss

            if current_price >= take_profit_price:
                # Perform take profit action (e.g., sell)
                # Implement your take profit logic here
                print(f"Take profit triggered at price: {current_price}")

                # Remove the order from the file after selling
                orders.pop()
                with open(filename, 'w') as file:
                    json.dump(orders, file)

            if current_price <= stop_loss_price:
                # Perform stop loss action (e.g., sell)
                # Implement your stop loss logic here
                print(f"Stop loss triggered at price: {current_price}")

                # Remove the order from the file after selling
                orders.pop()
                with open(filename, 'w') as file:
                    json.dump(orders, file)

if __name__ == "__main__":
    while True:
        main()
        time.sleep(60)  # waits 60 seconds




That’s about it, you now have a functional Stop Loss and Take Profit mechanism for your python trading bot.

Limitations of Custom Coded Crypto Trading Bots

Naturally, the example above is quite minimal and, while it’s functionally sound, it’s missing many features that could help you gain an additional edge in trading. Building a robust cryptocurrency trading bot takes time. We know that, we built an algorithmic cryptocurrency trading platform entirely dedicated to simplifying this process.

So if you’re looking for a quick start, without the learning curve, plus the ability to run your bots in the cloud without having to run them locally 24/7, our algorithmic cryptocurrency trading platform Aesir is the quickest, most efficient way on how to get started with no risk.

Don’t forget to join our discord to stay up to date with our trading bot tutorials!

@SIR

©DEM Group 2022