Select Page

This tutorial was a result of Part Time Larry’s video TradingView Strategy Alert Webhooks with Binance API, Heroku, Python, and Flask. Below are the sections of this tutorial:

  • Part 1 Setup TradingView Alert Webhook
  • Part 2 Setup Binance API Key
  • Part 3 Setup Environment Variables
  • Part 4 Setup Python project workspace
  • Part 5 Test using REST Client
  • Part 6 Setup Git
  • Part 7 Deploy in Heroku
  • Part 8 Go Live



PART 1 : SETUP TRADINGVIEW WEBHOOK
Step 1. Login in to www.tradingview.com . Make sure your subscription is at least Pro. You may sign up for a 30-day trial account. https://www.tradingview.com/gopro/

Step 2. Select the pair you want to trade. In his example, it is ADAUSD from Binance US.

Step 3. On the bottom panel, select “Pine Editor“.


Step 4. Copy the sample-cardano-sma.pinescript below. Paste it in the “Pine Editor“. NOTE that this is NOT a profitable strategy. Please do your own research on a profitable trading strategy.

//@version=4
strategy("ADA SMA", overlay=true, initial_capital=25, default_qty_type=strategy.percent_of_equity, default_qty_value=100)

start_date = input(title="Start Date", type=input.integer, defval=1, minval=1, maxval=31)
start_month = input(title="Start Month", type=input.integer, defval=5, minval=1, maxval=12)
start_year = input(title="Start Year", type=input.integer, defval=2021)
end_date = input(title="End Date", type=input.integer, defval=6, minval=1, maxval=31)
end_month = input(title="End Month", type=input.integer, defval=9, minval=1, maxval=12)
end_year = input(title="End Year", type=input.integer, defval=2021)
     
between_dates = (time >= timestamp(start_year, start_month, start_date, 7, 0)) and (time < timestamp(end_year, end_month, end_date, 23, 59))
    
fast_ma_period = input(title="Fast MA", type=input.integer, defval=2)
slow_ma_period = input(title="Slow MA", type=input.integer, defval=5)

fast_ma = sma(close, fast_ma_period)
slow_ma = sma(close, slow_ma_period)

plot(fast_ma, color=color.green, linewidth=1)
plot(slow_ma, color=color.yellow, linewidth=3)

buy_condition = crossover(fast_ma, slow_ma)
sell_condition = crossunder(fast_ma, slow_ma)

if between_dates
    strategy.entry("ADA door", strategy.long, when=buy_condition)

strategy.close("ADA door",  when=sell_condition)


Step 5. Click “Add to Chart“. Make sure the “Object tree” is the current panel on the right vertical shortcut options.


Step 6. Select “Strategy Tester” for backtest results.
Step 7. To create an alert, select the alarm clock icon.


Step 8. In the Condition dropdown, select “ADA SMA“. This is the name of our indicator created in Step 3 the Pine Editor.


Step 9. Copy the contents of sample TradingView payload below. Paste to the Message textarea in the Alert being created (refer to above Step 8)

{
    "passphrase": "abcdefgh",
    "time": "{{timenow}}",
    "exchange": "{{exchange}}",
    "ticker": "{{ticker}}",
    "bar": {
        "time": "{{time}}",
        "open": {{open}},
        "high": {{high}},
        "low": {{low}},
        "close": {{close}},
        "volume": {{volume}}
    },
    "strategy": {
        "position_size": {{strategy.position_size}},
        "order_action": "{{strategy.order.action}}",
        "order_contracts": {{strategy.order.contracts}},
        "order_price": {{strategy.order.price}},
        "order_id": "{{strategy.order.id}}",
        "market_position": "{{strategy.market_position}}",
        "market_position_size": {{strategy.market_position_size}},
        "prev_market_position": "{{strategy.prev_market_position}}",
        "prev_market_position_size": {{strategy.prev_market_position_size}}
    }
}


