Rajandran R Creator of OpenAlgo - OpenSource Algo Trading framework for Indian Traders. Telecom Engineer turned Full-time Derivative Trader. Mostly Trading Nifty, Banknifty, High Liquid Stock Derivatives. Trading the Markets Since 2006 onwards. Using Market Profile and Orderflow for more than a decade. Designed and published 100+ open source trading systems on various trading tools. Strongly believe that market understanding and robust trading frameworks are the key to the trading success. Building Algo Platforms, Writing about Markets, Trading System Design, Market Sentiment, Trading Softwares & Trading Nuances since 2007 onwards. Author of Marketcalls.in

Supertrend Algomojo Trading Strategy using Algomojo and yfinance

6 min read

Supertrend is a simple ATR-based trend-following strategy that identifies the current trend and mages the risk dynamically with ATR-based trailing stop-loss. In this blog, we will learn how to implement the Supertrend Algomojo trading strategy using Algomojo and yfinance python library.

Algomojo is a cloud-based trading platform that provides APIs to connect to different brokers and exchanges. yfinance is a Python library that provides historical price data from Yahoo Finance. We will use both Algomojo and yfinance to implement the Supertrend trading strategy.

Requirements

1)Access to Algomojo Free API + Free Algo Platform

2)Python 3.x installed with Visual Studio Code Editor

3)Install Python Libraries – Algomojo, yfinance

pip install algomojo
pip install yfinance

Copy

4)Knowlege of using PlaceSmartOrder Algomojo Function

5)Knowledge of Handling pandas dataframe

yfinance python Library

The yfinance Python library is a popular and widely used package for retrieving financial data from Yahoo Finance. yfinance is a user-friendly and well-documented library that provides an easy way to access financial data, making it an ideal choice for beginners. yfinance is an open-source library and is free to use, making it a cost-effective option for automated trading.

While yfinance is a widely used library, the data it retrieves from Yahoo Finance may not always be reliable, and it may not be suitable for professional trading purposes. For professional trading it is highly recommended to use Authentic data vendors API or Broker API

Importing the Libraries

First, let’s import the necessary libraries.

from algomojo.pyapi import *
from datetime import datetime

import yfinance as yf

import pandas as pd
import numpy as np

import matplotlib.pyplot as plt

import math
import time
import threading

Setting Trading and Indicator Parameters

Next, we will set the necessary parameters for our trading strategy.

#set the StrategyName, broker code, Trading symbol, exchange, product and quantity
strategy = "Supertrend Python"
broker = "an"
api_key = "46ad9245cca3dfe957deb235a39d02a3"
api_secret = "30ca108cfb91f458babd2681fb6d0817"
symbol = "RELIANCE-EQ"  #Trading Symbol
exchange = "NSE"
product="MIS"
quantity = 10


#yfinance datafeed settings
yfsymbol = "RELIANCE.NS" #Datafeed Symbol
period = "1d"
timeframe = "1m"

#supertrend indicator inputs
atr_period = 5
atr_multiplier = 1.0

Here, we are setting the strategy name, broker code, api_key, api_secret, symbol of the security we want to trade, exchange on which the security is listed, product type, quantity of the security we want to trade, yfsymbol for the Yahoo Finance datafeed, period for the historical data, timeframe for the interval of the data, atr_period and atr_multiplier for the Supertrend indicator.

Setting API Key and API secret

To make use of the Supertrend algorithm to trade with Algomojo, we will need to create an API object and specify our API Key and API Secret Key.

algomojo = api(api_key=api_key, api_secret=api_secret)

Building Supertrend Function

Next, we need to define a function that will calculate the Supertrend based on a dataframe of historical price data. We will be using yfinance to obtain the price data. Code is inspired by Yong Hong Tan blog

def Supertrend(df, atr_period, multiplier):
    
    high = df['High']
    low = df['Low']
    close = df['Close']
    
    # calculate ATR
    price_diffs = [high - low, 
                   high - close.shift(), 
                   close.shift() - low]
    true_range = pd.concat(price_diffs, axis=1)
    true_range = true_range.abs().max(axis=1)
    # default ATR calculation in supertrend indicator
    atr = true_range.ewm(alpha=1/atr_period,min_periods=atr_period).mean() 
    # df['atr'] = df['tr'].rolling(atr_period).mean()
    
    # HL2 is simply the average of high and low prices
    hl2 = (high + low) / 2
    # upperband and lowerband calculation
    # notice that final bands are set to be equal to the respective bands
    final_upperband = upperband = hl2 + (multiplier * atr)
    final_lowerband = lowerband = hl2 - (multiplier * atr)
    
    # initialize Supertrend column to True
    supertrend = [True] * len(df)
    
    for i in range(1, len(df.index)):
        curr, prev = i, i-1
        
        # if current close price crosses above upperband
        if close[curr] > final_upperband[prev]:
            supertrend[curr] = True
        # if current close price crosses below lowerband
        elif close[curr] < final_lowerband[prev]:
            supertrend[curr] = False
        # else, the trend continues
        else:
            supertrend[curr] = supertrend[prev]
            
            # adjustment to the final bands
            if supertrend[curr] == True and final_lowerband[curr] < final_lowerband[prev]:
                final_lowerband[curr] = final_lowerband[prev]
            if supertrend[curr] == False and final_upperband[curr] > final_upperband[prev]:
                final_upperband[curr] = final_upperband[prev]

        # to remove bands according to the trend direction
        if supertrend[curr] == True:
            final_upperband[curr] = np.nan
        else:
            final_lowerband[curr] = np.nan
    
    return pd.DataFrame({
        'Supertrend': supertrend,
        'Final Lowerband': final_lowerband,
        'Final Upperband': final_upperband
    }, index=df.index)

The Supertrend function takes in a dataframe of historical price data as well as the ATR period and multiplier used in the Supertrend algorithm. It then calculates the ATR and the upper and lower bands, and uses these to determine the Supertrend for each point in the dataframe.

Next, we define our main trading function, which will loop continuously, checking the Supertrend at every iteration and placing trades accordingly.

Main Strategy Function


def supertrend_strategy():
    # Get historical data for the stock using Yahoo Finance API
    stock = yf.Ticker(yfsymbol)
   
     # Set initial values for variables
    position = 0
    
    


    # Main loop
    while True:
        # Get historical price data from 5min timeframe 

        df = stock.history(period=period, interval=timeframe)
        close = df.Close.round(2)
        supertrend = Supertrend(df, atr_period, atr_multiplier)
       

        # Calculate Supertrend
        is_uptrend = supertrend['Supertrend']

        # Determine the crossover point
        longentry = is_uptrend[-2] and (not is_uptrend[-3])
        shortentry = is_uptrend[-3] and (not is_uptrend[-2])

        
        # Place an order if there's a crossover and we don't already have a position
        if longentry and position<=0:

            # Update position variable
            position = quantity

            # Place Smart market buy order
            response = algomojo.PlaceSmartOrder(broker=broker ,
                                strategy=strategy,
                                exchange=exchange,
                                symbol=symbol,
                                action="BUY",
                                product=product,
                                pricetype="MARKET",
                                quantity=quantity,
                                price="0",
                                position_size=position,
                                trigger_price="0",
                                disclosed_quantity="0",
                                amo="NO",
                                splitorder="NO",
                                split_quantity="1") 

            print ("Buy Order Response :",response)
            
            

        # Close position if there's a crossover and we already have a position
        elif shortentry and position>=0:

            # Update position variable
            position = quantity*-1
            
            # Place Smart market sell order
            response = algomojo.PlaceSmartOrder(broker=broker,
                                strategy=strategy,
                                exchange=exchange,
                                symbol=symbol,
                                action="SELL",
                                product=product,
                                pricetype="MARKET",
                                quantity=quantity,
                                price="0",
                                position_size=position,
                                trigger_price="0",
                                disclosed_quantity="0",
                                amo="NO",
                                splitorder="NO",
                                split_quantity="1") 

            print ("Sell Order Response :",response)
            
            

        # Print current position and price data
        print("Position:", position)
        print("LTP:", close[-1])
        print("Supertrend:", supertrend['Supertrend'][-2])
        print("LowerBand:", supertrend['Final Lowerband'][-2].round(2))
        print("UpperBand:", supertrend['Final Upperband'][-2].round(2))
        print("longentry:", longentry)
        print("shortentry:", shortentry)

        # Wait for 15 seconds before checking again
        time.sleep(15)

