Skip to main content

Basic EMA Crossover Strategy

Overview

The Basic EMA Crossover Strategy is one of the most popular trend-following trading strategies used by traders across stocks, futures, options, forex, and cryptocurrency markets. The strategy uses two Exponential Moving Averages (EMAs) to identify trend changes and generate Buy and Sell signals automatically. This strategy comes with built-in Mirrorpip Integration Code, allowing traders to automate their TradingView signals directly to supported exchanges without any coding.

What is an EMA?

EMA (Exponential Moving Average) is a moving average that gives more weight to recent price movements, making it more responsive than a Simple Moving Average (SMA). Traders commonly use EMA crossovers to identify:
  • Trend reversals
  • Trend continuations
  • Entry opportunities
  • Exit opportunities
Here is the source code of the strategy
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © MIRRORPIP

//@version=5
strategy("MIRRORPIP EMA Strategy", shorttitle="MIRRORPIP EMA Strategy", overlay=true, default_qty_type=strategy.fixed, default_qty_value=1, pyramiding = 0, initial_capital=300000, currency=currency.NONE, commission_value=0, commission_type=strategy.commission.percent, process_orders_on_close=false, calc_on_every_tick=true, calc_on_order_fills = false)

////======================================================
paraTradeMode = input.string(title='Trade Mode', defval='Both', options=['Both', 'LongOnly', 'ShortOnly'], group = "Trade Settings")
paraSystemMode = input.session(defval="Intraday", title="System Mode", options=["Intraday", "Positional"], group = "Trade Settings")
s = input.session(title='Intraday Start Session:', defval='0915-1445', group='Trade Settings')
e = input.session(title='Intraday End Session:', defval='1500-1515', group='Trade Settings')

paraEMA1 = input.int(5, "Period : EMA-1 : ", minval = 1, group = "Trade Settings", inline = "EMA")
paraEMA2 = input.int(20, "EMA-2 : ", minval = 1, group = "Trade Settings", inline = "EMA")

paraTGTMode = input.string(defval="%", title="Target : ", options=["Off", "%", "Pts"], inline = "TGT", group = "Target Settings")
paraTGT1 = input.float(1, "T1 : ", minval = 0.1, inline = "TGT", group = "Target Settings")
paraTGT = input.float(2, "T2 : ", minval = 0.1, inline = "TGT", group = "Target Settings")

paraSLMode = input.string(defval="%", title="Stoploss : ", options=["Off", "%", "Pts"], inline = "SL", group = "Stoploss Settings")
paraSL = input.float(1, "Value : ", minval = 0.1, inline = "SL", group = "Stoploss Settings")

paraTSLMode = input.string(defval="%", title="Trail SL : ", options=["Off", "%", "Pts"], inline = "TSL", group = "TSL Settings")
paraTSL = input.float(0.50, "Value : ", minval = 0.1, inline = "TSL", group = "TSL Settings")

paraShowDashboard = input.bool(true, "Show Strategy Dashboard")
////======================================================

////======================================================
grpAlgo = "Algo Setup"
paraExchange = input.string(title='Exchange', defval='delta', group=grpAlgo)
paraCode = input.string(title='Code', defval='XXXXXX', group=grpAlgo)
paraQtyType = input.string(title="Quantity Type", defval='Fixed',options=['Fixed','Exposure'], group=grpAlgo)
paraQty = input.float(title='Quantity ', defval=1, minval=0, group=grpAlgo, tooltip='Qty in Lots for Futures')
paraT1Qty = input.float(title='Target-1 Exit Qty (%)', defval=0, minval=0, maxval = 100, group=grpAlgo, tooltip='Qty in Percentage')
paraMaxProfit = input.int(0, "Max Profit Per Trade", 0, group=grpAlgo, tooltip='Exit on Max. Profit in Rs.')
paraMaxLoss = input.int(0, "Max Loss Per Trade", 0, group=grpAlgo, tooltip='Exit on Max. Loss in Rs.')
////======================================================

////======================================================
FC = session.isfirstbar
LC = session.islastbar

