function Init() indicator:name("DMRB Candles Paint"); indicator:description("DMRB Candles Paint"); indicator:requiredSource(core.Bar); indicator:type(core.Indicator); indicator.parameters:addGroup("Stratégie DMRB"); indicator.parameters:addBoolean("bDMRB", "Activer stratégie DMRB", "", true); indicator.parameters:addColor("UPclr", "Signal DMRB haussier", "", core.COLOR_UPCANDLE); indicator.parameters:addColor("DNclr", "Signal DMRB baissier", "", core.COLOR_DOWNCANDLE); indicator.parameters:addColor("clr1", "Signal DMRB mais potentiel de RR < 2", "", core.rgb(204, 204, 204)); indicator.parameters:addColor("IDLEclr", "Couleur bougies idle", "", core.rgb(62, 62, 62)); indicator.parameters:addGroup("Paramètres Ichimoku"); indicator.parameters:addInteger("T", "Tenkan Period", "Tenkan Period", 9); indicator.parameters:addInteger("K", "Kijun Period", "Kijun Period", 26); indicator.parameters:addInteger("S", "Senkou Period", "Senkou Period", 52); indicator.parameters:addString("Period", "Timeframe", "", "m1"); indicator.parameters:setFlag("Period", core.FLAG_PERIODS); indicator.parameters:addGroup("Paramètres DMRB"); indicator.parameters:addBoolean("bPivot", "Prise en compte du pivot journalier", "", true); indicator.parameters:addGroup("Alerting"); indicator.parameters:addFile("SoundFile", "Fichier son à jouer", "", ""); indicator.parameters:setFlag("SoundFile", core.FLAG_SOUND); indicator.parameters:addBoolean("RecurrentSound", "Son récurrent", "", false); end local source; local name; local open=nil; local close=nil; local high=nil; local low=nil; local first; local Tenkan; local Kijun; local Senkou; local firstICH={}; local ICH; local bPivot; local Pivot; local instrument; function Prepare(nameOnly) source = instance.source; first=source:first(); name = "DMRB Candles Paint"; instance:name(name); if nameOnly then return end Colors=instance:addInternalStream(first, 0); open = instance:addStream("open", core.Line, name, "open", core.COLOR_UPCANDLE, first) high = instance:addStream("high", core.Line, name, "high", core.COLOR_UPCANDLE, first) low = instance:addStream("low", core.Line, name, "low", core.COLOR_UPCANDLE, first) close = instance:addStream("close", core.Line, name, "close", core.COLOR_UPCANDLE, first) instance:createCandleGroup("PaintCandles", "", open, high, low, close); Tenkan = instance.parameters.T; Kijun = instance.parameters.K; Senkou = instance.parameters.S; ICH = core.indicators:create("ICH", source, Tenkan, Kijun, Senkou); firstICH["SL"]=ICH.SL:first(); firstICH["TL"]=ICH.TL:first(); firstICH["SA"]=ICH.SA:first(); firstICH["CS"]=ICH.SA:first(); firstICH["SB"]=ICH.SB:first(); firstICH["PRICE"]=source:first(); pivot = core.indicators:create("PIVOT", source, "D1", "Pivot", "HIST"); bPivot = instance.parameters.bPivot; instrument = instance.source:instrument(); end -- Sens de la bougie -- retourne up (haussière), down (baissière) ou none (doji) function sensBougie(period) if source.open[period] == source.close[period] then return "none"; elseif source.open[period] < source.close[period] then return "up"; elseif source.open[period] > source.close[period] then return "down"; end end -- Sens du kumo -- retourne up ou down function kumoDirection(period) if ICH.SA[period] > ICH.SB [period]then return "up"; elseif ICH.SA[period] < ICH.SB [period]then return "down"; end end -- Prix par rapport au kumo -- retourne up ou down function prixKumo(period) if source.open[period] > ICH.SA[period] and source.open[period] > ICH.SB[period] and source.close[period] > ICH.SA[period] and source.close[period] > ICH.SB[period] then return "up"; elseif source.open[period] < ICH.SA[period] and source.open[period] < ICH.SB[period] and source.close[period] < ICH.SA[period] and source.close[period] < ICH.SB[period] then return "down"; end end -- Prix par rapport au Pivot journalier -- retourne up (au dessus), down (en dessous) ou non (croise le pp) function prixPP(period) if source.close[period] > pivot.P[period] and source.close[period] > pivot.P[period] then return "up"; elseif source.open[period] < pivot.P[period] and source.close[period] < pivot.P[period] then return "down"; else return "none"; end end -- Orientation de la Kijun -- Le calcul simple est basé sur les 5 dernières périodes -- retourne up, down ou none (plat) function sensKJ(period) if ICH.TL[period]>ICH.TL[period-5] then return "up"; elseif ICH.TL[period]ICH.TL[period] then return "up"; elseif ICH.SL[period]ICH.SL[period] then return "up"; else return "down"; end end -- Cassure de la Kijun par le prix -- retourne yes ou none function cassureKJ(period) if source.close[period]>ICH.TL[period] and source.open[period]ICH.TL[period] then return "yes"; else return "none"; end end -- Potentiel RR doit être supérieur à 2 -- le calcul est fait entre la taille entre la cloture du signal et le + bas/haut des 5 dernières bougies jusqu'au prochain pivot function rrValable(period) if sensBougie(period) == "up" then local plusBas = source.low[period]; for i=1,5 do if source.low[period-i] < plusBas then plusBas = source.low[period-i]; end end local tailleRisquePoints = (source.close[period] - plusBas)/source:pipSize(); -- Identification de la position au niveau des Pivots if source.close[period] < pivot.R1[period] then if tailleRisquePoints < ((pivot.R1[period]-source.close[period])/source:pipSize())/2 then return true; end elseif source.close[period] < pivot.R2[period] then if tailleRisquePoints < ((pivot.R2[period]-source.close[period])/source:pipSize())/2 then return true; end elseif source.close[period] < pivot.R3[period] then if tailleRisquePoints < ((pivot.R3[period]-source.close[period])/source:pipSize())/2 then return true; end elseif source.close[period] < pivot.R4[period] then if tailleRisquePoints < ((pivot.R4[period]-source.close[period])/source:pipSize())/2 then return true; end end elseif sensBougie(period) == "down" then local plusHaut = source.high[period]; for i=1,5 do if source.high[period-i] > plusHaut then plusHaut = source.high[period-i]; end end local tailleRisquePoints = (plusHaut-source.close[period])/source:pipSize(); if source.close[period] > pivot.S1[period] then if tailleRisquePoints < ((source.close[period]-pivot.S1[period])/source:pipSize())/2 then return true; end elseif source.close[period] > pivot.S2[period] then if tailleRisquePoints < ((source.close[period]-pivot.S2[period])/source:pipSize())/2 then return true; end elseif source.close[period] > pivot.S3[period] then if tailleRisquePoints < ((source.close[period]-pivot.S3[period])/source:pipSize())/2 then return true; end elseif source.close[period] > pivot.S4[period] then if tailleRisquePoints < ((source.close[period]-pivot.S4[period])/source:pipSize())/2 then return true; end end end return false; end function isSignalUP(period) if sensBougie(period) == "up" and prixKumo(period) == "up" and (not bPivot or prixPP(period) == "up" ) and sensKJ(period) == "up" and (positionTK(period) == "down" or positionPrixTK(period) == "up") and cassureKJ(period) == "yes" then return true; end return false; end function isSignalDN(period) if sensBougie(period) == "down" and prixKumo(period) == "down" and (not bPivot or prixPP(period) == "down") and sensKJ(period) == "down" and (positionTK(period) == "up" or positionPrixTK(period) == "down") and cassureKJ(period) == "yes" then return true; end return false; end local lastSignalSerial = 0; function declencherSignal (period, color) open:setColor(period, color); -- TODO : Alerte + PlaySound UNIQUEMENT si dernière bougie active if period == source:size()-2 and lastSignalSerial ~= period then terminal:alertMessage(source:instrument(), 0, "Signal DMRB !" , 0); terminal:alertSound(instance.parameters.SoundFile, instance.parameters.RecurrentSound); lastSignalSerial = period; end end local initialized = false; function Update(period, mode) if period < first or not source:hasData(period) then return; end if not initialized and pivot.S1:hasData(period) then initialized = true; instance:updateFrom(0); return; end ICH:update(mode); pivot:update(mode); open[period]=source.open[period]; close[period]=source.close[period]; low[period]=source.low[period]; high[period]=source.high[period]; period = period -1; if isSignalUP(period) then if rrValable(period) then declencherSignal(period, instance.parameters.UPclr); else declencherSignal(period, instance.parameters.clr1); end elseif isSignalDN(period) then if rrValable(period) then declencherSignal(period, instance.parameters.DNclr); else declencherSignal(period, instance.parameters.clr1); end else open:setColor(period, instance.parameters.IDLEclr); end end