Step 10. Save the alert. You will start receiving emails when the criteria are met.

PART 2 SETUP BINANCE API KEY

This tutorial uses Binance exchange. Other exchanges that supports API and official Python Library (e.g. Coinbase Pro, Kucoin, etc) can also be used for trading bots.
Step 1. Login to your Binance US account.
Step 2. Click “API Management” under the email address drop-down.


Step 3. Enter the API key label. Click “Create” when done.


Step 4. An email is sent to confirm that you created the API key.


Step 5. Open your email. Click “Confirm API Key Creation” button.


Step 6. The newly-created API key will be displayed. Make sure to save the Secret Key somewhere safe. It will disappear after refreshing the page. The API Key and Secret Key will later be used in PART 3 Step 5.

PART 3. SETUP ENVIRONMENT VARIABLES

Step 1. Type “Environment variables” in the Windows search bar. Choose the Best match.

Step 2. Click “Environment Variables…” button

Step 3. Click “New…” In the Variable Name and Variable Value fields, enter these combinations

Variable nameVariable valueNotes
API_KEYCopy the API Key from Part 2 Step 6
API_SECRETCopy the Secret Key from Part 2 Step 6
WEBHOOK_PASSPHRASEabcdefghRefer to the passphrase used in Part 1 Step 9

Step 5. The list of environment variables for the current user should look like this. Click the OK button to save.

PART 4 SETUP PYTHON PROJECT WORKSPACE
Step 1. Install Pycharm Community Edition in https://www.jetbrains.com/pycharm/download/
This tutorial uses the latest stable release pycharm-community-2021.1.2.exe

Step 2. Open Pycharm. Create New Project with a Virtual environment. The latest Pycharm installer will always have new virtual environment installed.


Step 3. Create new file with filename requirements.txt

flask
gunicorn
python-binance

Step 4. Select “Terminal” on the bottom panel. This will launch a command line. Execute the command

pip3 install -r requirements.txt

Step 5. Create new file with filename app.py
Go to https://flask.palletsprojects.com/en/1.1.x/quickstart/
Copy the contents of Minimal Application

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

Step 6. Create a file with filename Procfile. Associate it to a text file. Copy the below contents

web: gunicorn app:app

Step 7. In the Terminal window, execute

flask run

The Terminal logs will display above message and no errors.

Step 8. Open http://127.0.0.1:5000/ in a web browser. This will confirm that the local flask application is up.

Step 9. Now we are ready to write the code that consumes a JSON payload. Open app.py and copy the below code. Note that the actual execution of orders is commented out. Remember to uncomment the code when you want to execute the buy and sell orders.

import json, os

from binance.client import Client
from binance.enums import *
from flask import Flask, request

app = Flask(__name__)
client = Client(os.environ.get('API_KEY'), os.environ.get('API_SECRET'), tld='us')

def order(side, quantity, symbol, order_price, passphrase, order_type=ORDER_TYPE_LIMIT, timeInForce=TIME_IN_FORCE_GTC):
    try:
        print(f"{passphrase} {symbol} Sending order {order_type} - {side} {quantity} {symbol} at {order_price}.")
        #order = client.create_order(symbol=symbol, side=side, type=order_type, quantity=quantity, timeInForce=timeInForce, price=order_price)
        print(f" {passphrase} {symbol} Not Executed order {order_type} - {side} {quantity} {symbol} at {order_price}.")
    except Exception as e:
        print("An exception occured - {}".format(e))
        return False

    return order


@app.route('/')
def welcome():
    return "<h1>This is my first trading bot</h1>"


@app.route('/webhook', methods=['POST'])
def webhook():

    data = json.loads(request.data)

    if data['passphrase'] != os.environ.get('WEBHOOK_PASSPHRASE'):
        return {
            "code": "error",
            "message": "Nice try, invalid passphrase"
        }
    side = data['strategy']['order_action'].upper()
    quantity = data['strategy']['order_contracts']
    ticker = data['ticker'].upper()
    order_price = data['strategy']['order_price']

    order_response = order(side, quantity, ticker, order_price, data['passphrase'])


    if order_response:
        return {
            "code": "success",
            "message": "Order executed."
        }
    else:
        print("Order Failed.")

        return {
            "code": "error",
            "message": "Order Failed."
        }