st = paraSystemMode=="Positional" ? true : not na(time(timeframe.period, s))
et = paraSystemMode=="Intraday" and not na(time(timeframe.period, e))

EMA1 = ta.ema(close, paraEMA1)
EMA2 = ta.ema(close, paraEMA2)

eBuy1 = ta.crossover(EMA1, EMA2) and barstate.isconfirmed
eShort1 = ta.crossunder(EMA1, EMA2) and barstate.isconfirmed

eSignal = 0
eBuy =  eBuy1 
eShort =  eShort1 
eSell = eShort or et
eCover = eBuy or et
eSignal := eBuy ? 1 : eShort ? -1 : eSell and eSignal[1] > 0 ? 0 : eCover and eSignal[1] < 0 ? 0 : eSignal[1]

MainSignal = 0
BuySignal = paraTradeMode!="ShortOnly" and st and eSignal > 0 and eSignal[1] <= 0 and barstate.isconfirmed and (nz(MainSignal[1]) <= 0)
ShortSignal = paraTradeMode!="LongOnly" and st and eSignal < 0 and eSignal[1] >= 0 and barstate.isconfirmed and (nz(MainSignal[1]) >= 0)
SellSignal = (((ShortSignal or eSignal <= 0) and barstate.isconfirmed) or et) and (nz(MainSignal[1]) == 1)
CoverSignal = (((BuySignal or eSignal >= 0) and barstate.isconfirmed) or et) and (nz(MainSignal[1]) == -1)
MainSignal := BuySignal ? 1 : ShortSignal ? -1 : SellSignal and MainSignal[1] > 0 ? 0 : CoverSignal and MainSignal[1] < 0 ? 0 : MainSignal[1]
////======================================================

////======================================================
symbol = syminfo.ticker

BuyPrice = ta.valuewhen(BuySignal, close, 0)
ShortPrice = ta.valuewhen(ShortSignal, close, 0)

LESym = str.tostring(syminfo.ticker) 
LXSym = str.tostring(syminfo.ticker) 
SESym = str.tostring(syminfo.ticker) 
SXSym = str.tostring(syminfo.ticker) 

var float BuyTradeQty = na
var float ShortTradeQty = na

BuyTradeQty := paraQty
ShortTradeQty := paraQty

if (paraQtyType=="Exposure")
    BuyTradeQty := paraQty / BuyPrice
    BuyTradeQty := math.round(BuyTradeQty / syminfo.pointvalue) 
    ShortTradeQty := paraQty / ShortPrice
    ShortTradeQty := math.round(ShortTradeQty / syminfo.pointvalue) 

    if (BuyTradeQty < 0)
        BuyTradeQty := 1
    if (ShortTradeQty < 0)
        ShortTradeQty := 1

buyData = '{ "exchange": "' + paraExchange + '", "price": "' + str.tostring(close) + '", "chart_symbol": "' + LESym + '", "order_type": "BUY", "instrument_type": "NA", "quantity": "' + str.tostring(BuyTradeQty) + '", "tp": "0", "sl": "0", "code": "'+paraCode+'"}'
sellData = '{ "exchange": "' + paraExchange + '", "price": "' + str.tostring(close) + '", "chart_symbol": "' + LXSym + '", "order_type": "SELL", "instrument_type": "NA", "quantity": "' + str.tostring(BuyTradeQty) + '", "tp": "0", "sl": "0", "code": "'+paraCode+'"}'
shortData = '{ "exchange": "' + paraExchange + '", "price": "' + str.tostring(close) + '", "chart_symbol": "' + SESym + '", "order_type": "SHORT", "instrument_type": "NA", "quantity": "' + str.tostring(ShortTradeQty) + '", "tp": "0", "sl": "0", "code": "'+paraCode+'"}'
coverData = '{ "exchange": "' + paraExchange + '", "price": "' + str.tostring(close) + '", "chart_symbol": "' + SXSym + '", "order_type": "COVER", "instrument_type": "NA", "quantity": "' + str.tostring(ShortTradeQty) + '", "tp": "0", "sl": "0", "code": "'+paraCode+'"}'
////======================================================

