Documentation
HomeGithubDiscordBlog
  • What is OpenAlgo?
  • OpenAlgo Architecture
  • Mini FOSS Universe
  • Community Support
  • OpenAlgo GPT
  • New Features
    • Fast Scalper
    • API Analyzer
    • Traffic/Latency Monitor
    • Chartink Integration
  • Monetization
  • Connect Brokers
    • Brokers
      • 5Paisa
      • 5paisa (XTS)
      • AliceBlue
      • AngelOne
      • Compositedge
      • Dhan
      • Dhan(Sandbox)
      • Firstock
      • FlatTrade
      • Fyers
      • Groww
      • IIFL (XTS)
      • Jainam Retail (XTS)
      • Jainam Dealer (XTS)
      • Kotak Securities
      • Paytm
      • Pocketful
      • Shoonya
      • Tradejini
      • Upstox
      • Wisdom Capital
      • Zebu
      • Zerodha
  • Installation Guidelines
  • Getting Started
    • Windows Installation
      • Pre-Requesites
      • Setup
      • Install Dependencies
      • Ngrok Config
      • Environmental Variables
      • Start OpenAlgo
      • SSL Verification Failed
      • Accessing OpenAlgo
    • Windows Server Installation
    • Mac OS Installation
      • Pre-Requesties
      • Setup
      • Install Dependencies
      • Ngrok Config
      • Environmental Variables
      • Start OpenAlgo
      • Install certifi
      • Accessing OpenAlgo
    • Amazon Elastic Beanstalk
    • Ubuntu Server Installation
    • Docker Development
    • Testing OpenAlgo in Cloud
    • Upgrade
  • Latency
  • API Documentation
    • V1
      • Accounts API
        • Funds
        • Orderbook
        • Tradebook
        • PositionBook
        • Holdings
      • Orders API
        • Placeorder
        • PlaceSmartOrder
        • BasketOrder
        • SplitOrder
        • ModifyOrder
        • CancelOrder
        • CancelAllOrder
        • ClosePosition
        • OrderStatus
        • OpenPosition
      • Data API
        • Quotes
        • Depth
        • History
        • Intervals
        • Symbol
        • Ticker
      • Websockets
      • Order Constants
      • HTTP Status Codes
      • Rate Limiting
      • API Collections
  • Symbol Format
  • MCP
  • Trading Platform
    • Amibroker
      • AmiQuotes
      • Button Trading Module
      • Button Trading with Split Orders
      • Button Trading with Stoploss
      • SmartOrder Chart Module
      • Trailing Stoploss Execution Module
      • Line Trading Module
      • Equity Exploration Module
      • CSV Exploration Module
      • Options Button Trading Module
      • Spot/Futures to Options Module (Single Leg)
      • Spot/Futures to Options Module (Two Leg)
      • Time Based Execution
    • Tradingview
      • Futures to Options Module
    • ChartInk
    • Python
      • Strategy Management
      • EMA Crossover Strategy
      • EMA Crossover Strategy with Stoploss and Target
      • Supertrend Strategy
      • Supertrend Strategy with yfinance data
      • Voice Based Orders
    • NodeJS
    • Metatrader 5
      • Download & Install Library
      • OpenAlgo MQL5 Functions
      • Include the Header File
      • Sample Expert Advisor
    • Excel
    • Google Spreadsheets
    • N8N
    • Chrome Extension
  • Strategy Management
  • Developers
    • Design Documentation
      • Architecture
      • API Layer
      • Broker Integerations
      • Database Layer
      • Authentication Platforms
      • Configuration
      • Utilities
      • Broker Integration Checklist
  • Change Log
    • Version 1.0.0.25 Launched
    • Version 1.0.0.24 Launched
    • Version 1.0.0.23 Launched
    • Version 1.0.0.22 Launched
    • Version 1.0.0.21 Launched
    • Version 1.0.0.20 Launched
    • Version 1.0.0.19 Launched
    • Version 1.0.0.18 Launched
    • Version 1.0.0.17 Launched
    • Version 1.0.0.16 Launched
    • Version 1.0.0.15 Launched
    • Version 1.0.0.14 Launched
    • Version 1.0.0.13 Launched
    • Version 1.0.0.12 Launched
    • Version 1.0.0.11 Launched
    • Version 1.0.0.10 Launched
    • Version 1.0.0.9 Launched
    • Version 1.0.0.8 Launched
    • Version 1.0.0.7 Launched
    • Version 1.0.0.6 Launched
    • Version 1.0.0.5 Launched
    • Version 1.0.0.4 Launched
    • Version 1.0.0.3 Launched
    • Version 1.0.0.2 Launched
    • Version 1.0.0.1 Launched
    • Version 1.0.0.0 Launched
