Strooths Candle Indicator

stable
By Strooth in Other Published May 2021 👁 1,367 views 💬 0 comments

Description

Scans price chart for defined list of known bullish/bearish candle patterns and their directions. The patterns were found on http://thepatternsite.com/patternz.html and I adapted as best I could. This will scan for up/down breakout, reversal/continuation and based on the long/short weight it will signal the heavier side. You can adjust the weights and penetration to suit and enable the plotting if you would like. The amount of iteration this command does unfortunately makes it quite slow. I'm not sure if there is anything that can be done to speed up my code but all ears if someone knows the answer. As they say, best used on longer time frames as you will get lots of false positives on short ones. There is one issue that I believe exists - if it detects more than one pattern at the same candle the last found pattern will be the one plotted as it overwrites the previous plot data afaik. Based on the weighting this should not affect the signal however. You can just call it like so local signal = CC_StroothCDL() Or specify the settings to fine tune a little more if you like local signal = CC_StroothCDL(1, CurrentInterval(), {OpenPrices(), HighPrices(), LowPrices(), ClosePrices()}, 3, 3, 4, false, false, false)
HaasScript
-- author - Find me on discord - strooth#4739

-- Define command
DefineCommand("StroothsCDLIndicator", "Strooths Custom CDL Pattern finding signal indicator")

-- Define command parameters.
local penetration = DefineParameter(NumberType, 'penetration', 'the penetration level before pattern is vaalid', false, 1, 'Number,InputInterval')
local interval = DefineParameter(NumberType, 'interval', 'Used interval for price data. Default is 0 and the main interval will be used.', false, 0, 'Number,InputInterval')
local source = DefineParameter(ListDynamicType, 'source', 'Price Source {OpenPrices(),HighPrices(),LowPrices(),ClosePrices()}.', false, {OpenPrices(interval),HighPrices(interval),LowPrices(interval),ClosePrices(interval)}, '{CurrentPrice(),OpenPrices(),HighPrices(),LowPrices(),ClosePrices()}')
local shortweight = DefineParameter(NumberType, 'shortweight', 'the consensus weight threshold of each signal.', false, 3, 'Number,InputInterval')
local longweight = DefineParameter(NumberType, 'longweight', 'the consensus weight threshold of each signal.', false, 3, 'Number,InputInterval')
local noneweight = DefineParameter(NumberType, 'noneweight', 'the consensus weight threshold of each signal.', false, 4, 'Number,InputInterval')
local useother = DefineParameter(BooleanType, 'other', 'check other uncommon patterns', false, false, 'true,false')
local plotall = DefineParameter(BooleanType, 'plotall', 'plot and mark each signal', false, true, 'true,false')
local plotfinal = DefineParameter(BooleanType, 'plotfinal', 'plot and mark only the final signal', false, false, 'true,false')
local log = DefineParameter(BooleanType, 'log', 'log each signal', false, false, 'true,false')

DefineIntervalOptimization(interval)

-- Enums
local upbreakout = {
bearish = {ThreeLineStrikeType},
normal = {TasukiGapType, MorningDojiStarType, MorningStarType, PiercingType, ThreeInsideType, ThrustingType, TasukiGapType}
}
local upcontinuation = {
bearish = {DojiStarType},
bullish  = {SeperatingLinesType},
normal = {AdvanceBlockType, StalledPatternType, EngulfingType, MatHoldType, RiseFallThreeMethodsType, ShootingStarType, GapSideSideWhiteType, UpsideGapTwoCrowsType}
}
local upreversals = {
bearish =  {ThreeLineStrikeType},
bullish  = {AbandonedBabyType, BeltHoldType, ThreeOutsideType},
normal =  {MorningDojiStarType, MorningStarType, TakuriType, ThreeStarsInSouthType, ThreeWhiteSoldiersType}
}
local downbreakout = {
bearish = {BreakawayType},
bullish  = {ThreeLineStrikeType},
normal = {EveningStarType,InvertedHammerType,InNeckType,MatchingLowType,StickSandwhichType,ThreeBlackCrowsType}
}
local downcontinuations = {
bearish = {SeperatingLinesType},
bullish  = {DojiStarType},
normal = {ConcealBabysWallType, RiseFallThreeMethodsType, InvertedHammerType, EngulfingType, MatchingLowType, StickSandwhichType, UniqueThreeRiverType}
}
local downreversals = { 
bearish = {AbandonedBabyType, BeltHoldType, BreakawayType, EngulfingType, ThreeOutsideType },
bullish  = {ThreeLineStrikeType },
normal = {EveningDojiStarType,EveningStarType,IdenticalThreeCrowsType,ThreeBlackCrowsType}
}
local otherpatterns = { AdvanceBlockType, ClosingMarubozuType, CounterAttackType, DarkCloudCoverType, DragonflyDojiType, GravestoneDojiType, HammerType, HangingManType, HaramiCrossType, HaramiType, HignWaveType, HikkakeModType, HikkakeType, HomingPigeonType, KickingByLengthType, KickingType, LadderBottomType, LongLeggedDojiType, LongLineType, MarubozuType, RickshawManType, RiseFallThreeMethodsType, ShortLineType, SimpleDoubleDownCandleType, SimpleDoubleUpCandleType, SimpleDownCandleType, SimpleUpCandleType, SpinningTopType, TristarType, TwoCrowsType, XSideGapThreeMethodsType,
}