////======================================================
if BuySignal and strategy.position_size < 0  
    strategy.entry('BUY', strategy.long, comment='Buy', qty=BuyTradeQty, alert_message="["+coverData+","+buyData+"]")
else if BuySignal and strategy.position_size == 0 
    strategy.entry('BUY', strategy.long, comment='Buy', qty=BuyTradeQty, alert_message="["+buyData+"]")

if ShortSignal and strategy.position_size > 0
    strategy.entry('SHORT', strategy.short, comment='Short', qty=ShortTradeQty, alert_message="["+sellData+","+shortData+"]")
else if ShortSignal and strategy.position_size == 0 
    strategy.entry('SHORT', strategy.short, comment='Short', qty=ShortTradeQty, alert_message="["+shortData+"]")


var float BuyTGT = na
var float ShortTGT = na
var float BuyTGT1 = na
var float ShortTGT1 = na
var float BuySL = na
var float ShortSL = na
var float BuyTSL = na
var float ShortTSL = na

ut = (paraTGTMode != "Off")
us = (paraSLMode != "Off")

if (strategy.position_size > 0 and strategy.position_size[1] <= 0)
    BuyPrice := strategy.position_avg_price
    if (paraSLMode=="%")
        BuySL := BuyPrice * (1-(paraSL/100))
    else if (paraSLMode=="Pts")
        BuySL := BuyPrice - (paraSL)

    if (paraTGTMode=="%")
        BuyTGT1 := BuyPrice * (1+(paraTGT1/100))
        BuyTGT := BuyPrice * (1+(paraTGT/100))
    else if (paraTGTMode=="Pts")
        BuyTGT1 := BuyPrice + (paraTGT1)
        BuyTGT := BuyPrice + (paraTGT)

if (strategy.position_size < 0 and strategy.position_size[1] >= 0)
    ShortPrice := strategy.position_avg_price
    if (paraSLMode=="%")
        ShortSL := ShortPrice * (1+(paraSL/100))
    else if (paraSLMode=="Pts")
        ShortSL := ShortPrice + (paraSL)

    if (paraTGTMode=="%")
        ShortTGT1 := ShortPrice * (1-(paraTGT1/100))
        ShortTGT := ShortPrice * (1-(paraTGT/100))
    else if (paraTGTMode=="Pts")
        ShortTGT1 := ShortPrice - (paraTGT1)
        ShortTGT := ShortPrice - (paraTGT)

if (paraTSLMode != "Off")
    if (strategy.position_size > 0 and strategy.position_size[1] > 0)
        if (paraTSLMode=="%")
            BuyTSL := high[1] * (1-(paraTSL/100))
        else
            BuyTSL := high[1] - paraTSL
        if (BuySL < BuyTSL)
            BuySL := BuyTSL
    if (strategy.position_size < 0 and strategy.position_size[1] < 0)
        if (paraTSLMode=="%")
            ShortTSL := low[1] * (1+(paraTSL/100))
        else
            ShortTSL := low[1] + paraTSL
        if (ShortSL > ShortTSL)
            ShortSL := ShortTSL

if (paraMaxProfit > 0)
    if (strategy.position_size > 0 and strategy.opentrades.profit(strategy.opentrades - 1) >= paraMaxProfit)
        strategy.close("BUY", immediately = true, alert_message="["+sellData+"]")
    if (strategy.position_size < 0 and strategy.opentrades.profit(strategy.opentrades - 1) >= paraMaxProfit)
        strategy.close("SHORT", immediately = true, alert_message="["+coverData+"]")

if (paraMaxLoss > 0)
    if (strategy.position_size > 0 and strategy.opentrades.profit(strategy.opentrades - 1) <= -(paraMaxLoss))
        strategy.close("BUY", immediately = true, alert_message="["+sellData+"]")
    if (strategy.position_size < 0 and strategy.opentrades.profit(strategy.opentrades - 1) <= -(paraMaxLoss))
        strategy.close("SHORT", immediately = true, alert_message="["+coverData+"]")