Powered by GitBook
On this page
  1. Trading Platform
  2. Python

EMA Crossover Strategy with Stoploss and Target

Strategy Name

EMA_Crossover_RELIANCE

Strategy Type

Positional Strategy – This strategy does not impose any intraday entry/exit time limits. Positions may remain open across multiple trading sessions until stoploss or target conditions are met.


Instrument Configuration

Parameter
Value

Symbol

RELIANCE

Exchange

NSE

Quantity

1

Order Type

MARKET

Product Type

MIS

Note: Even though MIS is used, positional behavior is controlled through logic, not by broker product type. This can be switched to CNC for true positional holding if desired.


Indicators Used

  • EMA 5: Exponential Moving Average over the last 5 closing prices (short-term trend).

  • EMA 10: Exponential Moving Average over the last 10 closing prices (medium-term trend).


Entry Conditions

  • Fetch 1-minute historical candle data every 5 seconds.

  • Calculate EMA-5 and EMA-10.

  • Identify confirmed crossover using the last two closed candles (i.e., not the current forming candle).

    • Buy Signal: Previous candle EMA-5 < EMA-10 and last closed candle EMA-5 > EMA-10.

    • Sell Signal: Previous candle EMA-5 > EMA-10 and last closed candle EMA-5 < EMA-10.

  • When a signal is confirmed:

    • Place a MARKET order (BUY or SELL).

    • Capture entry price and calculate:

      • Stoploss = Entry Price − 10.0

      • Target = Entry Price + 20.0


Exit Conditions

  • Use WebSocket streaming to receive live LTP updates.

  • Continuously monitor whether LTP hits stoploss or target levels.

  • When triggered, exit the position by placing a MARKET order in the opposite direction.


Strategy Architecture

  • Two dedicated threads:

    1. WebSocket Thread: Listens to real-time LTP and checks SL/Target.

    2. Strategy Thread: Periodically fetches historical data, calculates EMA signals, and initiates trades.

  • Uses threading.Event() to handle graceful shutdown via CTRL+C.


Shutdown Behavior

  • On receiving a keyboard interrupt, both threads are safely stopped.

  • WebSocket subscription is removed, and connection is closed.

  • The strategy exits cleanly and logs the shutdown.


Complete Code

import threading
import time
import signal
import pandas as pd
import pandas_ta as ta
from datetime import datetime, timedelta
from openalgo import api

# Initialize OpenAlgo client
client = api(
    api_key="openalgo-api-key",
    host="http://127.0.0.1:5000",
    ws_url="ws://127.0.0.1:8765"
)

# Configuration
STRATEGY_NAME = "EMA_Crossover_RELIANCE"
SYMBOL = "RELIANCE"
EXCHANGE = "NSE"
QUANTITY = 1
PRODUCT = "MIS"
PRICE_TYPE = "MARKET"
STOPLOSS_BUFFER = 10.0
TARGET_BUFFER = 20.0
instrument = [{"exchange": EXCHANGE, "symbol": SYMBOL}]

# State Variables
ltp = None
in_position = False
entry_price = None
stoploss_price = None
target_price = None
current_position = None
exit_signal = False
stop_event = threading.Event()

# WebSocket LTP Handler
def on_data_received(data):
    global ltp, exit_signal
    if data.get("type") == "market_data" and data.get("symbol") == SYMBOL:
        ltp = float(data["data"]["ltp"])
        print(f"LTP Update {EXCHANGE}:{SYMBOL} => ₹{ltp}")
        if in_position and not exit_signal:
            if ltp <= stoploss_price or ltp >= target_price:
                print(f"Exit Triggered: LTP ₹{ltp} hit stoploss or target.")
                exit_signal = True