-- Variables
local stally,ltally,text = {},{}
local op,hp,lp,clp=source[1],source[2],source[3],source[4],source[5]
local signal,clsignal,colsignal,cossignal,csrsignal,cscsignal,csbsignal,clcsignal,clrsignal,clbsignal = SignalNone,SignalNone,SignalNone,SignalNone,SignalNone,SignalNone,SignalNone,SignalNone,SignalNone,SignalNone

-- Calculate direction
local sum = function(i, o, l)
    local output = ArraySum(Grab(i, o, l))
    if IsSmallerThan(output, 0) then 
        output = output * -1
        end
    output = output / 100
    if output == l then return true else return false end
end 

-- Check for patterns function
local check = function(patterns, interval, bearish, bullish, nolog)
    local output 
    local lindex = 0
    local sindex = 0
    local sp 
    local both = false 
    if bullish and bearish then 
        both = true 
    end 
for i=1, #patterns do 
        local result = CDL(op, hp, lp, clp, patterns[i], penetration)
        result = Grab(result, 1, 1)
        result = Parse(result, NumberType)
        if IsNotNull(result) and IsSmallerThan(result,  0) then 
            if both or bearish then 
                sindex = sindex + 1
                stally[sindex] = result
                if not nolog and plotall then 
                local text = Parse(patterns[i], StringType)
                PlotShape(0, ShapeTriangleDown, Red, 10, true, text, White)
                MarkCandle(0, 1)
                end 
            end 
        end
    if IsNotNull(result) and IsBiggerThan(result, 0) then 
        if both or bullish then 
        lindex = lindex + 1
        ltally[lindex] = result
        if not nolog and plotall then 
        local text = Parse(patterns[i], StringType)
        PlotShape(0, ShapeTriangleUp, Green, 10, false, text, White)
        MarkCandle(0, 1)
        end 
        end 
    end 
end 
if both or bearish then 
    if IsNotNull(ArraySum(stally)) then 
        sp =  ArraySum(stally) * -1
    end 
end 
if both then 
     if IsNotNull(sp) and IsNotNull(ArraySum(ltally)) then 
        if IsBiggerThan(sp, ArraySum(ltally)) then 
            local weight = sp 
            output = SignalWeight(SignalShort, weight) 
        end 
        if IsBiggerThan(ArraySum(ltally), sp) then 
            local weight = ArraySum(ltally) / 100
            output = SignalWeight(SignalLong, weight) 
        end 
    end 
elseif bullish then 
    if IsNotNull(ArraySum(ltally)) then 
        if IsBiggerThan(ArraySum(ltally), 1) then 
            local weight = ArraySum(ltally) 
        output = SignalWeight(SignalLong, weight) 
        end 
    end 
elseif bearish then 
    if IsNotNull(ArraySum(stally)) then 
        if IsSmallerThan(ArraySum(stally), 0) then 
            local weight = sp 
            output = SignalWeight(SignalShort, weight) 
        end 
    end 
else 
    output = SignalWeight(SignalNone, 1) 
end
if IsNull(output) then output = SignalWeight(SignalNone, 1) end 
return output 
end 

