-- Id: 17736 -- More information about this indicator can be found at: -- http://fxcodebase.com/code/viewtopic.php?f=31&t=64447 --+------------------------------------------------------------------+ --| Copyright © 2019, Gehtsoft USA LLC | --| http://fxcodebase.com | --+------------------------------------------------------------------+ --| Developed by : Mario Jemic | --| mario.jemic@gmail.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() --The strategy profile initialization strategy:name("Highly adaptable BB_ANALYSER") strategy:description("") strategy:setTag("NonOptimizableParameters", "Email,SendEmail,SoundFile,RecurrentSound,PlaySound, ShowAlert") strategy.parameters:addGroup("Price") strategy.parameters:addString("Type", "Price Type", "", "Bid") strategy.parameters:addStringAlternative("Type", "Bid", "", "Bid") strategy.parameters:addStringAlternative("Type", "Ask", "", "Ask") strategy.parameters:addString("TF", "Time frame", "", "H1") strategy.parameters:setFlag("TF", core.FLAG_PERIODS) strategy.parameters:addGroup("Calculation") strategy.parameters:addInteger("Period", "Period", "", 20, 1, 10000) strategy.parameters:addDouble("Deviation", "Deviation", "", 2.0, 0.0001, 1000.0) strategy.parameters:addString("Method", "Method to smooth", "", "HMA") strategy.parameters:addStringAlternative("Method", "MVA", "", "MVA") strategy.parameters:addStringAlternative("Method", "EMA", "", "EMA") strategy.parameters:addStringAlternative("Method", "KAMA", "", "KAMA") strategy.parameters:addStringAlternative("Method", "Wilder", "", "Wilder") strategy.parameters:addStringAlternative("Method", "LWMA", "", "LWMA") strategy.parameters:addStringAlternative("Method", "SineWMA", "", "SineWMA") strategy.parameters:addStringAlternative("Method", "TriMA", "", "TriMA") strategy.parameters:addStringAlternative("Method", "LSMA", "", "LSMA") strategy.parameters:addStringAlternative("Method", "SMMA", "", "SMMA") strategy.parameters:addStringAlternative("Method", "HMA", "", "HMA") strategy.parameters:addStringAlternative("Method", "ZeroLagEMA", "", "ZeroLagEMA") strategy.parameters:addStringAlternative("Method", "DEMA", "", "DEMA") strategy.parameters:addStringAlternative("Method", "T3", "", "T3") strategy.parameters:addStringAlternative("Method", "ITrend", "", "ITrend") strategy.parameters:addStringAlternative("Method", "Median", "", "Median") strategy.parameters:addStringAlternative("Method", "GeoMean", "", "GeoMean") strategy.parameters:addStringAlternative("Method", "REMA", "", "REMA") strategy.parameters:addStringAlternative("Method", "ILRS", "", "ILRS") strategy.parameters:addStringAlternative("Method", "IE/2", "", "IE/2") strategy.parameters:addStringAlternative("Method", "TriMAgen", "", "TriMAgen") strategy.parameters:addStringAlternative("Method", "JSmooth", "", "JSmooth") strategy.parameters:addInteger("Smooth", "Number of periods to smooth", "", 3, 1, 10000) strategy.parameters:addDouble( "SlopeConfirmBubble", "Minimum Slope to confirm Bubble (pip/minute)", "", 0.18, 0.0, 20.0 ) strategy.parameters:addInteger("ConfirmEndSausage", "Confirm end of Sausage (%)", "", 25, 1, 100) strategy.parameters:addGroup("Selector") strategy.parameters:addString("Action" .. 1, "Bubble Up", "", "NO") strategy.parameters:addStringAlternative("Action" .. 1, "No Action", "", "NO") strategy.parameters:addStringAlternative("Action" .. 1, "Sell", "", "SELL") strategy.parameters:addStringAlternative("Action" .. 1, "Buy", "", "BUY") strategy.parameters:addStringAlternative("Action" .. 1, "Close Position", "", "CLOSE") strategy.parameters:addStringAlternative("Action" .. 1, "Alert", "", "Alert") strategy.parameters:addString("Action" .. 2, "Sausage Up", "", "NO") strategy.parameters:addStringAlternative("Action" .. 2, "No Action", "", "NO") strategy.parameters:addStringAlternative("Action" .. 2, "Sell", "", "SELL") strategy.parameters:addStringAlternative("Action" .. 2, "Buy", "", "BUY") strategy.parameters:addStringAlternative("Action" .. 2, "Close Position", "", "CLOSE") strategy.parameters:addStringAlternative("Action" .. 2, "Alert", "", "Alert") strategy.parameters:addString("Action" .. 3, "Bubble Down", "", "NO") strategy.parameters:addStringAlternative("Action" .. 3, "No Action", "", "NO") strategy.parameters:addStringAlternative("Action" .. 3, "Sell", "", "SELL") strategy.parameters:addStringAlternative("Action" .. 3, "Buy", "", "BUY") strategy.parameters:addStringAlternative("Action" .. 3, "Close Position", "", "CLOSE") strategy.parameters:addStringAlternative("Action" .. 3, "Alert", "", "Alert") strategy.parameters:addString("Action" .. 4, "Sausage Down", "", "NO") strategy.parameters:addStringAlternative("Action" .. 4, "No Action", "", "NO") strategy.parameters:addStringAlternative("Action" .. 4, "Sell", "", "SELL") strategy.parameters:addStringAlternative("Action" .. 4, "Buy", "", "BUY") strategy.parameters:addStringAlternative("Action" .. 4, "Close Position", "", "CLOSE") strategy.parameters:addStringAlternative("Action" .. 4, "Alert", "", "Alert") strategy.parameters:addString("Action" .. 5, "Squeeze", "", "NO") strategy.parameters:addStringAlternative("Action" .. 5, "No Action", "", "NO") strategy.parameters:addStringAlternative("Action" .. 5, "Sell", "", "SELL") strategy.parameters:addStringAlternative("Action" .. 5, "Buy", "", "BUY") strategy.parameters:addStringAlternative("Action" .. 5, "Close Position", "", "CLOSE") strategy.parameters:addStringAlternative("Action" .. 5, "Alert", "", "Alert") strategy.parameters:addGroup("Trend Stop Selector") strategy.parameters:addBoolean("confirm_with_trendstop", "Confirm Using Trendstop", "", true) strategy.parameters:addString("trendstop_tf", "Trendstop's Time Frame", "", "H4") strategy.parameters:setFlag("trendstop_tf", core.FLAG_PERIODS) strategy.parameters:addInteger("trendstop_period", "Trendstop's Period", "Period", 20) strategy.parameters:addString("trendstop_type", "Triger", "", "Close") strategy.parameters:addStringAlternative("trendstop_type", "Close", "", "Close") strategy.parameters:addStringAlternative("trendstop_type", "High/Low", "", "High") CreateTradingParameters() end function CreateTradingParameters() strategy.parameters:addGroup("Trading Parameters") strategy.parameters:addBoolean("AllowTrade", "Allow strategy to trade", "", false) strategy.parameters:setFlag("AllowTrade", core.FLAG_ALLOW_TRADE) strategy.parameters:addString("ExecutionType", "End of Turn / Live", "", "End of Turn") strategy.parameters:addStringAlternative("ExecutionType", "End of Turn", "", "End of Turn") strategy.parameters:addStringAlternative("ExecutionType", "Live", "", "Live") strategy.parameters:addBoolean("CloseOnOpposite", "Close On Opposite", "", true) strategy.parameters:addString( "CustomID", "Custom Identifier", "The identifier that can be used to distinguish strategy instances", "HABA" ) strategy.parameters:addBoolean("PositionCap", "Use Position Cap", "", false) strategy.parameters:addInteger( "MaxNumberOfPositionInAnyDirection", "Max Number Of Open Position In Any Direction", "", 10, 1, 10000 ) strategy.parameters:addInteger("MaxNumberOfPosition", "Max Number Of Position In One Direction", "", 5, 1, 100000) strategy.parameters:addString( "ALLOWEDSIDE", "Allowed side", "Allowed side for trading or signaling, can be Sell, Buy or Both", "Both" ) strategy.parameters:addStringAlternative("ALLOWEDSIDE", "Both", "", "Both") strategy.parameters:addStringAlternative("ALLOWEDSIDE", "Buy", "", "Buy") strategy.parameters:addStringAlternative("ALLOWEDSIDE", "Sell", "", "Sell") strategy.parameters:addString("Direction", "Type of Signal / Trade", "", "direct") strategy.parameters:addStringAlternative("Direction", "Direct", "", "direct") strategy.parameters:addStringAlternative("Direction", "Reverse", "", "reverse") 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, 10000) strategy.parameters:addBoolean("SetLimit", "Set Limit Orders", "", false) strategy.parameters:addInteger("Limit", "Limit Order in pips", "", 30, 1, 10000) strategy.parameters:addBoolean("SetStop", "Set Stop Orders", "", false) strategy.parameters:addInteger("Stop", "Stop Order in pips", "", 30, 1, 10000) strategy.parameters:addBoolean("TrailingStop", "Trailing stop order", "", false) strategy.parameters:addBoolean("Exit", "Use Optional Exit", "", true) strategy.parameters:addGroup("Alerts") strategy.parameters:addBoolean("ShowAlert", "ShowAlert", "", true) strategy.parameters:addBoolean("PlaySound", "Play Sound", "", false) strategy.parameters:addFile("SoundFile", "Sound File", "", "") strategy.parameters:setFlag("SoundFile", core.FLAG_SOUND) strategy.parameters:addBoolean("RecurrentSound", "Recurrent Sound", "", true) strategy.parameters:addBoolean("SendEmail", "Send Email", "", false) strategy.parameters:addString("Email", "Email", "", "") strategy.parameters:setFlag("Email", core.FLAG_EMAIL) strategy.parameters:addGroup("Time Parameters") strategy.parameters:addString("StartTime", "Start Time for Trading", "", "00:00:00") strategy.parameters:addString("StopTime", "Stop Time for Trading", "", "24:00:00") strategy.parameters:addBoolean("UseMandatoryClosing", "Use Mandatory Closing", "", false) strategy.parameters:addString("ExitTime", "Mandatory Closing Time", "", "23:59:00") strategy.parameters:addInteger("ValidInterval", "Valid interval for operation in second", "", 60) end local Source local SoundFile = nil local RecurrentSound = false local ALLOWEDSIDE local AllowMultiple local AllowTrade local Offer local CanClose local Account local Amount local SetLimit local Limit local SetStop local Stop local TrailingStop local ShowAlert local Email local SendEmail local BaseSize local CustomID local CloseOnOpposite local MaxNumberOfPositionInAnyDirection local MaxNumberOfPosition local Exit local ExecutionType, TickSource local Action = {} local PositionCap local Indicator local Direction local first local UseMandatoryClosing local ValidInterval local first local Period, Deviation, Method, Smooth, SlopeConfirmBubble, ConfirmEndSausage local trend_stop local trendstop_source local TICK_SOURCE_ID = 1 local MAIN_SOURCE_ID = 2 local TRENDSTOP_SOURCE_ID = 3 -- Don't need to store hour + minute + second for each time local OpenTime, CloseTime, ExitTime -- function Prepare(nameOnly) CustomID = instance.parameters.CustomID CloseOnOpposite = instance.parameters.CloseOnOpposite MaxNumberOfPositionInAnyDirection = instance.parameters.MaxNumberOfPositionInAnyDirection MaxNumberOfPosition = instance.parameters.MaxNumberOfPosition Direction = instance.parameters.Direction == "direct" Exit = instance.parameters.Exit ExecutionType = instance.parameters.ExecutionType PositionCap = instance.parameters.PositionCap ValidInterval = instance.parameters.ValidInterval UseMandatoryClosing = instance.parameters.UseMandatoryClosing Period = instance.parameters.Period Deviation = instance.parameters.Deviation Method = instance.parameters.Method Smooth = instance.parameters.Smooth SlopeConfirmBubble = instance.parameters.SlopeConfirmBubble ConfirmEndSausage = instance.parameters.ConfirmEndSausage local s, e, s1, e1 s, e = core.getcandle(instance.parameters.TF, core.now(), 0, 0) s1, e1 = core.getcandle(instance.parameters.trendstop_tf, core.now(), 0, 0) assert((e - s) <= (e1 - s1), "Trend Stop time frame must be equal to or bigger than the chart time frame!") assert(core.indicators:findIndicator("AVERAGES") ~= nil, "Please, download and install AVERAGES.LUA indicator") assert( core.indicators:findIndicator("BB_ANALYSER_2") ~= nil, "Please, download and install BB_ANALYSER_2.LUA indicator" ) assert(core.indicators:findIndicator("TRENDSTOP") ~= nil, "Please, download and install TRENDSTOP.LUA indicator") assert(instance.parameters.TF ~= "t1", "The time frame must not be tick") local name name = profile:id() .. "( " .. instance.bid:name() local i for i = 1, 14, 1 do Action[i] = instance.parameters:getString("Action" .. i) end name = name .. " )" instance:name(name) PrepareTrading() if nameOnly then return end if ExecutionType == "Live" then TickSource = ExtSubscribe(1, nil, "t1", instance.parameters.Type == "Bid", "close") end Source = ExtSubscribe(2, nil, instance.parameters.TF, instance.parameters.Type == "Bid", "bar") if instance.parameters.confirm_with_trendstop then trendstop_source = ExtSubscribe( TRENDSTOP_SOURCE_ID, nil, instance.parameters.trendstop_tf, instance.parameters.Type == "Bid", "bar" ) trend_stop = core.indicators:create( "TRENDSTOP", trendstop_source, instance.parameters.trendstop_period, instance.parameters.trendstop_type ) end Indicator = core.indicators:create( "BB_ANALYSER_2", Source, Period, Deviation, Method, Smooth, SlopeConfirmBubble, ConfirmEndSausage ) first = Indicator.DATA:first() local valid OpenTime, valid = ParseTime(instance.parameters.StartTime) assert(valid, "Time " .. instance.parameters.StartTime .. " is invalid") CloseTime, valid = ParseTime(instance.parameters.StopTime) assert(valid, "Time " .. instance.parameters.StopTime .. " is invalid") ExitTime, valid = ParseTime(instance.parameters.ExitTime) assert(valid, "Time " .. instance.parameters.ExitTime .. " is invalid") if UseMandatoryClosing then core.host:execute("setTimer", 100, math.max(ValidInterval / 2, 1)) end end function ConfirmLongWithTrendstop() if not instance.parameters.confirm_with_trendstop then return true end if (trendstop_source.close[NOW] > trend_stop.DATA[NOW]) then return true else return false end end function ConfirmShortWithTrendstop() if not instance.parameters.confirm_with_trendstop then return true end if (trendstop_source.close[NOW] < trend_stop.DATA[NOW]) then return true else return false end end function ParseTime(time) local pos = string.find(time, ":") if pos == nil then return nil, false end local h = tonumber(string.sub(time, 1, pos - 1)) time = string.sub(time, pos + 1) pos = string.find(time, ":") if pos == nil then return nil, false end local m = tonumber(string.sub(time, 1, pos - 1)) local s = tonumber(string.sub(time, pos + 1)) return (h / 24.0 + m / 1440.0 + s / 86400.0), ((h >= 0 and h < 24 and m >= 0 and m < 60 and s >= 0 and s < 60) or -- time in ole format (h == 24 and m == 0 and s == 0)) -- validity flag end function InRange(now, openTime, closeTime) if openTime < closeTime then return now >= openTime and now <= closeTime; end if openTime > closeTime then return now > openTime or now < closeTime; end return now == openTime; end function PrepareTrading() ALLOWEDSIDE = instance.parameters.ALLOWEDSIDE local PlaySound = instance.parameters.PlaySound if PlaySound then SoundFile = instance.parameters.SoundFile else SoundFile = nil end assert(not (PlaySound) or (PlaySound and SoundFile ~= ""), "Sound file must be chosen") ShowAlert = instance.parameters.ShowAlert RecurrentSound = instance.parameters.RecurrentSound SendEmail = instance.parameters.SendEmail if SendEmail then Email = instance.parameters.Email else Email = nil end assert(not (SendEmail) or (SendEmail and Email ~= ""), "E-mail address must be specified") AllowTrade = instance.parameters.AllowTrade 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) SetLimit = instance.parameters.SetLimit Limit = instance.parameters.Limit SetStop = instance.parameters.SetStop Stop = instance.parameters.Stop TrailingStop = instance.parameters.TrailingStop end local ONE function ExtUpdate(id, source, period) -- The method called every time when a new bid or ask price appears. now = core.host:execute("getServerTime") -- get only time now = now - math.floor(now) -- check whether the time is in the exit time period if not InRange(now, OpenTime, CloseTime) then return end if AllowTrade then if not (checkReady("trades")) or not (checkReady("orders")) then return end end if id == TRENDSTOP_SOURCE_ID then return end if period < 0 then return end if ExecutionType == "Live" then if id ~= 1 then return end period = core.findDate(Source.close, TickSource:date(period), false) if ONE == Source:serial(period) then return end else if id ~= 2 then return end end if period < 0 then return end if trend_stop ~= nil then trend_stop:update(core.UpdateAll) end Indicator:update(core.UpdateLast) if not Indicator.DATA:hasData(period) then return end if Indicator.BubbleUp[period] > 0 and (Indicator.BubbleUp[period - 1] == 0 or Indicator.BubbleUp[period - 1] == nil) then ACTION(1, 1, "Bubble Up", period) end if Indicator.SausageUp[period] > 0 and (Indicator.SausageUp[period - 1] == 0 or Indicator.SausageUp[period - 1] == nil) then ACTION(2, 1, "Sausage Up", period) end if Indicator.BubbleDn[period] > 0 and (Indicator.BubbleDn[period - 1] == 0 or Indicator.BubbleDn[period - 1] == nil) then ACTION(3, 2, "Bubble Dn", period) end if Indicator.SausageDn[period] > 0 and (Indicator.SausageDn[period - 1] == 0 or Indicator.SausageDn[period - 1] == nil) then ACTION(4, 2, "Sausage Dn", period) end if Indicator.Squeeze[period] > 0 and (Indicator.Squeeze[period - 1] == 0 or Indicator.Squeeze[period - 1] == nil) then ACTION(5, 3, "Squeeze", period) end end -- NG: Introduce async function for timer/monitoring for the order results function ExtAsyncOperationFinished(cookie, success, message) if cookie == 100 then -- timer if UseMandatoryClosing and AllowTrade then now = core.host:execute("getServerTime") -- get only time now = now - math.floor(now) -- check whether the time is in the exit time period if now >= ExitTime and now < ExitTime + (ValidInterval / 86400.0) then if not (checkReady("trades")) or not (checkReady("orders")) then return end if haveTrades("S") then exitSpecific("S") Signal("Close Short") end if haveTrades("B") then exitSpecific("B") Signal("Close Long") end end end elseif cookie == 200 and not success then terminal:alertMessage( instance.bid:instrument(), instance.bid[instance.bid:size() - 1], "Open order failed" .. message, instance.bid:date(instance.bid:size() - 1) ) elseif cookie == 201 and not success then terminal:alertMessage( instance.bid:instrument(), instance.bid[instance.bid:size() - 1], "Close order failed" .. message, instance.bid:date(instance.bid:size() - 1) ) end end function ACTION(Flag, Line, Label, period) ONE = Source:serial(period) if Action[Flag] == "NO" then return elseif Action[Flag] == "BUY" and ConfirmLongWithTrendstop() then BUY() elseif Action[Flag] == "SELL" and ConfirmShortWithTrendstop() then SELL() elseif Action[Flag] == "CLOSE" then if AllowTrade then if haveTrades("B") then exitSpecific("B") Signal("Close Long") end if haveTrades("S") then exitSpecific("S") Signal("Close Short") end else Signal("Close All") end elseif Action[Flag] == "Alert" then Signal(Line .. " Line Cross" .. Label) end end --===========================================================================-- -- TRADING UTILITY FUNCTIONS -- --============================================================================-- function BUY() if AllowTrade then if CloseOnOpposite and haveTrades("S") then -- close on opposite signal exitSpecific("S") Signal("Close Short") end if ALLOWEDSIDE == "Sell" then -- we are not allowed buys. return end enter("B") else Signal("Buy Signal") end end function SELL() if AllowTrade then if CloseOnOpposite and haveTrades("B") then -- close on opposite signal exitSpecific("B") Signal("Close Long") end if ALLOWEDSIDE == "Buy" then -- we are not allowed sells. return end enter("S") else Signal("Sell Signal") end end function Signal(Label) if ShowAlert then terminal:alertMessage(instance.bid:instrument(), instance.bid[NOW], Label, instance.bid:date(NOW)) end if SoundFile ~= nil then terminal:alertSound(SoundFile, RecurrentSound) end if Email ~= nil then terminal:alertEmail( Email, Label, profile:id() .. "(" .. instance.bid:instrument() .. ")" .. instance.bid[NOW] .. ", " .. Label .. ", " .. instance.bid:date(NOW) ) end end function checkReady(table) local rc if Account == "TESTACC_ID" then -- run under debugger/simulator rc = true else rc = core.host:execute("isTableFilled", table) end return rc end function tradesCount(BuySell) local enum, row local count = 0 enum = core.host:findTable("trades"):enumerator() row = enum:next() while row ~= nil do if row.AccountID == Account and row.OfferID == Offer and row.QTXT == CustomID and (row.BS == BuySell or BuySell == nil) then count = count + 1 end row = enum:next() end return count end function haveTrades(BuySell) local enum, row local found = false enum = core.host:findTable("trades"):enumerator() row = enum:next() while (row ~= nil) do if row.AccountID == Account and row.OfferID == Offer and row.QTXT == CustomID and (row.BS == BuySell or BuySell == nil) then found = true break end row = enum:next() end return found end -- enter into the specified direction function enter(BuySell) -- do not enter if position in the specified direction already exists if (tradesCount(BuySell) >= MaxNumberOfPosition or (tradesCount(nil) >= MaxNumberOfPositionInAnyDirection)) and PositionCap then return true end -- send the alert after the checks to see if we can trade. if (BuySell == "S") then Signal("Sell Signal") else Signal("Buy Signal") end return MarketOrder(BuySell) end -- enter into the specified direction function MarketOrder(BuySell) local valuemap, success, msg valuemap = core.valuemap() valuemap.Command = "CreateOrder" valuemap.OrderType = "OM" valuemap.OfferID = Offer valuemap.AcctID = Account valuemap.Quantity = Amount * BaseSize valuemap.BuySell = BuySell valuemap.CustomID = CustomID -- add stop/limit valuemap.PegTypeStop = "O" if SetStop then if BuySell == "B" then valuemap.PegPriceOffsetPipsStop = -Stop else valuemap.PegPriceOffsetPipsStop = Stop end end if TrailingStop then valuemap.TrailStepStop = 1 end valuemap.PegTypeLimit = "O" if SetLimit then if BuySell == "B" then valuemap.PegPriceOffsetPipsLimit = Limit else valuemap.PegPriceOffsetPipsLimit = -Limit end end if (not CanClose) then valuemap.EntryLimitStop = "Y" end success, msg = terminal:execute(200, valuemap) if not (success) then terminal:alertMessage( instance.bid:instrument(), instance.bid[instance.bid:size() - 1], "Open order failed" .. msg, instance.bid:date(instance.bid:size() - 1) ) return false end return true end -- exit from the specified trade using the direction as a key function exitSpecific(BuySell) local enum, row, valuemap enum = core.host:findTable("trades"):enumerator() while true do row = enum:next() if row == nil then break end if row.AccountID == Account and row.OfferID == Offer and row.BS == BuySell and row.QTXT == CustomID then -- if trade has to be closed if CanClose then -- non-FIFO account, create a close market order valuemap = core.valuemap() valuemap.OrderType = "CM" valuemap.OfferID = Offer valuemap.AcctID = Account valuemap.Quantity = row.Lot valuemap.TradeID = row.TradeID valuemap.CustomID = CustomID if row.BS == "B" then valuemap.BuySell = "S" else valuemap.BuySell = "B" end success, msg = terminal:execute(201, valuemap) if not (success) then terminal:alertMessage( instance.bid:instrument(), instance.bid[instance.bid:size() - 1], "Close order failed" .. msg, instance.bid:date(instance.bid:size() - 1) ) return false end else -- FIFO account, create an opposite market order valuemap = core.valuemap() valuemap.OrderType = "OM" valuemap.OfferID = Offer valuemap.AcctID = Account valuemap.Quantity = Amount * BaseSize valuemap.CustomID = CustomID if row.BS == "B" then valuemap.BuySell = "S" else valuemap.BuySell = "B" end success, msg = terminal:execute(201, valuemap) if not (success) then terminal:alertMessage( instance.bid:instrument(), instance.bid[instance.bid:size() - 1], "Close order failed" .. msg, instance.bid:date(instance.bid:size() - 1) ) return false end end end end end dofile(core.app_path() .. "\\strategies\\standard\\include\\helper.lua")