-- More information about this indicator can be found at: -- http://fxcodebase.com/code/viewtopic.php?f=27&t=65013 function Init() --The strategy profile initialization strategy:name("DNC MA cross strategy"); strategy:description("DNC MA cross strategy"); strategy.parameters:addGroup("Parameters"); strategy.parameters:addInteger("Period1", "Period of MA1", "", 100); strategy.parameters:addString("Method1", "Method of MA1", "", "MVA"); strategy.parameters:addStringAlternative("Method1", "MVA", "", "MVA"); strategy.parameters:addStringAlternative("Method1", "EMA", "", "EMA"); strategy.parameters:addStringAlternative("Method1", "KAMA", "", "KAMA"); strategy.parameters:addStringAlternative("Method1", "Wilder", "", "Wilder"); strategy.parameters:addStringAlternative("Method1", "LWMA", "", "LWMA"); strategy.parameters:addStringAlternative("Method1", "SineWMA", "", "SineWMA"); strategy.parameters:addStringAlternative("Method1", "TriMA", "", "TriMA"); strategy.parameters:addStringAlternative("Method1", "LSMA", "", "LSMA"); strategy.parameters:addStringAlternative("Method1", "SMMA", "", "SMMA"); strategy.parameters:addStringAlternative("Method1", "HMA", "", "HMA"); strategy.parameters:addStringAlternative("Method1", "ZeroLagEMA", "", "ZeroLagEMA"); strategy.parameters:addStringAlternative("Method1", "DEMA", "", "DEMA"); strategy.parameters:addStringAlternative("Method1", "T3", "", "T3"); strategy.parameters:addStringAlternative("Method1", "ITrend", "", "ITrend"); strategy.parameters:addStringAlternative("Method1", "Median", "", "Median"); strategy.parameters:addStringAlternative("Method1", "GeoMean", "", "GeoMean"); strategy.parameters:addStringAlternative("Method1", "REMA", "", "REMA"); strategy.parameters:addStringAlternative("Method1", "ILRS", "", "ILRS"); strategy.parameters:addStringAlternative("Method1", "IE/2", "", "IE/2"); strategy.parameters:addStringAlternative("Method1", "TriMAgen", "", "TriMAgen"); strategy.parameters:addStringAlternative("Method1", "JSmooth", "", "JSmooth"); strategy.parameters:addString("Price1", "Price of MA1", "", "close"); strategy.parameters:addStringAlternative("Price1", "close", "", "close"); strategy.parameters:addStringAlternative("Price1", "open", "", "open"); strategy.parameters:addStringAlternative("Price1", "high", "", "high"); strategy.parameters:addStringAlternative("Price1", "low", "", "low"); strategy.parameters:addStringAlternative("Price1", "median", "", "median"); strategy.parameters:addStringAlternative("Price1", "typical", "", "typical"); strategy.parameters:addStringAlternative("Price1", "weighted", "", "weighted"); strategy.parameters:addInteger("Period2", "Period of MA2", "", 30); strategy.parameters:addString("Method2", "Method of MA2", "", "MVA"); strategy.parameters:addStringAlternative("Method2", "MVA", "", "MVA"); strategy.parameters:addStringAlternative("Method2", "EMA", "", "EMA"); strategy.parameters:addStringAlternative("Method2", "KAMA", "", "KAMA"); strategy.parameters:addStringAlternative("Method2", "Wilder", "", "Wilder"); strategy.parameters:addStringAlternative("Method2", "LWMA", "", "LWMA"); strategy.parameters:addStringAlternative("Method2", "SineWMA", "", "SineWMA"); strategy.parameters:addStringAlternative("Method2", "TriMA", "", "TriMA"); strategy.parameters:addStringAlternative("Method2", "LSMA", "", "LSMA"); strategy.parameters:addStringAlternative("Method2", "SMMA", "", "SMMA"); strategy.parameters:addStringAlternative("Method2", "HMA", "", "HMA"); strategy.parameters:addStringAlternative("Method2", "ZeroLagEMA", "", "ZeroLagEMA"); strategy.parameters:addStringAlternative("Method2", "DEMA", "", "DEMA"); strategy.parameters:addStringAlternative("Method2", "T3", "", "T3"); strategy.parameters:addStringAlternative("Method2", "ITrend", "", "ITrend"); strategy.parameters:addStringAlternative("Method2", "Median", "", "Median"); strategy.parameters:addStringAlternative("Method2", "GeoMean", "", "GeoMean"); strategy.parameters:addStringAlternative("Method2", "REMA", "", "REMA"); strategy.parameters:addStringAlternative("Method2", "ILRS", "", "ILRS"); strategy.parameters:addStringAlternative("Method2", "IE/2", "", "IE/2"); strategy.parameters:addStringAlternative("Method2", "TriMAgen", "", "TriMAgen"); strategy.parameters:addStringAlternative("Method2", "JSmooth", "", "JSmooth"); strategy.parameters:addString("Price2", "Price of MA2", "", "close"); strategy.parameters:addStringAlternative("Price2", "close", "", "close"); strategy.parameters:addStringAlternative("Price2", "open", "", "open"); strategy.parameters:addStringAlternative("Price2", "high", "", "high"); strategy.parameters:addStringAlternative("Price2", "low", "", "low"); strategy.parameters:addStringAlternative("Price2", "median", "", "median"); strategy.parameters:addStringAlternative("Price2", "typical", "", "typical"); strategy.parameters:addStringAlternative("Price2", "weighted", "", "weighted"); strategy.parameters:addInteger("DNC_N", "DNC Number of periods", "", 20, 2, 10000); strategy.parameters:addGroup("Strategy Parameters"); strategy.parameters:addString("TypeSignal", "Type of signal", "", "direct"); strategy.parameters:addStringAlternative("TypeSignal", "direct", "", "direct"); strategy.parameters:addStringAlternative("TypeSignal", "reverse", "", "reverse"); strategy.parameters:addGroup("Price Parameters"); strategy.parameters:addString("TF", "Time Frame", "", "m15"); strategy.parameters:setFlag("TF", core.FLAG_PERIODS); strategy.parameters:addGroup("Trading Parameters"); strategy.parameters:addBoolean("AllowTrade", "Allow strategy to trade", "", false); strategy.parameters:addString("Account", "Account to trade on", "", ""); strategy.parameters:setFlag("Account", core.FLAG_ACCOUNT); strategy.parameters:addInteger("Amount", "Trade Amount in Lots", "", 1, 1, 100); strategy.parameters:addString("AllowDirection", "Allow direction for positions", "", "Both"); strategy.parameters:addStringAlternative("AllowDirection", "Both", "", "Both"); strategy.parameters:addStringAlternative("AllowDirection", "Long", "", "Long"); strategy.parameters:addStringAlternative("AllowDirection", "Short", "", "Short"); strategy.parameters:addGroup("Signal Parameters"); strategy.parameters:addBoolean("ShowAlert", "Show Alert", "", true); strategy.parameters:addBoolean("PlaySound", "Play Sound", "", false); strategy.parameters:addFile("SoundFile", "Sound File", "", ""); strategy.parameters:setFlag("SoundFile", core.FLAG_SOUND); strategy.parameters:addBoolean("Recurrent", "RecurrentSound", "", false); strategy.parameters:addGroup("Email Parameters"); strategy.parameters:addBoolean("SendEmail", "Send email", "", false); strategy.parameters:addString("Email", "Email address", "", ""); strategy.parameters:setFlag("Email", core.FLAG_EMAIL); end -- Signal Parameters local ShowAlert; local SoundFile; local RecurrentSound; local SendEmail, Email; local DNC; -- Internal indicators local TMAC = nil; -- Strategy parameters local openLevel = 0 local closeLevel = 0 local confirmTrend; -- Trading parameters local AllowTrade = nil; local Account = nil; local Amount = nil; local BaseSize = nil; local PipSize; local CanClose = nil; local AllowDirection; -- -- -- function Prepare() ShowAlert = instance.parameters.ShowAlert; AllowDirection = instance.parameters.AllowDirection; local PlaySound = instance.parameters.PlaySound if PlaySound then SoundFile = instance.parameters.SoundFile; else SoundFile = nil; end assert(not(PlaySound) or SoundFile ~= "", "Sound file must be chosen"); RecurrentSound = instance.parameters.Recurrent; local SendEmail = instance.parameters.SendEmail; if SendEmail then Email = instance.parameters.Email; else Email = nil; end assert(not(SendEmail) or Email ~= "", "Email address must be specified"); assert(instance.parameters.TF ~= "t1", "The time frame must not be tick"); local name; name = profile:id() .. "(" .. instance.bid:name() .. "." .. instance.parameters.TF .. "," .. ")"; instance:name(name); AllowTrade = instance.parameters.AllowTrade; if AllowTrade then Account = instance.parameters.Account; Amount = instance.parameters.Amount; BaseSize = core.host:execute("getTradingProperty", "baseUnitSize", instance.bid:instrument(), Account); Offer = core.host:findTable("offers"):find("Instrument", instance.bid:instrument()).OfferID; CanClose = core.host:execute("getTradingProperty", "canCreateMarketClose", instance.bid:instrument(), Account); PipSize = instance.bid:pipSize(); end assert(core.indicators:findIndicator("TWO_MA_CROSS2") ~= nil, "Please, download and install TWO_MA_CROSS2.LUA indicator"); assert(core.indicators:findIndicator("DNC") ~= nil, "Please, download and install DNC.LUA indicator"); Source = ExtSubscribe(2, nil, instance.parameters.TF, true, "bar"); TMAC = core.indicators:create("TWO_MA_CROSS2", Source, instance.parameters.Period1, instance.parameters.Method1, instance.parameters.Price1, instance.parameters.Period2, instance.parameters.Method2, instance.parameters.Price2); DNC = core.indicators:create("DNC", Source, instance.parameters.DNC_N); ExtSetupSignal(profile:id() .. ":", ShowAlert); ExtSetupSignalMail(name); end function haveTrades(BuySell) local enum = core.host:findTable("trades"):enumerator() local row = enum:next() while (not found) and (row ~= nil) do if row.AccountID == Account and (row.BS == BuySell or BuySell == nil) then return true; end row = enum:next() end return false end function ExtUpdate(id, source, period) -- The method called every time when a new bid or ask price appears. TMAC:update(core.UpdateLast); DNC:update(core.UpdateLast); -- Check that we have enough data if (TMAC.DATA:first() > (period - 1)) then return end local pipSize = instance.bid:pipSize() local trades = core.host:findTable("trades"); local MustOpenB=false; local MustOpenS=false; if TMAC.MA1_Buff[period-1]>TMAC.MA2_Buff[period-1] and TMAC.MA1_Buff[period]TMAC.MA2_Buff[period] then if instance.parameters.TypeSignal=="direct" then MustOpenS=true; else MustOpenB=true; end end if (haveTrades()) then local enum = trades:enumerator(); while true do local row = enum:next(); if row == nil then break end if row.AccountID == Account and row.OfferID == Offer then -- Close position if we have corresponding closing conditions. if row.BS == 'B' then if MustOpenS then if ShowAlert then if instance.parameters.AllowDirection=="Long" then ExtSignal(source, period, "Close BUY", SoundFile, Email, RecurrentSound); else ExtSignal(source, period, "Close BUY and SELL", SoundFile, Email, RecurrentSound); end end if AllowTrade then Close(row); if instance.parameters.AllowDirection~="Long" then Open("S", DNC.DU[period], DNC.DN[period]); end end end elseif row.BS == 'S' then if MustOpenB then if ShowAlert then if instance.parameters.AllowDirection=="Short" then ExtSignal(source, period, "Close SELL", SoundFile, Email, RecurrentSound); else ExtSignal(source, period, "Close SELL and BUY", SoundFile, Email, RecurrentSound); end end if AllowTrade then Close(row); if instance.parameters.AllowDirection~="Short" then Open("B", DNC.DN[period], DNC.DU[period]); end end end end end end else if MustOpenB==true and instance.parameters.AllowDirection~="Short" then if ShowAlert then ExtSignal(source, period, "BUY", SoundFile, Email, RecurrentSound) end if AllowTrade then Open("B", DNC.DN[period], DNC.DU[period]); end end if MustOpenS==true and instance.parameters.AllowDirection~="Long" then if ShowAlert then ExtSignal(source, period, "SELL", SoundFile, Email, RecurrentSound) end if AllowTrade then Open("S", DNC.DU[period], DNC.DN[period]); end end end end -- The strategy instance finalization. function ReleaseInstance() end -- The method enters to the market function Open(side, Price, Stop) local valuemap; valuemap = core.valuemap(); local CurPrice=Source.close[Source.close:size()-1]; if (side=="B" and Price>CurPrice) or (side=="S" and Price