-- Run pattern checks and generate signals
clbsignal = SignalWeight(GetWeightedConsensusSignal(7,7,7, check(upbreakout.bearish, interval, true, false),check(upbreakout.normal, interval, true, true)), 3)
csbsignal = SignalWeight(GetWeightedConsensusSignal(7,7,7, check(upreversals.bearish, interval, true, false),check(upreversals.bullish, interval, false, true),check(upreversals.normal, interval, true, true)), 3)
clrsignal = SignalWeight(GetWeightedConsensusSignal(8,8,8, check(upcontinuation.bearish, interval, true, false),check(upcontinuation.bullish, interval, false, true),check(upcontinuation.normal, interval, true, true)), 4)
csrsignal = SignalWeight(GetWeightedConsensusSignal(7,7,7, check(downbreakout.bearish, interval, true, false),check(downbreakout.bullish, interval, false, true),check(downbreakout.normal, interval, true, true)), 4)
cscsignal = SignalWeight(GetWeightedConsensusSignal(7,7,7, check(downreversals.bearish, interval, true, false),check(downreversals.bullish, interval, false, true),check(downreversals.normal, interval, true, true)), 2)
clcsignal = SignalWeight(GetWeightedConsensusSignal(8,8,8, check(downcontinuations.bearish, interval, true, false),check(downcontinuations.bullish, interval, false, true),check(downcontinuations.normal, interval, true, true)), 2)
if useother then cossignal = SignalWeight(GetWeightedConsensusSignal(9,9,9, check(otherpatterns, interval, true, false, false),check(otherpatterns, interval, false, true, false),check(otherpatterns, interval, true, true, false)), 1) end 

-- log signals 
if log then 
    local allsignals = {UpBreakout = clbsignal, UpReversals = csbsignal, UpContinuation = clrsignal, DownBreakout = csrsignal, DownReversals = cscsignal, DownContinuations = clcsignal, OtherPattern = cossignal}
    for type,sig in pairs(allsignals) do 
        if sig != SignalNone then 
            LogWarning(type..' = '..Parse(sig, StringType))
        end 
    end 
end 

-- get final signal 
signal = GetWeightedConsensusSignal(longweight,shortweight,noneweight, clbsignal,clrsignal,csbsignal,csrsignal,cscsignal,clcsignal,cossignal) 

-- plot final signal 
if plotfinal then 
    if signal != SignalNone then 
        local p = IfElse(signal==SignalLong,{shape=ShapeTriangleUp,color=Green,ab=false,text='GoLong'},{shape=ShapeTriangleDown,color=Red,ab= true,text='GoShort'})
        PlotShape(0, p.shape, p.color, 5, p.ab, p.text, White)
        MarkCandle(0, 1)
    end 
end 


-- log final signal
if log then
    if signal != SignalNone then 
        local weights = {LongWeight = longweight, ShortWeight = shortweight, NoneWeight = noneweight}
        for type,weight in pairs(weights) do 
            LogWarning(type..' = '..weight)
        end 
        LogWarning('Final Weighted Signal = '..Parse(signal, StringType))
    end 
end 

-- Create output 
local output = {}
output.Signal = signal
output.Upbreakout = clbsignal
output.Downbreakout = csbsignal
output.Upreversal = clrsignal
output.Downreversal = csrsignal
output.Downcontinue = cscsignal
output.Upcontinue = clcsignal
output.Other = cossignal

--Return the custom signal.
DefineOutput(ListDynamicType, output , 'Signal result', 'TradeBotContainer, IndicatorContainer, Signal Helpers')
DefineOutputIndex(1, EnumType, 'Signal', 'main signal', 'signallong,signalshort')
DefineOutputIndex(2, EnumType, 'Upbreakout', 'upbreakout', 'signallong,signalshort')
DefineOutputIndex(3, EnumType, 'Downbreakout', 'downbreakout', 'signallong,signalshort')
DefineOutputIndex(4, EnumType, 'Upreversal', 'upreversal', 'signallong,signalshort')
DefineOutputIndex(5, EnumType, 'Downreversal', 'downreversal', 'signallong,signalshort')
DefineOutputIndex(6, EnumType, 'Downcontinue', 'downcontinue', 'signallong,signalshort')
DefineOutputIndex(7, EnumType, 'Upcontinue', 'upcontinue', 'signallong,signalshort')
DefineOutputIndex(8, EnumType, 'Other', 'other', 'signallong,signalshort')

0 Comments

Sign in to leave a comment.

No comments yet. Be the first!