Step 10. In the Terminal window, execute

flask run

PART 5 TEST USING REST CLIENT

This tutorial uses Insomnia as a REST Client. Feel free if you are more comfortable in using other REST clients.

Step 1. Download Insomnia REST client https://insomnia.rest/download
Step 2. Under the Dashboard, click Insomnia

The options will be displayed as below


Step 3. Press Ctrl + N to create a new request. Enter “http://127.0.0.1:5000/webhook” as the Name. Change “GET” to “POST” as the Method. Click “Create“.


Step 4. You may have to enter again the URL http://127.0.0.1:5000/webhook after the POST dropdown


Step 5. In the middle panel of Insomnia, select the “Body” dropdown. Click “JSON”

Step 6. Copy the JSON payload was sent to your email when the alert was triggered. You may use this sample filled payload:

{
    "passphrase": "abcdefgh",
    "time": "2020-09-06T01:44:17Z",
    "exchange": "BINANCE",
    "ticker": "ADAUSD",
    "bar": {
        "time": "2020-09-06T01:43:00Z",
        "open": 0.002748,
        "high": 0.0027486,
        "low": 0.002748,
        "close": 0.0027486,
        "volume": 150177
    },
    "strategy": {
        "position_size": 1000,
        "order_action": "buy",
        "order_contracts": 10,
        "order_price": 1.5,
        "order_id": "AMA door",
        "market_position": "long",
        "market_position_size": 10000,
        "prev_market_position": "flat",
        "prev_market_position_size": 0
    }
}

Step 7. Click “Send” button. The results will be displayed on the right panel.

Step 8. Familiarize yourself with the Binance API errors. Update the Python and/or Pinescript codes as needed.

Error code and messageExplanation and solution
01APIError(code=-2010): Account has insufficient balance for requested actionThe parameters are all correct, however there is not enough balance in the Binance account to execute the order
Solution: Deposit enough USD or cryptocurrency
02APIError(code=-1013): Filter failure: MIN_NOTIONALScenario: XTZUSD Sending order LIMIT – BUY 0.02 XTZUSD at $7.3865. Solution: Solution: Increase the order_contracts to at least 1
03APIError(code=-1111): Precision is over the maximum defined for this assetScenario: XTZUSD Sending order LIMIT – BUY 10 XTZUSD at $1.73215.
Solution: Set the price’s decimal places up to 4 only, e.g. $1.7321
04APIError(code=-1013): Filter failure: PERCENT_PRICEScenario: Current price of XTZUSD is $8.4972. Sending order LIMIT – BUY 10 XTZUSD at $1.5. The price cannot be lower than $1.6904
05 APIError(code=-1013): Filter failure: LOT_SIZE Scenario: Current price of XTZUSD is $8.4972. XTZUSD Sending order LIMIT – BUY 1000000 XTZUSD at $1.74.
Solution: Set the order_contracts to lower amount, e.g. 100000. If order_contracts is 541.861, decrease the precision, e.g. 541.86

PART 6 SETUP GIT

Step 1. Install Git from https://git-scm.com/downloads
Step 2. Open Git CMD and run this in the command line.

git config --global user.email "hello@example.com"

PART 7 DEPLOY IN HEROKU
Step 1. Sign up for a Heroku account in https://signup.heroku.com/account if you do not have an account yet.
Step 2.

Step 3. Enter the application name

Step 4. Setup the environment variables. In Heroku, this can be found in the application’s Dashboard –> Settings tab. Scroll to Config Vars. Click on the “Reveal Config Vars” button.

Add the following KEYs and VALUEs:

