DIY Trendline Trading Bot for Bittrex in Python

in #python7 years ago (edited)

This is not much of a tutorial but it will show you how to write a trading bot in Python 2.7 that’ll buy or sell along a given linear trendline. This can be used as a moving stoploss function or allow you to buy a dip automatically without having to sit staring at your computer all night. It is intended for people with basic Python skills.

Firstly you’ll need Python 2.7. Mac and linux users should already have this by default, Windows users can download and install the correct version here https://www.python.org/downloads. I won’t go into the intricacies of getting Python to work on Windows. There are plenty of tutorials already out there.

I’m going to be building a bot that works on the Bittrex exchange. But if you’re willing to learn about your exchange’s api protocol, you should be able to modify this script as needed. Once you have Python 2.7 set up, you’ll need to download the python-bittrex API bindings from Github here https://github.com/ericsomdahl/python-bittrex. Just unpack that zip file put it somewhere out of the way. Before we go any further you’ll also need to generate an api key and secret on Bittrex. This is done in your account settings on the website. Just make sure to tick all the options before generating and copy and paste the details somewhere safe, because you won’t be able to see them after you navigate away!

Now let’s get started. Open a new file in your favourite editor, then copy and paste the following code, saving it in the python-bittrex directory as trendlineTrader.py

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Fri Jan 19 13:04:24 2018

@author: barclay


trendlineTrader.py


READ ME

This script allows us to place buy or sell orders along a linear trendline of
the form y = mx + c. This means we can set a moving stoploss or buy a dip
on an inclined support line automatically without supervision. At present this 
only works on Bittrex.

REQUIREMENTS

1. You must have Python 2.7 installed. This will not work in Python 3 without 
modification. By default, this should already be installed on linux machines 
and Macs
2. You'll need a BITTREX account with an API key. This can be set in your 
account settings on BITTREX. Make sure to tick all options.

INSTALLATION

1. Download python-bittrex API bindings from Github: 
    
    https://github.com/ericsomdahl/python-bittrex 
    
   and unpack.
2. Copy or download this script and make sure it is saved as trendlineTrader.py 
   in the python-bittrex directory. If using Windows make sure the file 
   extension is .py not .txt
3. Enter your api key and secret from BITTREX into the corresponding 
   variables KEY and SECRET in this file. Scroll down. Afterwards they should 
   look somehting like this
   
   KEY = "YOUR_KEY_HERE"
   SECRET = "YOUR_SECRET_HERE"

4. Finished, just make sure to save the file.

USE

This is a command line programme. There is no GUI. However it is relatively 
easy.

1. Open your python console, e.g. a terminal on linux or Mac or the python 
   console of your Windows installation and navigate to the directory where 
   the script is stored.
2. Open a chart of the market you want to trade in tradingview.com via your
   webbrowser.
3. In your browser draw the trendline that you want to trade on. You will need 
   to enter the coordinates of the end points in the python script. 
   tradingview.com makes this easy by highlight these on the time and price 
   axes.
4. In the terminal enter the following command all on one line:
    
    python trendlineTrader.py -t TYPE -m MARKET -i INTERVAL -q QUANTITY 
    -p0 POINT0 -p1 POINT1 -v VARIANCE

    where the variables are
    
    TYPE        Type of trade. Select from: buy, sell
    MARKET      This is your trading market, e.g. USDT-BTC, USDT-BCC or
                BTC-ADA etc
    INTERVAL    This the the candlestick interval you are trading on.
                Select from: 15, 60, 240, D
    QUANTITY    Enter the quantity of the currency that you want to trade
    POINT0      Enter the coordinates of the start point in the following 
                format:
                    Hour Minute Price
    POINT1      Enter the coordinates of the end point in the following 
                format:
                    Hour Minute Price
    
    VARIANCE    This OPTIONAL parameter is set to 0 by default. It allows you 
                to set a margin of error either side of your trendline, e.g. if
                you enter -0.001, your order will be triggered when the 
                price reaches 0.1 % under the trendline. Use a positive number
                to set the variance above the trendline.

EXAMPLE: to buy 1 BTC on a trendline starting at 15:30 hrs and USD 11150 and 
         ending at 20:00 hrs and USD 15200 with default variance

     python trendlineTrader.py -t buy -m USDT-BTC -i 60 -q 1 -p0 15 30 11150 
     -p1 20 00 15200


That's it. Running the script is just one line. For each interval, the script 
calculates your buy or sell price and automatically places an order for you. 
If the order is not filled during the interval, it cancels the order and 
recalculates a new target and then places a new order for the next interval. 
The script terminates once the buy or sell order has been filled or the proces 
is terminated by the user.

Terminate the programme by closing the console or pressing Ctrl+c

