Here is a pretty good script i've been working on - it works as is. I frankly think anyone could trade it. Though, I would like a professional to assist with a few things. At some point I'll finish it without assistance, however, since my scripting skills consistent of trying everything until it works, it may be sometime until it's complete.
I would like to:
1. Shorten plot logic: I created a custom switch (without using a switch function), but it surely could be shortened to resemble something like SAR or ATR trailing stop logic.
2. Breakout signals: While they work quite well, it some instances it fires late. I don't want to change the current breakout signals as they keep the box intact with false breakout signals, so something added which does the same is important.
3. Box Repainting while trade is active. This could be solved with 1 above. This is the main priority. if anyone could do this, I can figure the rest out.
thanks, mcdon
Code:
### Name: Mcdon030_Compression Box Breakout _Version 1
## date: V1 1/9/2020
## signals from: Mobius Expansion Contraction Indicator (ECI):https://tos.mx/p8PbL4
## Notes:
## 1. Attempt at painting a box around fractal energy signals
## 2. Basic trade logic has inputs for full box range, mid range or input range multipler after breakout. Mobius suggested midrange i believe
## 3. Multiple attempts for better breakout signals. see below line 70
## inputs:
## 1. length2 always egreater than length1 - box finds previous highest and lowest from signal back as far as length2
## 2. stdev input yes to add stdev levels to breakout
input length1 = 11;
input length2 =15;
input Compresslength = 2; ##
input mult = .04;
input Compress = .7;
input projectmult =.618;
input breakSD =yes;
input ShowLabels=yes;
input Showtrade=yes;
########################################## signal assist
def bn = BarNumber();
def bodyHeight = BodyHeight();
def IsUp = close > open;
def IsDown = close < open;
def LowVol = volume < Average(volume, 50);
def buybody = bodyHeight > Average(bodyHeight, length1);
script p {
input data = close;
input Length = 20;
def w = (2 * Double.Pi / (Length / 2));
def beta = (1 - Cos(w)) / (Power(1.414, 2.0 / Length) - 1);
def alpha = (-beta + Sqrt(beta * beta + 2 * beta));
def a = Power(alpha, 4) * data + 4 * (1 - alpha) * a[1] - 6 * Power(1 - alpha, 2) * a[2] + 4 * Power(1 - alpha, 3) * a[3] - Power(1 - alpha, 4) * a[4];
plot line = a;
}
def o = p(open, Length = Length1);
def l = p(low, Length = Length1);
def h = p(high, Length = Length1);
def c = p(close, Length = Length1);
def bar = BarNumber();
def HMax = Highest(Max(h, c[1]), Length1);
def LMax = Lowest(Min(l, c[1]), Length1);
def TR = Max(h, c[1]) - Min(l, c[1]);
def R = Highest(h, Length1) - Lowest(l, Length1);
def F = Log(Sum(TR, Length1) / R) / Log(Length1);
def FE =(Log(Sum(Max(high, close[1]) - Min(low, close[1]), Length1) / (Highest(high, Length1) - Lowest(low, Length1))) / Log(Length1));
def consolidation = if F crosses above Compress then close else if f> Compress then close else double.nan;
script ff {
input v1 = 0.0 ;
input v2 = 0.0;
def bn = BarNumber();
def lbar = HighestAll(if IsNaN(close) then 0 else bn);
def va1 = fold id = 1 to lbar with t = 0 while t == 0 do if GetValue(v1, -id) then id else 0;
plot for = GetValue(v2, -va1);
}
########################################## box values
def consave = !isnan(consolidation) and sum(!isnan(consolidation),Compresslength )>=Compresslength ;
def con_ = if IsNaN(consave) then 0 else consave;
def start = bn == ff(con_, bn) - length2;
def start_ = if IsNaN(start) then 0 else start;
def startcnt = if start_ then 1 else startcnt[1] + 1;
def startbn = if start then bn else startbn [1];
def endbn = if con_ then bn else endbn [1];
def gethigh = if con_ then Highest(high, length2) else gethigh[1];
def getlow = if con_ then Lowest(low, length2) else getlow[1];
def getstdev = if con_ then StDev(close, length2) else getstdev[1];
def getSVSD = (Highest(getstdev, length2) + Lowest(getstdev, length2)) / 2;
def highend = CompoundValue(1, if start_ then ff(con_,gethigh) else highend[1], high);
def lowend = CompoundValue(1, if start_ then ff(con_, getlow) else lowend[1], low);
def stdevend = CompoundValue(1, if start_ then ff(con_, getSVSD) else stdevend [1], 1);
########################################## breakout from highest high and lowest low or add standard deviation
def highend_ = if breakSD==no then highend else highend+stdevend ;
def lowend_ = if breakSD==no then lowend else lowend-stdevend ;
def stopH1 = buybody and low> highend_ ;
def stopL1 = buybody and high < lowend_;
def stopH2 = low> highend_ and high[1]<=highend_;
def stopL2 = high <lowend_ and low[1]>=lowend_; ;
########################################## limit break signals
def stopHL2lmt = if stopH2 then stopHL2lmt[1] + 1 else if stopL2 then stopHL2lmt[1] + 1 else stopHL2lmt[1];
def stoph = stopHL2lmt[1] >= 2 and stopH2 or stopH1;
def stopH_ = if IsNaN(stoph) then 0 else stoph;
def stopl = stopHL2lmt[1] >= 2 and stopL2 or stopL1;
def stopL_ = if IsNaN(stopl) then 0 else stopl;
def stopHL = stopH2 or stopL2 or stopH1 or stopL1;
def stopHL_ = if IsNaN(stopHL) then 0 else stopHL;
### limit future signals below 1
def stopHLofst = CompoundValue(1, if start_ then 0 else if stopHL_ then 1 else stopHLofst[1], 0);
def stopHLofst_ = stopHLofst and !stopHLofst[1];
def activextend = CompoundValue(1, if start_ then 1 else if stopHLofst_ then 0 else activextend[1], 0);
def breakout = ! activextend and activextend[1];
########################################## color
DefineGlobalColor("range", CreateColor(50, 80, 140));
DefineGlobalColor("range SD", CreateColor(100, 180, 160));
########################################## plot
plot dotss = consolidation;
dotss.SetPaintingStrategy(PaintingStrategy.POINTS);
dotss.SetLineWeight(1);
dotss.SetDefaultColor(Color.Yellow);
plot rangehigh = if activextend then highend else Double.NaN;
rangehigh.SetLineWeight(2);
rangehigh.SetDefaultColor(Color.CYAN);
rangehigh.SetStyle(curve.Long_DASH);
plot rangelow = if activextend then lowend else Double.NaN;
rangelow.SetLineWeight(2);
rangelow.SetDefaultColor(Color.CYAN);
rangelow.SetStyle(curve.Long_DASH);
plot rangehighSD = if activextend && breakSD then highend +stdevend else Double.NaN;
rangehighSD.SetLineWeight(1);
rangehighSD .SetDefaultColor(Color.CYAN);
rangehighSD.SetPaintingStrategy(paintingStrategy.POINTS);
plot rangelowSD = if activextend && breakSD then lowend-stdevend else Double.NaN;
rangelowSD.SetLineWeight(1);
rangelowSD.SetDefaultColor(Color.CYAN);
rangelowSD.SetPaintingStrategy(PaintingStrategy.points);
########################################## clouds
AddCloud(rangehigh, rangelow, globalcolor("range"));
AddCloud(rangehighsd, rangehigh,globalcolor("range SD"));
AddCloud(rangelow, rangelowsd, globalcolor("range SD"));
###################################################################################################################################
#################################################################### trade #######################################################
###################################################################################################################################
def range = highend_ - lowend_;
def mdrange = (highend_ - lowend_)/2;
def raTargmult = (highend_ - lowend_) * projectmult ;
### create exit logic
def activetrade = !activextend && activextend[1] or !IsNaN(activextend[1]) and IsNaN(activextend) ;
### limit future signals below 2
def cntafterLmt = CompoundValue(1, if activetrade then 1 else if cntafterLmt[1] >= 1 and startcnt == 1 and startcnt[1] > 5 then cntafterLmt[1] else cntafterLmt[1] + 1, 1);
## limit entry and exit signals
def findlmt = if activextend[1] and stopH_ then 1 else if activextend[1] and stopL_ then 2 else if activextend[1] and !stopL_ and !stopH_ then double.nan else findlmt[1];
########################################## input targets
def targetswh;
def targetswl;
input projecttarget = { default fullRange, midRange, multRange};
switch (projecttarget ) {
case fullRange:
targetswh = highend_ + range ;
targetswl = lowend_ - range;
case midRange:
targetswh = highend_ + mdrange ;
targetswl = lowend_ - mdrange;
case multRange:
targetswh = highend_ + raTargmult ;
targetswl = lowend_ - raTargmult;
}
### projected targets
def trstopH1a = findlmt == 1 && high>targetswh ;
def trstopL1a = findlmt == 2 && low<targetswl;
def trstopH1b = if IsNaN(trstopH1a) then 0 else trstopH1a;
def trstopl1b = if IsNaN(trstopL1a) then 0 else trstopL1a;
def trstopH1c = if trstopH1b then 1 else trstopH1c [1] + 1;
def trstopl1c = if trstopl1b then 1 else trstopl1c [1] + 1;
def tradestoph = CompoundValue(1, if cntafterLmt>= 1 then lowend_ else tradestoph[1], 1);
def tradestopl = CompoundValue(1, if cntafterLmt>= 1 then highend_ else tradestopl[1], 1);
def trstopH2a = findlmt==1 && low < tradestoph;
def trstopl2a = findlmt==2 && high > tradestopl ;
def trstopH2b = if IsNaN(trstopH2a) then 0 else trstopH2a;
def trstopL2b = if IsNaN(trstopl2a) then 0 else trstopl2a;
def trstopH2c = if trstopH2b then 1 else trstopH2c[1] + 1;
def trstopL2c = if trstopL2b then 1 else trstopL2c[1] + 1;
def trstopHL = (trstopH1c >= 1 && trstopH1b or trstopH2c >= 1 && trstopH2b) or (trstopl1c >= 1 && trstopl1b or trstopL2c >= 1 && trstopL2b );
def trstopHL_ = if IsNaN(trstopHL ) then 0 else trstopHL ;
def activetrade_ = CompoundValue(1, if activetrade then 1 else if trstopHL_[1] then 0 else activetrade_[1], 0);
### switch targetswh to plot
def switch1 = CompoundValue(1, if findlmt== 1 && cntafterLmt== 1 then targetswh else if findlmt== 2 && cntafterLmt== 1 then targetswl else switch1[1], double.nan);
def switch2 = CompoundValue(1, if findlmt==1 && cntafterLmt== 1 then highend_ else if findlmt==2 && cntafterLmt== 1 then lowend_ else switch2[1], double.nan);
def tradestop = CompoundValue(1, if findlmt==1 && cntafterLmt==1 then lowend_ else if findlmt==2 && cntafterLmt==1 then highend_ else tradestop[1], 1);
def activeswitch = CompoundValue(1, if bn == 1 or Showtrade==no then double.nan else if activetrade_ then 1 else if trstopHL_[1] then 0 else activeswitch[1], double.nan);
def bueEn = !activextend and activextend[1];
def bueEx = !activeswitch and activeswitch[1];
plot rangeswitch2 = if activeswitch then switch2 else Double.NaN;
rangeswitch2.SetLineWeight(2);
rangeswitch2.SetDefaultColor(Color.LIGHT_RED);
rangeswitch2.SetStyle(curve.Long_DASH);
plot rangeswitch1= if activeswitch then switch1 else Double.NaN;
rangeswitch1.SetLineWeight(2);
rangeswitch1.SetDefaultColor(Color.green);
rangeswitch1.SetStyle(curve.Long_DASH);
AddCloud(rangeswitch1, rangeswitch2,globalcolor("range"));
plot projectedstop = if activeswitch then tradestop else Double.NaN;
projectedstop.SetLineWeight(2);
projectedstop.SetDefaultColor(Color.light_RED);
projectedstop.SetStyle(curve.Long_DASH);
###### signals
plot bullEntry = findlmt==1 && bueEn ;
bullEntry.SetDefaultColor(Color.GREEN);
bullEntry.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
bullEntry.SetLineWeight(2);
plot bearEntry = findlmt==2 && bueEn ;
bearEntry.SetDefaultColor(Color.GREEN);
bearEntry.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
bearEntry.SetLineWeight(2);
plot bullExit = findlmt==1 && bueEx ;
bullExit.SetDefaultColor(Color.red);
bullExit.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
bullExit.SetLineWeight(2);
plot bearExit = findlmt==2 && bueEx ;
bearExit.SetDefaultColor(Color.RED);
bearExit.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
bearExit.SetLineWeight(2);
########################################## labels
def conscnt = CompoundValue(1, if !isnan(consolidation) then conscnt[1]+1 else 1, 1);
def cntuntil = if !isnan(consolidation) then Compresslength -conscnt[1] else double.nan;
AddLabel( ShowLabels,
" Inputs "+
" Length One: (" + Length1 +
") Length Two: (" + Length2 +")"+
") Compression Length : (" + Compresslength +")"+
") Compress Value : (" + Compress +")"+
" StDev : " +( if breakSD then "Yes" else "No")
, Color.WHITE );
AddLabel(Showtrade,
if activextend
then " High Break at: " +highend_ + " low Break at: "+ lowend_
else if !isnan(consolidation)
then "Forming Pattern In = " +conscnt + " Gauss FE = " + F + " Normal FE " + FE
else if activeswitch
then " Target at: " +switch2 + " Target at: "+ switch1
else "No Pattern Forming : Gauss FE = " + F + " Normal FE " + FE
, if activextend or activeswitch
then color.green
else color.light_Green);
########################################## alerts
alert(consave , "Consolidation Pattern", alert.bar, sound.Ring);
alert(breakout, "Breakout", alert.bar, sound.Ring);
Last edited by a moderator: