Source: https://fxcodebase.com/code/viewtopic.php?f=17&t=1259
Forum: 17 · Topic 1259 · 6 post(s)
Alexander.Gettinger · Thu Jun 03, 2010 11:22 pm
SAR oscillator=SAR-Close;

Code: Select all `function Init() indicator:name(“SAR oscillator”); indicator:description(“SAR oscillator”); indicator:requiredSource(core.Bar); indicator:type(core.Oscillator); indicator.parameters:addDouble(“Step”, “Step for SAR”, “”, 0.02, 1, 200); indicator.parameters:addDouble(“Max”, “Max for SAR”, “”, 0.2, 1, 200);
indicator.parameters:addColor(“clr_buff1”, “Color of Buff1”, “Color of Buff1”, core.rgb(0, 255, 0)); indicator.parameters:addColor(“clr_buff2”, “Color of Buff2”, “Color of Buff2”, core.rgb(0, 128, 0)); indicator.parameters:addColor(“clr_buff3”, “Color of Buff3”, “Color of Buff3”, core.rgb(255, 0, 0)); indicator.parameters:addColor(“clr_buff4”, “Color of Buff4”, “Color of Buff4”, core.rgb(128, 0, 0)); indicator.parameters:addColor(“clr_Line”, “Color of Line”, “Color of Line”, core.rgb(255, 255, 0)); end
local first; local source = nil; local Step; local Max; local SAR; local Buff1=nil; local Buff2=nil; local Buff3=nil; local Buff4=nil; local LineBuff=nil;
function Prepare() source = instance.source; Step=instance.parameters.Step; Max=instance.parameters.Max; SAR = core.indicators:create(“SAR”, source, Step, Max); first = SAR.DATA:first()+2; local name = profile:id() .. “(“ .. source:name() .. “, “ .. instance.parameters.Step .. “, “ .. instance.parameters.Max .. “)”; instance:name(name); Buff1 = instance:addStream(“Buff1”, core.Bar, name .. “.Buff1”, “Buff1”, instance.parameters.clr_buff1, first); Buff2 = instance:addStream(“Buff2”, core.Bar, name .. “.Buff2”, “Buff2”, instance.parameters.clr_buff2, first); Buff3 = instance:addStream(“Buff3”, core.Bar, name .. “.Buff3”, “Buff3”, instance.parameters.clr_buff3, first); Buff4 = instance:addStream(“Buff4”, core.Bar, name .. “.Buff4”, “Buff4”, instance.parameters.clr_buff4, first); LineBuff = instance:addStream(“LineBuff”, core.Line, name .. “.LineBuff”, “LineBuff”, instance.parameters.clr_Line, first); end
function Update(period, mode) if (period>first) then SAR:update(mode); LineBuff[period]=math.max(SAR.UP[period],SAR.DN[period])-source.close[period]; if LineBuff[period]<0. then if LineBuff[period]>LineBuff[period-1] then Buff1[period]=LineBuff[period]; else Buff2[period]=LineBuff[period]; end else if LineBuff[period]>LineBuff[period-1] then Buff3[period]=LineBuff[period]; else Buff4[period]=LineBuff[period]; end end end end`
MT4/Mq4 version viewtopic.php?f=38&t=63980&p=108612#p108612
frank62 · Sun Jun 13, 2010 10:38 am
Hello I have instal this SAR oscillator! Unfortunadly I cant see it on the chart. Alexander can u check this SAR oscillator again please? I want to say that in this forum is an excelent work,thanks much!
Checkz · Sat Sep 11, 2010 6:49 am
CAN THIS BE TURNED INTO A MULTI HEAT MAP.IT WOULD BE NICE
Apprentice · Sat Sep 11, 2010 7:01 am
Added to development cue.
Alexander.Gettinger · Tue Sep 14, 2010 11:15 am
SAR Oscillator Heat Map indicator.