The complete Supertrend Python strategy (supertrend.py)

#For Complete Algomojo Python Documentation Visit - https://pypi.org/project/algomojo/
#Coded by Rajandran R - www.marketcalls.in / www.algomojo.com

from algomojo.pyapi import *
from datetime import datetime

import yfinance as yf

import pandas as pd
import numpy as np

import matplotlib.pyplot as plt

import math
import time
import threading

#set the StrategyName, broker code, Trading symbol, exchange, product and quantity
strategy = "Supertrend Python"
broker = "an"
api_key = "46ad9245cca3dfe957deb235a39d02a3"
api_secret = "30ca108cfb91f458babd2681fb6d0817"
symbol = "RELIANCE-EQ"  #Trading Symbol
exchange = "NSE"
product="MIS"
quantity = 10


#yfinance datafeed settings
yfsymbol = "RELIANCE.NS" #Datafeed Symbol
period = "1d"
timeframe = "1m"

#supertrend indicator inputs
atr_period = 5
atr_multiplier = 1.0

# Set the API Key and API Secret key obtained from Algomojo MyAPI Section
algomojo = api(api_key=api_key, api_secret=api_secret)


def Supertrend(df, atr_period, multiplier):
    
    high = df['High']
    low = df['Low']
    close = df['Close']
    
    # calculate ATR
    price_diffs = [high - low, 
                   high - close.shift(), 
                   close.shift() - low]
    true_range = pd.concat(price_diffs, axis=1)
    true_range = true_range.abs().max(axis=1)
    # default ATR calculation in supertrend indicator
    atr = true_range.ewm(alpha=1/atr_period,min_periods=atr_period).mean() 
    # df['atr'] = df['tr'].rolling(atr_period).mean()
    
    # HL2 is simply the average of high and low prices
    hl2 = (high + low) / 2
    # upperband and lowerband calculation
    # notice that final bands are set to be equal to the respective bands
    final_upperband = upperband = hl2 + (multiplier * atr)
    final_lowerband = lowerband = hl2 - (multiplier * atr)
    
    # initialize Supertrend column to True
    supertrend = [True] * len(df)
    
    for i in range(1, len(df.index)):
        curr, prev = i, i-1
        
        # if current close price crosses above upperband
        if close[curr] > final_upperband[prev]:
            supertrend[curr] = True
        # if current close price crosses below lowerband
        elif close[curr] < final_lowerband[prev]:
            supertrend[curr] = False
        # else, the trend continues
        else:
            supertrend[curr] = supertrend[prev]
            
            # adjustment to the final bands
            if supertrend[curr] == True and final_lowerband[curr] < final_lowerband[prev]:
                final_lowerband[curr] = final_lowerband[prev]
            if supertrend[curr] == False and final_upperband[curr] > final_upperband[prev]:
                final_upperband[curr] = final_upperband[prev]

        # to remove bands according to the trend direction
        if supertrend[curr] == True:
            final_upperband[curr] = np.nan
        else:
            final_lowerband[curr] = np.nan
    
    return pd.DataFrame({
        'Supertrend': supertrend,
        'Final Lowerband': final_lowerband,
        'Final Upperband': final_upperband
    }, index=df.index)
    
    






