SuperTrend for some reason is unsymmetrical. You can ignore my suggested code and nonsense posts below, I was looking at wrong version of supertrend. I've attached my unsymmetrical strategy that should be symmetrical. It didn't become symmetrical until I removed supertrend.
According to: https://www.prorealcode.com/prorealtime-indicators/supertrend/
//This indicator contains functions that can only be used with ProRealTime v10.3 and above.<br />
//If you use a previous version of ProRealTime, use the other version of the Indicators.
multiplier=3
period=10
moy=averagetruerange[period](close)
price=medianprice
up=price+multiplier*moy
dn=price-multiplier*moy
once trend=1
if close>up[1] then
trend=1
elsif close<dn[1] then
trend=-1
endif
if trend<0 and trend[1]>0 then
flag=1
else
flag=0
endif
if trend>0 and trend[1]<0 then
flagh=1
else
flagh=0
endif
if trend>0 and dn<dn[1] then
dn=dn[1]
endif
if trend<0 and up>up[1] then
up=up[1]
endif
if flag=1 then
up=price+multiplier*moy
endif
if flagh=1 then
dn=price-multiplier*moy
endif
if trend=1 then
mysupertrend=dn
else
mysupertrend=up
endif
if mysupertrend > mysupertrend[1] then
color1=0
color2=255
color3=0
elsif mysupertrend < mysupertrend[1] then
color1=255
color2=0
color3=0
endif
return mysupertrend coloured (color1,color2,color3) as "SuperTrend"
Or maybe something like this was the original plan but i'm not sure if the snippet will handle "mode" properly yet....
LongEntrySignal = SuperTrend(Main chart,1, SuperTrendATRPeriod,8.4)[3] is falling; ShortEntrySignal = SuperTrend(Main chart,2, SuperTrendATRPeriod,8.4)[3] is rising;
if(Input.Close.get(0) > Value.get(1) && Input.Close.get(1) <=Value.get(1)){ Value.set(0, dLowerLevel); } else if(Input.Close.get(0) < Value.get(1) && Input.Close.get(1) >=Value.get(1)){ Value.set(0, dUpperLevel); } else if(Value.get(1)<dLowerLevel){ Value.set(0, dLowerLevel); } else if(Value.get(1)>dUpperLevel){ Value.set(0, dUpperLevel); } else Value.set(0, Value.get(1));
package SQ.Blocks.Indicators.SuperTrend; import com.strategyquant.lib.*; import com.strategyquant.datalib.*; import com.strategyquant.tradinglib.*; import SQ.Internal.IndicatorBlock; import SQ.Blocks.Indicators.MTATR.MTATR; import SQ.Blocks.Indicators.ATR.ATR; import com.strategyquant.tradinglib.simulator.Engines; @BuildingBlock(name="(ST) SuperTrendClone", display="SuperTrend(#Mode#,#ATRPeriod#,#ATRMult#)[#Shift#]", returnType = ReturnTypes.Price) @Help("SuperTrend help text") @ParameterSet(set="ATRPeriod=12") @ParameterSet(set="ATRPeriod=24") @ParameterSet(set="ATRPeriod=48") @ParameterSet(set="ATRPeriod=120") @ParameterSet(set="ATRPeriod=480") @ParameterSet(set="ATRPeriod=10") @ParameterSet(set="ATRPeriod=20") @ParameterSet(set="ATRPeriod=40") @ParameterSet(set="ATRPeriod=100") @ParameterSet(set="ATRPeriod=500") public class SuperTrendClone extends IndicatorBlock { @Parameter public ChartData Input; @Parameter(defaultValue="1") @Editor(type=Editors.Selection, values="Upper=1,Lower=2") public int Mode; @Parameter(defaultValue="24", isPeriod=true, minValue=2, maxValue=240, step=1) public int ATRPeriod; @Parameter(defaultValue="3", isPeriod=true, minValue=-2, maxValue=10, step=0.1) public double ATRMult; @Output public DataSeries Value; //------------------------------------------------------------------------ //------------------------------------------------------------------------ //------------------------------------------------------------------------ @Override protected void OnBarUpdate() throws TradingException { if(Engines.isTradestationEngine(Indicators.Engine)) { onBarUpdateTS(); } else { onBarUpdateMT(); } } protected void onBarUpdateMT() throws TradingException { // MT4/5 ATR MTATR indicator = Indicators.MTATR(Input, ATRPeriod); double atrValue = indicator.Value.getRounded(0); double dUpperLevel = (Input.High.get(0)+Input.Low.get(0))/2 + ATRMult*atrValue; double dLowerLevel = (Input.High.get(0)+Input.Low.get(0))/2 - ATRMult*atrValue; if (Mode==1) Value.set(0,dUpperLevel); else if (Mode==2) Value.set(0,dLowerLevel); } protected void onBarUpdateTS() throws TradingException { //// TS ATR ATR indicator = Indicators.ATR(Input, ATRPeriod); double atrValue = indicator.Value.getRounded(0); double dUpperLevel = (Input.High.get(0)+Input.Low.get(0))/2 + ATRMult*atrValue; double dLowerLevel = (Input.High.get(0)+Input.Low.get(0))/2 - ATRMult*atrValue; if (Mode==1) Value.set(0,dUpperLevel); else if (Mode==2) Value.set(0,dLowerLevel); } }
Attachment Strategy 19185941.sqx added
Attachment image-0.png added
Attachment image-1.png added
I've triple-checked the strategy. The ATR multiplier cannot be negative. Still, even if it is negative, I see short trades. If I make the right adjustments, the result is symmetrical.