-- Id: 858 -- More information about this indicator can be found at: -- http://fxcodebase.com/ --+------------------------------------------------------------------+ --| Copyright © 2019, Gehtsoft USA LLC | --| http://fxcodebase.com | --+------------------------------------------------------------------+ --| Support our efforts by donating | --| Paypal: https://goo.gl/9Rj74e | --+------------------------------------------------------------------+ --| Patreon : https://goo.gl/GdXWeN | --| BitCoin : 15VCJTLaz12Amr7adHSBtL9v8XomURo9RF | --| BitCoin Cash: 1BEtS465S3Su438Kc58h2sqvVvHK9Mijtg | --| Ethereum : 0x8C110cD61538fb6d7A2B47858F0c0AaBd663068D | --| LiteCoin : LLU8PSY2vsq7B9kRELLZQcKf5nJQrdeqwD | --+------------------------------------------------------------------+ function Init() strategy:name("MA Corss with the confirmation by the distance between lines"); strategy:setTag("NonOptimizableParameters", "Email,SendEmail,SoundFile,RecurrentSound,PlaySound,ShowAlert"); strategy:description("The signal checks for the Moving Average crosses confirmed by the distance between the MA lines"); strategy.parameters:addGroup("Parameter"); strategy.parameters:addInteger("FMA_N", "Fast Moving Average Period", "", 5); strategy.parameters:addString("FMA_M", "Fast Moving Average Method", "The methods marked by an asterisk (*) require the appropriate strategys to be loaded.", "MVA"); strategy.parameters:addStringAlternative("FMA_M", "MVA", "", "MVA"); strategy.parameters:addStringAlternative("FMA_M", "EMA", "", "EMA"); strategy.parameters:addStringAlternative("FMA_M", "LWMA", "", "LWMA"); strategy.parameters:addStringAlternative("FMA_M", "TMA", "", "TMA"); strategy.parameters:addStringAlternative("FMA_M", "SMMA*", "", "SMMA"); strategy.parameters:addStringAlternative("FMA_M", "Vidya (1995)*", "", "VIDYA"); strategy.parameters:addStringAlternative("FMA_M", "Vidya (1992)*", "", "VIDYA92"); strategy.parameters:addStringAlternative("FMA_M", "Wilders*", "", "WMA"); strategy.parameters:addStringAlternative("FMA_M", "TEMA*", "", "TEMA1"); strategy.parameters:addString("FMA_P", "Fast Moving Average Price", "", "C"); strategy.parameters:addStringAlternative("FMA_P", "Open", "", "O"); strategy.parameters:addStringAlternative("FMA_P", "High", "", "H"); strategy.parameters:addStringAlternative("FMA_P", "Low", "", "L"); strategy.parameters:addStringAlternative("FMA_P", "Close", "", "C"); strategy.parameters:addStringAlternative("FMA_P", "Median", "", "M"); strategy.parameters:addStringAlternative("FMA_P", "Typical", "", "T"); strategy.parameters:addStringAlternative("FMA_P", "Weighted", "", "W"); strategy.parameters:addInteger("SMA_N", "Slow Moving Average Period", "", 20); strategy.parameters:addString("SMA_M", "Slow Moving Average Method", "The methods marked by an asterisk (*) require the appropriate strategys to be loaded.", "MVA"); strategy.parameters:addStringAlternative("SMA_M", "MVA", "", "MVA"); strategy.parameters:addStringAlternative("SMA_M", "EMA", "", "EMA"); strategy.parameters:addStringAlternative("SMA_M", "LWMA", "", "LWMA"); strategy.parameters:addStringAlternative("SMA_M", "TMA", "", "TMA"); strategy.parameters:addStringAlternative("SMA_M", "SMMA*", "", "SMMA"); strategy.parameters:addStringAlternative("SMA_M", "Vidya (1995)*", "", "VIDYA"); strategy.parameters:addStringAlternative("SMA_M", "Vidya (1992)*", "", "VIDYA92"); strategy.parameters:addStringAlternative("SMA_M", "Wilders*", "", "WMA"); strategy.parameters:addStringAlternative("SMA_M", "TEMA*", "", "TEMA1"); strategy.parameters:addString("SMA_P", "Slow Moving Average Price", "", "C"); strategy.parameters:addStringAlternative("SMA_P", "Open", "", "O"); strategy.parameters:addStringAlternative("SMA_P", "High", "", "H"); strategy.parameters:addStringAlternative("SMA_P", "Low", "", "L"); strategy.parameters:addStringAlternative("SMA_P", "Close", "", "C"); strategy.parameters:addStringAlternative("SMA_P", "Median", "", "M"); strategy.parameters:addStringAlternative("SMA_P", "Typical", "", "T"); strategy.parameters:addStringAlternative("SMA_P", "Weighted", "", "W"); strategy.parameters:addInteger("Dist", "Distance between MA (points) to confirm", "", 10); strategy.parameters:addInteger("ConfN", "Number of bars to confirm", "Use 0 to confirm on the same bar only", 3); strategy.parameters:addString("Type", "Type of the price", "", "Bid"); strategy.parameters:addStringAlternative("Type", "Bid", "", "Bid"); strategy.parameters:addStringAlternative("Type", "Ask", "", "Ask"); strategy.parameters:addString("Period", "Time frame", "", "m1"); strategy.parameters:setFlag("Period", core.FLAG_PERIODS); strategy.parameters:addGroup("Signal"); strategy.parameters:addBoolean("ShowAlert", "Show Alert", "", true); strategy.parameters:addBoolean("PlaySound", "Play Sound", "", false); strategy.parameters:addFile("SoundFile", "Sound File", "", ""); end local SoundFile; local FMA, SMA; local Dist; local ConfN; local BUY, SELL; local gSource = nil; -- the source stream local first; function CreateIndicator(method, n, price) local source; if not(gSource:isBar()) then source = gSource; elseif price == "O" then source = gSource.open; elseif price == "H" then source = gSource.high; elseif price == "L" then source = gSource.low; elseif price == "C" then source = gSource.close; elseif price == "M" then source = gSource.median; elseif price == "T" then source = gSource.typical; elseif price == "W" then source = gSource.weighted; end assert(core.indicators:findIndicator(method) ~= nil, method .. " indicator must be installed"); return core.indicators:create(method, source, n); end function Prepare() local FastN, SlowN; -- collect parameters FMA_N = instance.parameters.FMA_N; SMA_N = instance.parameters.SMA_N; Dist = instance.parameters.Dist; ConfN = instance.parameters.ConfN; assert(FMA_N < SMA_N, "Fast MA must be faster than slow MA"); ShowAlert = instance.parameters.ShowAlert; if instance.parameters.PlaySound then SoundFile = instance.parameters.SoundFile; else SoundFile = nil; end assert(not(PlaySound) or (PlaySound and SoundFile ~= ""), "Sound File must be specified"); BUY = "BUY"; SELL = "SELL"; local fastsource, slowsource; ExtSetupSignal(profile:id() .. ":", ShowAlert); if instance.parameters.Period == "t1" then gSource = ExtSubscribe(1, nil, instance.parameters.Period, instance.parameters.Type == "Bid", "close"); else gSource = ExtSubscribe(1, nil, instance.parameters.Period, instance.parameters.Type == "Bid", "bar"); end FMA = CreateIndicator(instance.parameters.FMA_M, instance.parameters.FMA_N, instance.parameters.FMA_P); SMA = CreateIndicator(instance.parameters.SMA_M, instance.parameters.SMA_N, instance.parameters.SMA_P); first = math.max(FMA.DATA:first(), SMA.DATA:first()) + 1; local pip; pip = gSource:pipSize(); if pip > 1 then -- workaround for bug in Marketscope Apr, 10 release -- for a history returned via getHistory() the pipSize returns precision -- instead of pipsize Dist = math.pow(10, -pip) * Dist; else Dist = pip * Dist; end local name = profile:id() .. "(" .. instance.bid:instrument() .. "(" .. instance.parameters.Period .. ")," .. instance.parameters.FMA_M .. "(" .. instance.parameters.FMA_N .. ")," .. instance.parameters.SMA_M .. "(" .. instance.parameters.SMA_N .. ")," .. Dist .. "," .. ConfN .. ")"; instance:name(name); end local CurrDist = nil; local Signal = nil; local PrevDate = nil; -- when tick source is updated function ExtUpdate(id, source, period) -- update moving average FMA:update(core.UpdateLast); SMA:update(core.UpdateLast); if period <= first then return ; end if CurrDist ~= nil and PrevDate < gSource:date(period) then CurrDist = CurrDist + 1; end PrevDate = gSource:date(period); if core.crossesOver(FMA.DATA, SMA.DATA, period) then CurrDist = 0; Signal = 1; elseif core.crossesOver(SMA.DATA, FMA.DATA, period) then CurrDist = 0; Signal = -1; end if CurrDist ~= nil and CurrDist < ConfN then if Signal > 0 then if (FMA.DATA[period] - SMA.DATA[period]) >= Dist then ExtSignal(gSource, period, BUY, SoundFile); CurrDist = nil; end else if (SMA.DATA[period] - FMA.DATA[period]) >= Dist then ExtSignal(gSource, period, SELL, SoundFile); CurrDist = nil; end end end end dofile(core.app_path() .. "\\strategies\\standard\\include\\helper.lua");