def supertrend_strategy():
    # Get historical data for the stock using Yahoo Finance API
    stock = yf.Ticker(yfsymbol)
   
     # Set initial values for variables
    position = 0
    
    


    # Main loop
    while True:
        # Get historical price data from 5min timeframe 

        df = stock.history(period=period, interval=timeframe)
        close = df.Close.round(2)
        supertrend = Supertrend(df, atr_period, atr_multiplier)
       

        # Calculate Supertrend
        is_uptrend = supertrend['Supertrend']

        # Determine the crossover point
        longentry = is_uptrend[-2] and (not is_uptrend[-3])
        shortentry = is_uptrend[-3] and (not is_uptrend[-2])

        
        # Place an order if there's a crossover and we don't already have a position
        if longentry and position<=0:

            # Update position variable
            position = quantity

            # Place Smart market buy order
            response = algomojo.PlaceSmartOrder(broker=broker ,
                                strategy=strategy,
                                exchange=exchange,
                                symbol=symbol,
                                action="BUY",
                                product=product,
                                pricetype="MARKET",
                                quantity=quantity,
                                price="0",
                                position_size=position,
                                trigger_price="0",
                                disclosed_quantity="0",
                                amo="NO",
                                splitorder="NO",
                                split_quantity="1") 

            print ("Buy Order Response :",response)
            
            

        # Close position if there's a crossover and we already have a position
        elif shortentry and position>=0:

            # Update position variable
            position = quantity*-1
            
            # Place Smart market sell order
            response = algomojo.PlaceSmartOrder(broker=broker,
                                strategy=strategy,
                                exchange=exchange,
                                symbol=symbol,
                                action="SELL",
                                product=product,
                                pricetype="MARKET",
                                quantity=quantity,
                                price="0",
                                position_size=position,
                                trigger_price="0",
                                disclosed_quantity="0",
                                amo="NO",
                                splitorder="NO",
                                split_quantity="1") 

            print ("Sell Order Response :",response)
            
            

        # Print current position and price data
        print("Position:", position)
        print("LTP:", close[-1])
        print("Supertrend:", supertrend['Supertrend'][-2])
        print("LowerBand:", supertrend['Final Lowerband'][-2].round(2))
        print("UpperBand:", supertrend['Final Upperband'][-2].round(2))
        print("longentry:", longentry)
        print("shortentry:", shortentry)

        # Wait for 15 seconds before checking again
        time.sleep(15)

# Create and start a new thread to run the strategy
t = threading.Thread(target=supertrend_strategy)
t.start()
Rajandran R Creator of OpenAlgo - OpenSource Algo Trading framework for Indian Traders. Telecom Engineer turned Full-time Derivative Trader. Mostly Trading Nifty, Banknifty, High Liquid Stock Derivatives. Trading the Markets Since 2006 onwards. Using Market Profile and Orderflow for more than a decade. Designed and published 100+ open source trading systems on various trading tools. Strongly believe that market understanding and robust trading frameworks are the key to the trading success. Building Algo Platforms, Writing about Markets, Trading System Design, Market Sentiment, Trading Softwares & Trading Nuances since 2007 onwards. Author of Marketcalls.in

[Live Coding Webinar] Build Your First Trading Bridge for…

In this course, you will be learning to build your own trading bridge using Python. This 60-minute session is perfect for traders, Python enthusiasts,...
Rajandran R
1 min read

How to Place Orders Concurrently using ThreadPoolExecutor – Python…

Creating concurrent orders is essential for active traders, especially those handling large funds, as it allows for executing multiple trade orders simultaneously, thereby maximizing...
Rajandran R
2 min read

Host your Python Flask Web Application using pyngrok and…

Ngrok offers several significant advantages for developers, especially when it comes to testing applications or hosting machine learning models. Ngrok allows you to expose...
Rajandran R
1 min read

One Reply to “Supertrend Algomojo Trading Strategy using Algomojo and yfinance”

  1. no module algomojo.pyapi error even after installing algomojo Also name api does not exist error

Leave a Reply

Get Notifications, Alerts on Market Updates, Trading Tools, Automation & More