Code: Select all `– Adds SAR parameter function AddMvaParam(id, frame, step, max) indicator.parameters:addString(“B” .. id, “Time frame for avegage “ .. id, “”, frame); indicator.parameters:setFlag(“B” .. id, core.FLAG_PERIODS); indicator.parameters:addDouble(“Step” .. id, “Step “ .. id .. “ parameter”, “”, step); indicator.parameters:addDouble(“Max” .. id, “Max “ .. id .. “ parameter”, “”, max); end
function Init() indicator:name(“Multitimeframe SAR Heat Map”); indicator:description(“”); indicator:requiredSource(core.Bar); indicator:type(core.Oscillator);
indicator.parameters:addGroup(“Calculation”); AddMvaParam(1, “H1”, 0.02, 0.2); AddMvaParam(2, “H2”, 0.02, 0.2); AddMvaParam(3, “H4”, 0.02, 0.2); AddMvaParam(4, “H6”, 0.02, 0.2); AddMvaParam(5, “H8”, 0.02, 0.2); indicator.parameters:addGroup(“Display”); indicator.parameters:addColor(“clrUP1”, “Up color 1”, “”, core.rgb(0, 255, 0)); indicator.parameters:addColor(“clrUP2”, “Up color 2”, “”, core.rgb(0, 128, 0)); indicator.parameters:addColor(“clrDN1”, “Down color 1”, “”, core.rgb(255, 0, 0)); indicator.parameters:addColor(“clrDN2”, “Down color 2”, “”, core.rgb(128, 0, 0)); indicator.parameters:addColor(“clrLBL”, “Label color”, “”, core.COLOR_LABEL); end
– list of streams local streams = {} – the indicator source local source; local day_offset, week_offset; local dummy; local host; local U1 = {}; local D1 = {}; local U2 = {}; local D2 = {}; local L = {}; local SAR = nil;
function Prepare() source = instance.source; host = core.host;
day_offset = host:execute(“getTradingDayOffset”); week_offset = host:execute(“getTradingWeekOffset”);
CheckBarSize(1); CheckBarSize(2); CheckBarSize(3); CheckBarSize(4); CheckBarSize(5);
local i; local name = profile:id() .. “(“ .. source:name() .. “,”; for i = 1, 5, 1 do name = name .. “(“ .. instance.parameters:getDouble(“Step” .. i) .. “, “ .. instance.parameters:getDouble(“Max” .. i) .. “)”; L[i] = instance.parameters:getString(“B” .. i) .. “ “ .. instance.parameters:getString(“Step” .. i) .. “)”; end name = name .. “)”; instance:name(name); dummy = instance:addStream(“D”, core.Line, name .. “.D”, “D”, instance.parameters.clrLBL, 20); dummy:addLevel(0); dummy:addLevel(120); for i = 1, 5, 1 do U1[i] = instance:createTextOutput (“U1” .. i, “U1” .. i, “Wingdings”, 10, core.H_Center, core.V_Center, instance.parameters.clrUP1, 0); D1[i] = instance:createTextOutput (“D1” .. i, “D1” .. i, “Wingdings”, 10, core.H_Center, core.V_Center, instance.parameters.clrDN1, 0); U2[i] = instance:createTextOutput (“U2” .. i, “U2” .. i, “Wingdings”, 10, core.H_Center, core.V_Center, instance.parameters.clrUP2, 0); D2[i] = instance:createTextOutput (“D2” .. i, “D2” .. i, “Wingdings”, 10, core.H_Center, core.V_Center, instance.parameters.clrDN2, 0); end end
function CheckBarSize(id) local s, e, s1, e1; s, e = core.getcandle(source:barSize(), core.now(), 0, 0); s1, e1 = core.getcandle(instance.parameters:getString(“B” .. id), core.now(), 0, 0); assert ((e - s) <= (e1 - s1), “The chosen time frame must be equal to or bigger than the chart time frame!”); end
function Update(period, mode) local i, p, loading; – request for data and create MVA’s if they do not exist yet. if SAR == nil then SAR = {}; for i = 1, 5, 1 do stream = registerStream(i, instance.parameters:getString(“B” .. i), instance.parameters:getDouble(“Step” .. i)); SAR[i] = core.indicators:create(“SAR_OSCILLATOR”, getPriceStream(stream), instance.parameters:getDouble(“Step” .. i), instance.parameters:getDouble(“Max” .. i)); end end
for i = 1, 5, 1 do p, loading = getPeriod(i, period); if p ~= -1 then SAR[i]:update(mode); if SAR[i].LineBuff:hasData(p) then if SAR[i].Buff1[p] == SAR[i].LineBuff[p] then U1[i]:set(period, (6 - i) * 20, “\110”); end if SAR[i].Buff2[p] == SAR[i].LineBuff[p] then U2[i]:set(period, (6 - i) * 20, “\110”); end if SAR[i].Buff3[p] == SAR[i].LineBuff[p] then D1[i]:set(period, (6 - i) * 20, “\110”); end if SAR[i].Buff4[p] == SAR[i].LineBuff[p] then D2[i]:set(period, (6 - i) * 20, “\110”); end end end end
if period == source:size() - 1 then for i = 1, 5, 1 do host:execute(“drawLabel”, i, source:date(period), (6 - i) * 20, L[i]); end end end
function getPriceStream(stream) local s = instance.parameters.S; return stream; end
– register stream – @param barSize Stream’s bar size – @param extent The size of the required exten – @return the stream reference function registerStream(id, barSize, extent) local stream = {}; local s1, e1, length; local from, to;
s1, e1 = core.getcandle(barSize, core.now(), 0, 0); length = math.floor((e1 - s1) * 86400 + 0.5);
– the size of the source if barSize == source:barSize() then stream.data = source; stream.barSize = barSize; stream.external = false; stream.length = length; stream.loading = false; stream.extent = extent; stream.loading = false; else stream.data = nil; stream.barSize = barSize; stream.external = true; stream.length = length; stream.loading = false; stream.extent = extent; local from, dataFrom from, dataFrom = getFrom(barSize, length, extent); if (source:isAlive()) then to = 0; else t, to = core.getcandle(barSize, source:date(source:size() - 1), day_offset, week_offset); end stream.loading = true; stream.loadingFrom = from; stream.dataFrom = dataFrom; stream.data = host:execute(“getHistory”, id, source:instrument(), barSize, from, to, source:isBid()); setBookmark(0); end streams[id] = stream; return stream.data; end
function getPeriod(id, period) local stream = streams[id]; assert(stream ~= nil, “Stream is not registered”); local candle, from, dataFrom, to; if stream.external then candle = core.getcandle(stream.barSize, source:date(period), day_offset, week_offset); if candle < stream.dataFrom then setBookmark(period); if stream.loading then return -1, true; end from, dataFrom = getFrom(stream.barSize, stream.length, stream.extent); stream.loading = true; stream.loadingFrom = from; stream.dataFrom = dataFrom; host:execute(“extendHistory”, id, stream.data, from, stream.data:date(0)); return -1, true; end
if (not(source:isAlive()) and candle > stream.data:date(stream.data:size() - 1)) then setBookmark(period); if stream.loading then return -1, true; end stream.loading = true; from = bf_data:date(bf_data:size() - 1); to = candle; host:execute(“extendHistory”, id, stream.data, from, to); end
local p; p = findDateFast(stream.data, candle, true); return p, stream.loading; else return period; end end
function setBookmark(period) local bm; bm = dummy:getBookmark(1); if bm < 0 then bm = period; else bm = math.min(period, bm); end dummy:setBookmark(1, bm);
end
– get the from date for the stream using bar size and extent and taking the non-trading periods – into account function getFrom(barSize, length, extent) local from, loadFrom; local nontrading, nontradingend;
from = core.getcandle(barSize, source:date(source:first()), day_offset, week_offset); loadFrom = math.floor(from * 86400 - length * extent + 0.5) / 86400; nontrading, nontradingend = core.isnontrading(from, day_offset); if nontrading then – if it is non-trading, shift for two days to skip the non-trading periods loadFrom = math.floor((loadFrom - 2) * 86400 - length * extent + 0.5) / 86400; end return loadFrom, from; end
– the function is called when the async operation is finished function AsyncOperationFinished(cookie) local period; local stream = streams[cookie]; if stream == nil then return ; end stream.loading = false; period = dummy:getBookmark(1); if (period < 0) then period = 0; end loading = false; instance:updateFrom(period); end
– find the date in the stream using binary search algo. function findDateFast(stream, date, precise) local datesec = nil; local periodsec = nil; local min, max, mid;
datesec = math.floor(date * 86400 + 0.5)
min = 0; max = stream:size() - 1;
if max < 1 then return -1; end
while true do mid = math.floor((min + max) / 2); periodsec = math.floor(stream:date(mid) * 86400 + 0.5); if datesec == periodsec then return mid; elseif datesec > periodsec then min = mid + 1; else max = mid - 1; end if min > max then if precise then return -1; else return min - 1; end end end end`
Apprentice · Mon Feb 05, 2018 8:03 am
The Indicator was revised and updated.