Creating A DCA bot with Python

I decided to build my own bot, it’s fairly simple. I am not much of a trader, so I don’t feel comfortable making a bot that will do the trading for me, when I don’t know how to trade myself. But I do like to DCA and I am also very lazy. I don’t live in the states so I don’t have access to a handy service like swan signal and Binance doesn’t offer a DCA option so I have created this bot.

  • Some programing knowledge.
  • Python 3.
  • python-binance.
  • Tweepy for tweeting (not essential but nice to have).
  • A Binance Demo account to do some testing on (Note: you will need a Github account for this).
  • When you have finished your testing the Binance API.
  • It does not add money from your bank account to Binance, You’ll have to set this up yourself.
  • The buy amount has to be more than the minimum buy amount, for Euro this is €10.
  • This bot is not optimized for a server, so I am planning on having it run on a raspberry pie I have.

You can get the full script on Github.

Building the bot

Tip! Unfortunately, the python-binance doesn’t have support for the demo API. However, you can connect by manually changing the API endpoint URL in the library like so, I used this in almost every function to test the code

client.API_URL = 'https://testnet.binance.vision/api'

Set up is fairly easy, I saved my API keys in my OS environment but feel free to copy and paste yours in.

import time
import math
import tweepy
import os
from binance.client import Client
from binance.enums import *
from binance.exceptions import BinanceAPIException, BinanceOrderException

#real API
api_key = os.environ.get('binance_api') # OR add your API KEY here secretKey = os.environ.get('binance_secret') # OR add your API SecretKey here


#Test API keys#
api_key = testKey
#secretKey = sTestKey
#client.API_URL = 'https://testnet.binance.vision/api'
client = Client(api_key, secretKey)

First we need to create some Binance API helper functions, we are going to use these to get some useful data from the Binance exchange. I will include the ones that this bot will use down below, if you check the Github you will find more helper functions that were used for testing, you might want to use them in your testing.

Makes a request to Binance API for the account balance of what ever you are trading, EUR in my case, Note the test API does not have Euro so change to USDT or another stable currency.

def getBalances():
#client.API_URL = 'https://testnet.binance.vision/api'
balance = client.get_asset_balance(asset='EUR') # or asset = 'USDT' for test
return balance

This will get the current price for your chosen trading pair.

def getMarketPrice(tradingPair):
#client.API_URL = 'https://testnet.binance.vision/api'
price = client.get_symbol_ticker(symbol=tradingPair)
return price

This is a twitter bot that will tweet out the price you buy your Crypto at plus any errors that occur when making a transaction.

def tweet(Order):
# Authenticate to Twitter
auth = tweepy.OAuthHandler("CONSUMER_KEY", "CONSUMER_SECRET")
auth.set_access_token("ACCESS_TOKEN", "ACCESS_TOKEN_SECRET")
api = tweepy.API(auth)api.update_status(order)

This function places a market buy order, it will then tweet the piece and trading pair using, or an error if the buy order does not go through.

def placeBuyOrder(quantity, tradingPair):
#client.API_URL = 'https://testnet.binance.vision/api'
try:
order = client.create_order(symbol=tradingPair, side='BUY', type='MARKET', quantity=quantity)
#order = client.create_test_order(symbol=tradingPair, side='BUY', type='MARKET', quantity=quantity)
toTweet = "Bought " + order["symbol"] + " at "+ order["fills"][0]['price']
tweet(toTweet)
except BinanceAPIException as e:
tweet(e)
print(e)
except BinanceOrderException as e:
tweet(e)
print(e)
return

This is the main function where you will use the other functions discussed previously.

First of all this gets the current price for your chosen trading pair, then it gets the balance in our account for whatever our fiat value is, Euro for me but what ever you want. You then need to get the step size which is basically gives you how many decimal places you should go to when buying at the current price. (Note you may not need this, but I couldn’t get it working without it).

After that check your balance and make sure you have enough money to actually buy some crypto (minimum spend in euro is €10). If the balance is more than the minimum buy amount, then a buy order will calculate and the “placeBuyOrder” function to execute that buy.

If the there isn’t enough fait in the account, then we are assuming the standing order hasn’t gone through and we are waiting an hour to see if the money has been lodged.

If for some reason there is an error in any of this, the Bot will tweet the error so I know something is up.

def dcaBot(tradingPair, dcaAmount):
#client.API_URL = 'https://testnet.binance.vision/api'
try:
currentPrice = float(getMarketPrice(tradingPair)['price'])
print("The current price is for the ", tradingPair, "pair is ", currentPrice) getBalance = float(getBalances()['free']) print("The current balance for EUR is ", getBalance) symbol_info = client.get_symbol_info(tradingPair)
step_size = 0.0
for f in symbol_info['filters']:
if f['filterType'] == 'LOT_SIZE':
step_size = float(f['stepSize'])
precision = int(round(-math.log(step_size, 10), 0)) quantity = float(round(quantity, precision)) if getBalance > 10:
print("buy amount ", quantity)
placeBuyOrder(quantity, tradingPair)
else:
print("Inceficent funds, bot will try again in an hour")
time.sleep(3600)
dcaBot(tradingPair, dcaAmount)
except BinanceAPIException as e:
tweet(e)
print(e)

The Bells and Whistles

I added this section to automate the DCAing process, the majority of this isn’t really required and you can just hardcode most of it, which is what I did with the trading pair.

First the script will ask the user the time frame they wish to DCA at, I have added daily weekly and monthly, but feel free to add your own. Then you will need to add how much you wish to DCA.

The bot will then run using and then wait the selected time frame.

if __name__ == '__main__':
timeFrame = input("Enter DCA time frame (day, week, month):" )
dcaTimeFrame = {
"day": 86400,
"week": 604800,
"month": 2629746
}
print("This bot will check the ballence of you account until money has been lodged, you must set up standing order yourself.")
dcaAmount = float(input("Enter how much you want to buy in fiat:")) print("You have chosen to DCA ", dcaTimeFrame[timeFrame.lower()])
print('Press Ctrl-C to stop.')
# Change this to your fiat crypto pair
fiatPair = 'ETHEUR'
for i in count():
dcaBot(fiatPair, dcaAmount) #(buyAmount) if set amount
print(f'Iteration {i}')
time.sleep(dcaTimeFrame[timeFrame])

Conclusion

This was a fun little project, it still needs a bit of work, I would like to set it up so that I can completely interact with it from twitter, I could simply tweet at the bot to change the order amount/trading pair, but that’s for the future.

PhD student and crypto enthusiast