Pos_Size = math.abs(strategy.position_size)
T1ExQty = math.round(Pos_Size*(paraT1Qty/100))
TPsellData = '{ "exchange": "' + paraExchange + '", "price": "' + str.tostring(close) + '", "chart_symbol": "' + LXSym + '", "order_type": "SELL", "instrument_type": "NA", "quantity": "' + str.tostring(T1ExQty) + '", "tp": "0", "sl": "0", "code": "'+paraCode+'"}'
TPcoverData = '{ "exchange": "' + paraExchange + '", "price": "' + str.tostring(close) + '", "chart_symbol": "' + SXSym + '", "order_type": "COVER", "instrument_type": "NA", "quantity": "' + str.tostring(T1ExQty) + '", "tp": "0", "sl": "0", "code": "'+paraCode+'"}'

sellData := '{ "exchange": "' + paraExchange + '", "price": "' + str.tostring(close) + '", "chart_symbol": "' + LXSym + '", "order_type": "SELL", "instrument_type": "NA", "quantity": "' + str.tostring(Pos_Size) + '", "tp": "0", "sl": "0", "code": "'+paraCode+'"}'
coverData := '{ "exchange": "' + paraExchange + '", "price": "' + str.tostring(close) + '", "chart_symbol": "' + SXSym + '", "order_type": "COVER", "instrument_type": "NA", "quantity": "' + str.tostring(Pos_Size) + '", "tp": "0", "sl": "0", "code": "'+paraCode+'"}'

if ut == true and us == false
    if (strategy.position_size > 0)
        if (paraT1Qty > 0 and paraTGT1 > 0)
            strategy.exit(id="LongT1Exit", from_entry="BUY", qty = T1ExQty, limit=BuyTGT1, comment="TPSell", alert_message="["+TPsellData+"]", oca_name = "LX1")
        strategy.exit(id='LongExit', comment="Sell", from_entry='BUY', limit=BuyTGT, alert_message="["+sellData+"]")
    if (strategy.position_size < 0)
        if (paraT1Qty > 0 and paraTGT1 > 0)
            strategy.exit(id="ShortT1Exit", from_entry="SHORT", qty = T1ExQty, limit=ShortTGT1, comment="TPCover", alert_message="["+TPcoverData+"]", oca_name = "SX1")
        strategy.exit(id='ShortExit', comment="Cover", from_entry='SHORT', limit=ShortTGT, alert_message="["+coverData+"]")
if us == true and ut == false 
    if (strategy.position_size > 0)
        strategy.exit(id='LongExit', comment="Sell", from_entry='BUY', stop=BuySL, alert_message="["+sellData+"]")
    if (strategy.position_size < 0)
        strategy.exit(id='ShortExit', comment="Cover", from_entry='SHORT', stop=ShortSL, alert_message="["+coverData+"]")
if ut == true and us == true
    if (strategy.position_size > 0)
        if (paraT1Qty > 0 and paraTGT1 > 0)
            strategy.exit(id="LongT1Exit", from_entry="BUY", qty = T1ExQty, limit=BuyTGT1, stop=BuySL, comment="TPSell", alert_message="["+TPsellData+"]", oca_name = "LX1")
        strategy.exit(id='LongExit', comment="Sell", from_entry='BUY', limit=BuyTGT, stop=BuySL, alert_message="["+sellData+"]")
    if (strategy.position_size < 0)
        if (paraT1Qty > 0 and paraTGT1 > 0)
            strategy.exit(id="ShortT1Exit", from_entry="SHORT", qty = T1ExQty, limit=ShortTGT1, stop=ShortSL, comment="TPCover", alert_message="["+TPcoverData+"]", oca_name = "SX1")
        strategy.exit(id='ShortExit', comment="Cover", from_entry='SHORT', limit=ShortTGT, stop=ShortSL, alert_message="["+coverData+"]")

if (et ) and strategy.position_size > 0 
    strategy.cancel('LongExit')
    strategy.cancel('LongT1Exit')
    strategy.close(id='BUY', comment="Sell", alert_message="["+sellData+"]")