Variable nameVariable valueNotes
API_KEYCopy the API Key from PART 2 Step 6
API_SECRETCopy the Secret Key from PART 2 Step 6
WEBHOOK_PASSPHRASEabcdefghRefer to the passphrase used in PART 1 Step 9

Step 4. Once the application is successfully created, go to the application’s Dashboard –> Deploy tab. Refer to Deploy using Heroku Git.

Step 4a. Download and install Heroku installer that can be found in https://devcenter.heroku.com/articles/heroku-cli
Step 4b. Run this command in command prompt:

heroku login

It will ask you to press any key. Then a browser will open to Heroku login page. Enter your credentials. Below is a sample response in the command prompt.

Step 4c. To setup SSH key, run in the command prompt:

heroku keys:add

Type in y

Uploading C:\Users\TechieJackieBlogs.ssh\id_rsa.pub SSH key… done

Step 4d. Run in the command prompt:

ssh -v git@heroku.com

To verify the key has been added, open https://dashboard.heroku.com/account and scroll to the SSH Keys section.

Step 4e. In the Pycharm project Terminal, issue these commands:
git init
heroku git:remote -a <<App Name in Step 3>>

For example:

heroku git:remote -a mywebhook

If the commands do not work, double-check the PATH to include C:\Program Files\heroku\bin and C:\Program Files\Git\cmd

Step 4f. When there are changes in local codes that need to be committed to the Heroku Git server, execute these commands:
git add .

git commit -am "initial commit"
git push heroku master

Step 4g. To verify that the Heroku web application is live, open in a web browser https://{app-name}.herokuapp.com . For example, https://mywebhook.herokuapp.com/

To check for errors, in a command line or Pycharm Terminal, execute

heroku logs --tail

Possible ErrorPossible CausesHow to fix
at=error code=H14 desc=”No web processes running”The Procfile may have a .txt file extension1) Rename the local file
2) Run in command line git add .
git commit -am "added Procfile"
git push heroku master
at=error code=H14 desc=”No web processes running” There is no Procfile added in git1) Create a file named Procfile (no extension) with content web: gunicorn app:app
2) Run in command line git add .
git commit -am "added Procfile"
git push heroku master
at=error code=H14 desc=”No web processes running” No web dyno was setup1) Run in command line heroku ps:scale web=1
at=error code=H10 desc=”App crashed” method=GET path=”/”When running heroku logs --tail , the below messages are in the logs:
Starting process with command gunicorn app:app
bash: gunicorn: command not found
Process exited with status 127
1) Check requirements.txt if gunicorn is in the file. If not, add it to the file.
2) Run in command line git add .
git commit -am "added Procfile"
git push heroku master

The list of errors and explanations are found in https://devcenter.heroku.com/articles/error-codes

PART 8 GO LIVE

Step 1. Once you finalized a profitable strategy and replaced the Pinescript in Part 1 Step 4, it’s time to uncomment the Python code in app.py to execute buying or selling in Binance (Part 4 Step 9)

order = client.create_order(symbol=symbol, side=side, type=order_type, quantity=quantity, timeInForce=timeInForce, price=order_price)

Step 2. Commit the changes to Heroku Git (Follow Part 7 Step 4f)

Step 3. In Pycharm Terminal, execute heroku logs –tail

Step 4. Open the TradingView alert. Set the Webhook URL to the https://{app-name}.herokuapp.com/webhook (Part 1 Step 8)

Step 5. Monitor TradingView alert and your Binance app when the orders are executed. Happy lazy trading!

Areas of Improvement:

  1. Write a server-side validation to check there is enough balance to fill the order. Adjust the order_contracts based on the allowed balance to be used for the transaction.
  2. Round off the contract price and quantity in server-side (Python) or in Pinescript side to prevent errors mentioned in PART 5 Step 8 Familiarize yourself with the Binance API errors.

The source codes for this project can be downloaded here.