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!