# WebSocket Thread
def websocket_thread():
    try:
        client.connect()
        client.subscribe_ltp(instrument, on_data_received=on_data_received)
        print("WebSocket LTP thread started.")
        while not stop_event.is_set():
            time.sleep(1)
    finally:
        print("Shutting down WebSocket...")
        client.unsubscribe_ltp(instrument)
        client.disconnect()
        print("WebSocket connection closed.")

# EMA Signal Logic
def get_latest_signals():
    end_date = datetime.now()
    start_date = end_date - timedelta(days=3)

    df = client.history(
        symbol=SYMBOL,
        exchange=EXCHANGE,
        interval="5m",
        start_date=start_date.strftime("%Y-%m-%d"),
        end_date=end_date.strftime("%Y-%m-%d")
    )

    df.ta.ema(length=5, append=True)
    df.ta.ema(length=10, append=True)

    if len(df) < 3:
        print("Waiting for sufficient data...")
        return None

    prev = df.iloc[-3]
    last = df.iloc[-2]

    print(f"{datetime.now().strftime('%H:%M:%S')} | EMA5: {last['EMA_5']:.2f}, EMA10: {last['EMA_10']:.2f}")

    if prev['EMA_5'] < prev['EMA_10'] and last['EMA_5'] > last['EMA_10']:
        print("Confirmed BUY crossover.")
        return "BUY"
    elif prev['EMA_5'] > prev['EMA_10'] and last['EMA_5'] < last['EMA_10']:
        print("Confirmed SELL crossover.")
        return "SELL"
    return None

# Place Order
def place_order(action):
    global in_position, entry_price, stoploss_price, target_price, current_position

    print(f"Placing {action} order for {SYMBOL}")
    resp = client.placeorder(
        strategy=STRATEGY_NAME,
        symbol=SYMBOL,
        exchange=EXCHANGE,
        action=action,
        price_type=PRICE_TYPE,
        product=PRODUCT,
        quantity=QUANTITY
    )
    print("Order Response:", resp)

    if resp.get("status") == "success":
        order_id = resp.get("orderid")
        time.sleep(1)
        status = client.orderstatus(order_id=order_id, strategy=STRATEGY_NAME)
        data = status.get("data", {})
        if data.get("order_status", "").lower() == "complete":
            entry_price = float(data["price"])
            stoploss_price = round(entry_price - STOPLOSS_BUFFER, 2)
            target_price = round(entry_price + TARGET_BUFFER, 2)
            current_position = action
            in_position = True
            print(f"Entry @ ₹{entry_price} | SL ₹{stoploss_price} | Target ₹{target_price}")

# Exit Order
def exit_trade():
    global in_position, exit_signal
    action = "SELL" if current_position == "BUY" else "BUY"
    print(f"Exiting trade with {action}")
    client.placeorder(
        strategy=STRATEGY_NAME,
        symbol=SYMBOL,
        exchange=EXCHANGE,
        action=action,
        price_type=PRICE_TYPE,
        product=PRODUCT,
        quantity=QUANTITY
    )
    in_position = False
    exit_signal = False

# Strategy Thread
def strategy_thread():
    global exit_signal
    while not stop_event.is_set():
        if not in_position:
            signal = get_latest_signals()
            if signal:
                place_order(signal)
        elif exit_signal:
            exit_trade()
        time.sleep(5)

# Main Execution
def main():
    print("EMA Crossover Strategy is running...")

    ws_thread = threading.Thread(target=websocket_thread)
    strat_thread = threading.Thread(target=strategy_thread)

    ws_thread.start()
    strat_thread.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("KeyboardInterrupt received. Shutting down...")
        stop_event.set()
        ws_thread.join()
        strat_thread.join()
        print("Strategy shutdown complete.")

if __name__ == "__main__":
    main()

PreviousEMA Crossover StrategyNextSupertrend Strategy

Last updated 4 days ago