if (et ) and strategy.position_size < 0 
    strategy.cancel('ShortExit')
    strategy.cancel('ShortT1Exit')
    strategy.close(id='SHORT', comment="Cover", alert_message="["+coverData+"]")

if (strategy.position_size <= 0)
    strategy.cancel('LongExit')
    strategy.cancel('LongT1Exit')
if (strategy.position_size >= 0)
    strategy.cancel('ShortExit')
    strategy.cancel('ShortT1Exit')
////======================================================

////======================================================
plot(EMA1, "EMA", color.green)
plot(EMA2, "EMA", color.red)

//plotshape(BuySignal, style=shape.triangleup , location=location.belowbar, color=color.green, size=size.normal)
//plotshape(ShortSignal, style=shape.triangledown, location=location.abovebar, color=color.red, size=size.normal)
//plotshape(strategy.position_size>0?SellSignal:na, style=shape.triangledown , location=location.abovebar, color=color.green, size=size.small)
//plotshape(strategy.position_size<0?CoverSignal:na, style=shape.triangleup, location=location.belowbar, color=color.red, size=size.small)

plot((strategy.position_size > 0)?BuyPrice:na, color=color.fuchsia, linewidth=1, style=plot.style_linebr)
plot((strategy.position_size > 0) and paraTGT1?BuyTGT1:na, color=color.blue, linewidth=1, style=plot.style_linebr)
plot((strategy.position_size > 0)?BuyTGT:na, color=color.blue, linewidth=1, style=plot.style_linebr)
plot((strategy.position_size > 0)?BuySL:na, color=color.orange, linewidth=1, style=plot.style_linebr)

plot((strategy.position_size < 0)?ShortPrice:na, color=color.fuchsia, linewidth=1, style=plot.style_linebr)
plot((strategy.position_size < 0) and paraTGT1?ShortTGT1:na, color=color.blue, linewidth=1, style=plot.style_linebr)
plot((strategy.position_size < 0)?ShortTGT:na, color=color.blue, linewidth=1, style=plot.style_linebr)
plot((strategy.position_size < 0)?ShortSL:na, color=color.orange, linewidth=1, style=plot.style_linebr)
////======================================================

////======================================================
totalCols = 2
totalRows = 5 
stgTGTFlag = paraTGTMode != "Off"
stgSLFlag = paraSLMode != "Off"

if stgTGTFlag
    totalRows += 1
if stgSLFlag
    totalRows += 1