"""

from __future__ import division
import urllib2
import time
from datetime import datetime
import time
import argparse

from bittrex import *



"""
CHANGE THESE VARIABLES ONLY !!!
"""
KEY = "38f12a5429f548508cf4e635f1c4884f"
SECRET = "a762356a4fa74f7382e3caa2a3e458ef"




def getTicker(pair):
    """
    Gets last transaction from Bittrex ticker
    """
    url = "https://bittrex.com/api/v1.1/public/getticker?market=" + pair
    data = urllib2.urlopen(url).read()

    if data.index("true"):
      last = data[data.rindex('"Last":') + 8 : -2]
    return float(last) 



def formatPoints(array):
    """
    Convert user point data [HOUR, MIN, PRICE] to [UNIX TIME, PRICE]
    WARNING BUG: at present only points on the same day may be inputed !!!
    """
    year = datetime.now().year
    month = datetime.now().month
    day = datetime.now().day
    t0 = datetime(year, month, day, array[0][0], array[0][1])
    t1 = datetime(year, month, day, array[1][0], array[1][1])
    t0 = time.mktime(t0.timetuple())
    t1 = time.mktime(t1.timetuple())
    data = [(t0, array[0][2]), (t1, array[1][2])]
    return data

    
def getTarget(x, times, var=0):
    """
    Calculates equation of the line and then returns target value for given
    interval
    """
    x0, x1 = times[0][0], times[1][0]
    y0, y1 = times[0][1], times[1][1]
    
    mprime = (y0 - y1) / (x0 - x1)
    c = y1 - mprime * x1
    m = (y1 - y0) / (x1 - x0)
    y = m*x + c

    return y + var*y


#establish parser for command line arguments
#variance is optional argument
parser = argparse.ArgumentParser(description="Trendline Trader")
parser.add_argument('-t','--type', help='Type of trade, e.g. buy or sell', required=True)
parser.add_argument('-i','--interval', help='Candlestick interval', required=True)
parser.add_argument('-m','--market', help='Trading market', required=True)
parser.add_argument('-q','--quantity', help='Quantity to trade', type=float, required=True)
parser.add_argument('-p0','--point0', nargs='+', help='Line data, point 0', type=int, required=True)
parser.add_argument('-p1','--point1', nargs='+', help='Line data, point 1',  required=True)

parser.add_argument('-v','--variance', type=float, help='Plus or minus value for target',  required=False)
args = vars(parser.parse_args())


#now make sure all user input conforms to specifications
interval = args['interval']

if interval:
    try:
        if interval not in ["15", "60", "240", "D"]:
            print "Error: Invalid interval. Valid intervals are 15, 60, 240, D"
        else:
            interval = int(interval)
    except ValueError:
        if interval == "D":
            interval = 1440

timeout = interval * 60.0 

data = [args['point0'],args['point1']]

if data:
    try:
        for i in range(2):
            for j in range(2):
                data[i][j] = int(data[i][j])
            data[i][2] = float(data[i][2])
    except TypeError:
        print "Error: Invalid line data. Hours and minutes must be type int and price must be type float"
        
coords = formatPoints(data)

quantity = args['quantity']   

TYPE = args['type']

  
variance = args['variance']
if variance is None:
    variance = 0
    
if variance > 0.001:
    print "Warning: Variance " + str(variance) + " > 0.001. Consider a smaller value."





if TYPE:
    if TYPE == "buy":
        action = 1
    elif TYPE == "sell":
        action = 2
    else:
        print "Error: Invalid order type. Please enter either buy or sell"


market = args['market']

session = Bittrex(KEY, SECRET, api_version=API_V1_1)
if market:
    try:
        currency = market[market.index('-')+1:]
    except ValueError:
        print "Error: Invalid market. Please enter valid Bittrex market, e.g. USDT-BTC"
    markets = session.list_markets_by_currency(currency)
    if market not in markets:
        print "Error: Invalid market. Please enter a valid Bittrex market, e.g. USDT-BTC"


#begin trading functions
uuid = 0

while True:
    #Authenticate and make session every cycle in case of socket disconneciton
    #by Bittrex
    session = Bittrex(KEY, SECRET, api_version=API_V1_1)
    
    #check to see if last order still there, if yes cancel it, else terminate
    #programme
    if uuid:
        response = session.get_order(uuid)
        if response['result']:
            response = session.cancel(uuid)
        elif response['success'] == False:
            print "ERROR: " + response['message']
            break
        else:
            break


    last = getTicker(market)
    now = time.time() - 2*3600 
    target = getTarget(now, coords, variance)
    
    if action == 1:
        response = session.buy_limit(market, quantity, target)
    else:
        response = session.sell_limit(market, quantity, target)
        
    #confirm order placement
    if response['success'] == True:
        print "Buy order placed at " + str(target)
        uuid = response['result']['uuid']
        print "Uuid: " + uuid
    else:
        print "ERROR: " + response['message']
        break
    
    
    time.sleep(timeout)

After you save the file, enter your Bittrex api key and secret in the following two lines. Do not change anything else! Make sure your key and secret are written in the speech marks.

KEY = "YOUR KEY HERE"
SECRET = "YOUR SECRET HERE"

To use the bot, you’ll first need to define the parameters of the trendline. This is where it helps to have a free account at http://www.tradingview.com. Here you can easily draw lines on their interactive charts. When you do the coordinates of the end points are highlighted on the axes. This means for use to parametrise a trendline all we need are the start and end points whose (x, y) coordinates are in fact (time, price).

screen.jpg

Open a terminal in the python-bittrex directory. An example Bitcoin buy order of 1 BTC along a trendline on the 1 hour chart looks like this

python trendlineTrader.py -t buy -m USDT-BTC -i 60 -q 1 -p0 15 30 11150 -p1 20 00 15200 

The arguments p0 and p1 are the end points of the trendline that we get from the tradingview.com chart. The format is HOUR MINUTE PRICE

To see what the arguments do, use the built in help function by entering

python trendlineTrader.py -h 

For more thorough instructions see the README at the top of the script. I should warn you this is a real trading bot and will buy or sell cryptocurrencies automatically. Make sure you know what you’re doing before you start by testing with a small amount. The programme will terminate automatically after a buy or sell order is fulfilled or the user closes the terminal.

If you have any questions, just ask in the comments section. Have fun and happy trading!