var dashtable = table.new(position.bottom_left, totalCols, totalRows,
  frame_color=color.new(#000000,0),
  frame_width=1,
  border_color=color.new(#000000,0),
  border_width=1)

cell_up = #237a27 //input.color(#237a27,'Buy Cell Color'  ,group='Style Settings')
cell_dn = color.red //input.color(color.red,'Sell Cell Color'  ,group='Style Settings')
cell_Neut = color.gray //input.color(color.gray,'Neut Cell Color'  ,group='Style Settings')
txt_col = color.white

table_text_size = size.small

openProfit = strategy.openprofit
lastProfit = strategy.closedtrades.profit(strategy.closedtrades-1)
openProfitColor = openProfit >= 0 ? cell_up : cell_dn
lastProfitColor = lastProfit >= 0 ? cell_up : cell_dn

rowCtr = 0
colCtr = 0

if (barstate.islast and paraShowDashboard)
    table.cell(dashtable, 0, rowCtr, "MIRRORPIP Dashboard", text_color=txt_col, text_size=table_text_size, bgcolor=color.new(color.blue,80), tooltip="")  
    table.cell(dashtable, 1, rowCtr, '', text_color=txt_col, text_size=table_text_size, bgcolor=color.new(color.blue,80), tooltip="")
    table.merge_cells(dashtable, 0, 0, 1, 0)

    if strategy.position_size > 0
        rowCtr += 1
        table.cell(dashtable, 0, rowCtr, "Buy",text_color=txt_col,text_size=table_text_size,bgcolor=cell_up,tooltip="")
        table.cell(dashtable, 1, rowCtr, str.tostring(strategy.position_avg_price, format.mintick),text_color=txt_col,text_size=table_text_size,bgcolor=cell_up,tooltip="")
        rowCtr += 1
        table.cell(dashtable, 0, rowCtr, "Qty.",text_color=txt_col,text_size=table_text_size,bgcolor=cell_up,tooltip="")
        table.cell(dashtable, 1, rowCtr, str.tostring(strategy.position_size, "#"),text_color=txt_col,text_size=table_text_size,bgcolor=cell_up,tooltip="")
        if (stgTGTFlag)
            rowCtr += 1
            table.cell(dashtable, 0, rowCtr, "TGT",text_color=txt_col,text_size=table_text_size,bgcolor=cell_up,tooltip="")
            if (BuyTGT1)
                table.cell(dashtable, 1, rowCtr, str.tostring(BuyTGT1, format.mintick) + "/"+ str.tostring(BuyTGT, format.mintick),text_color=txt_col,text_size=table_text_size,bgcolor=cell_up,tooltip="")
            else    
                table.cell(dashtable, 1, rowCtr, str.tostring(BuyTGT, format.mintick),text_color=txt_col,text_size=table_text_size,bgcolor=cell_up,tooltip="")
        if (stgSLFlag)
            rowCtr += 1
            table.cell(dashtable, 0, rowCtr, "SL",text_color=txt_col,text_size=table_text_size,bgcolor=cell_dn,tooltip="")
            table.cell(dashtable, 1, rowCtr, str.tostring(BuySL, format.mintick),text_color=txt_col,text_size=table_text_size,bgcolor=cell_dn,tooltip="")
        rowCtr += 1
        table.cell(dashtable, 0, rowCtr, "P&L",text_color=txt_col,text_size=table_text_size,bgcolor=openProfitColor,tooltip="")
        table.cell(dashtable, 1, rowCtr, str.tostring(openProfit, format.mintick),text_color=txt_col,text_size=table_text_size,bgcolor=openProfitColor,tooltip="")

    if strategy.position_size < 0
        rowCtr += 1
        table.cell(dashtable, 0, rowCtr, "Short",text_color=txt_col,text_size=table_text_size,bgcolor=cell_dn,tooltip="")
        table.cell(dashtable, 1, rowCtr, str.tostring(strategy.position_avg_price, format.mintick),text_color=txt_col,text_size=table_text_size,bgcolor=cell_dn,tooltip="")
        rowCtr += 1
        table.cell(dashtable, 0, rowCtr, "Qty.",text_color=txt_col,text_size=table_text_size,bgcolor=cell_dn,tooltip="")
        table.cell(dashtable, 1, rowCtr, str.tostring(strategy.position_size, "#"),text_color=txt_col,text_size=table_text_size,bgcolor=cell_dn,tooltip="")
        if (stgTGTFlag)
            rowCtr += 1
            table.cell(dashtable, 0, rowCtr, "TGT",text_color=txt_col,text_size=table_text_size,bgcolor=cell_up,tooltip="")
            if (ShortTGT1)
                table.cell(dashtable, 1, rowCtr, str.tostring(ShortTGT1, format.mintick) + "/"+ str.tostring(ShortTGT, format.mintick),text_color=txt_col,text_size=table_text_size,bgcolor=cell_up,tooltip="")
            else    
                table.cell(dashtable, 1, rowCtr, str.tostring(ShortTGT, format.mintick),text_color=txt_col,text_size=table_text_size,bgcolor=cell_up,tooltip="")
        if (stgSLFlag)
            rowCtr += 1
            table.cell(dashtable, 0, rowCtr, "SL",text_color=txt_col,text_size=table_text_size,bgcolor=cell_dn,tooltip="")
            table.cell(dashtable, 1, rowCtr, str.tostring(ShortSL, format.mintick),text_color=txt_col,text_size=table_text_size,bgcolor=cell_dn,tooltip="")
        rowCtr += 1
        table.cell(dashtable, 0, rowCtr, "P&L",text_color=txt_col,text_size=table_text_size,bgcolor=openProfitColor,tooltip="")
        table.cell(dashtable, 1, rowCtr, str.tostring(openProfit, format.mintick),text_color=txt_col,text_size=table_text_size,bgcolor=openProfitColor,tooltip="")

    if strategy.position_size == 0
        rowCtr += 1
        table.cell(dashtable, 0, rowCtr, "No Trade", text_color=txt_col,text_size=table_text_size,bgcolor=cell_Neut,tooltip="")
        table.cell(dashtable, 1, rowCtr, "Relax", text_color=txt_col,text_size=table_text_size,bgcolor=cell_Neut,tooltip="")
        rowCtr += 1
        table.cell(dashtable, 0, rowCtr, "",text_color=txt_col,text_size=table_text_size,bgcolor=cell_Neut,tooltip="")
        table.cell(dashtable, 1, rowCtr, "",text_color=txt_col,text_size=table_text_size,bgcolor=cell_Neut,tooltip="")
        if (stgTGTFlag)
            rowCtr += 1
            table.cell(dashtable, 0, rowCtr, "",text_color=txt_col,text_size=table_text_size,bgcolor=cell_Neut,tooltip="")
            table.cell(dashtable, 1, rowCtr, "",text_color=txt_col,text_size=table_text_size,bgcolor=cell_Neut,tooltip="")
        if (stgSLFlag)
            rowCtr += 1
            table.cell(dashtable, 0, rowCtr, "",text_color=txt_col,text_size=table_text_size,bgcolor=cell_Neut,tooltip="")
            table.cell(dashtable, 1, rowCtr, "",text_color=txt_col,text_size=table_text_size,bgcolor=cell_Neut,tooltip="")
        rowCtr += 1
        table.cell(dashtable, 0, rowCtr, "",text_color=txt_col,text_size=table_text_size,bgcolor=cell_Neut,tooltip="")
        table.cell(dashtable, 1, rowCtr, "",text_color=txt_col,text_size=table_text_size,bgcolor=cell_Neut,tooltip="")

    if strategy.position_size <= 0 and strategy.position_size[1] > 0
        rowCtr += 1
        table.cell(dashtable, 0, rowCtr, "Exit Buy",text_color=txt_col,text_size=table_text_size,bgcolor=lastProfitColor,tooltip="")
        table.cell(dashtable, 1, rowCtr, str.tostring(lastProfit, format.mintick),text_color=txt_col,text_size=table_text_size,bgcolor=lastProfitColor,tooltip="")
    else if strategy.position_size >= 0 and strategy.position_size[1] < 0
        rowCtr += 1
        table.cell(dashtable, 0, rowCtr, "Exit Short",text_color=txt_col,text_size=table_text_size,bgcolor=lastProfitColor,tooltip="")
        table.cell(dashtable, 1, rowCtr, str.tostring(lastProfit, format.mintick),text_color=txt_col,text_size=table_text_size,bgcolor=lastProfitColor,tooltip="")
    else    
        rowCtr += 1
        table.cell(dashtable, 0, rowCtr, "Last P&L",text_color=txt_col,text_size=table_text_size,bgcolor=lastProfitColor,tooltip="")
        table.cell(dashtable, 1, rowCtr, str.tostring(lastProfit, format.mintick),text_color=txt_col,text_size=table_text_size,bgcolor=lastProfitColor,tooltip="")
////======================================================

How the Strategy Works

The strategy uses:
  • Fast EMA
  • Slow EMA
When the Fast EMA crosses the Slow EMA, a trading signal is generated.

Long Entry Logic

A Buy signal is generated when:
  • Fast EMA crosses above the Slow EMA.
  • The market shows bullish momentum.
Mirrorpip automatically places a Buy order on the connected exchange.

Example

Fast EMA: 20 Slow EMA: 50 If EMA 20 crosses above EMA 50: → Buy Signal Generated

Short Entry Logic

A Sell or Short signal is generated when:
  • Fast EMA crosses below the Slow EMA.
  • The market shows bearish momentum.
Mirrorpip automatically places a Sell/Short order on supported exchanges.

Example

Fast EMA: 20 Slow EMA: 50 If EMA 20 crosses below EMA 50: → Short Signal Generated

Fully Customizable EMA Settings

Users can configure both moving averages according to their trading style.

Fast EMA

Common values:
  • 9 EMA
  • 10 EMA
  • 20 EMA
  • 21 EMA

Slow EMA

Common values:
  • 50 EMA
  • 100 EMA
  • 200 EMA

Aggressive Setup

  • Fast EMA: 9
  • Slow EMA: 21
Suitable for:
  • Scalping
  • Intraday Trading

Balanced Setup

  • Fast EMA: 20
  • Slow EMA: 50
Suitable for:
  • Swing Trading
  • Trend Following

Conservative Setup

  • Fast EMA: 50
  • Slow EMA: 200
Suitable for:
  • Positional Trading
  • Long-Term Trend Identification

Profit Target Management

The strategy supports two independent profit targets.

Target 1 (T1)

Can be configured in:
  • Percentage (%)
  • Points
Examples:
  • 1%
  • 2%
  • 100 Points

Target 2 (T2)

Can be configured independently in:
  • Percentage (%)
  • Points
Examples:
  • 3%
  • 5%
  • 300 Points
This allows traders to book partial profits while keeping the remaining position open for larger market moves.

Stop Loss Management

The strategy includes flexible Stop Loss options.

Percentage-Based Stop Loss

Examples:
  • 1%
  • 2%
  • 3%

Point-Based Stop Loss

Examples:
  • 50 Points
  • 100 Points
  • 200 Points
Mirrorpip automatically exits the position if the stop loss level is reached.

Trailing Stop Loss (TSL)

The strategy includes a Trailing Stop Loss feature to protect profits during trending markets.

TSL Options

Users can configure:
  • Percentage-Based TSL
  • Point-Based TSL
Benefits:
  • Protects unrealized profits.
  • Allows winners to run.
  • Reduces the impact of sudden reversals.

Intraday and Positional Trading Modes

Intraday Mode

Best suited for:
  • Indian Stock Markets
  • Index Trading
  • Futures & Options
Recommended Timeframes:
  • 5 Minute
  • 15 Minute
  • 30 Minute

Positional Mode

Best suited for:
  • Cryptocurrency Markets
  • Forex Markets
  • International Indices
Recommended Timeframes:
  • 1 Hour
  • 4 Hour
  • Daily

Fully Automated with Mirrorpip

The strategy comes with pre-built Mirrorpip automation code.

Setup Process

  1. Add the strategy to your TradingView chart.
  2. Select Fast EMA and Slow EMA values.
  3. Configure Targets, Stop Loss, and Trailing Stop Loss.
  4. Create a TradingView Alert.
  5. Connect the alert with Mirrorpip.
  6. Mirrorpip automatically executes trades on your connected exchange account.
No manual intervention is required after setup.

Supported Exchanges

Mirrorpip supports automated execution on multiple exchanges, including:
  • Bybit
  • Binance
  • Delta Exchange
  • CoinSwitch
  • OKX
  • Bitget
  • Gate.io
  • KuCoin
  • Shark Exchange
and many more.

Advantages of EMA Crossover Strategy

  • Simple and easy to understand.
  • Works across multiple markets.
  • Suitable for beginners and experienced traders.
  • Identifies major trend changes.
  • Fully automatable using Mirrorpip.
  • Requires minimal chart analysis.

Limitations

Like all trend-following systems, EMA crossover strategies can generate false signals during sideways or highly choppy markets. To improve performance, traders often:
  • Use higher timeframes.
  • Combine with volume confirmation.
  • Use trend filters.
  • Apply proper risk management.

Risk Disclaimer

Trading involves risk and no strategy guarantees profits. Always:
  • Use appropriate position sizing.
  • Configure stop losses.
  • Test settings before live deployment.
  • Monitor exchange and TradingView connectivity regularly.

Conclusion

The Basic EMA Crossover Strategy is a powerful and beginner-friendly trend-following system that helps traders capture directional market moves. With customizable EMA periods, dual profit targets, stop loss, trailing stop loss, and built-in Mirrorpip integration, traders can fully automate their trading workflow across stocks, futures, forex, and cryptocurrency markets.