Please see the attached file. This is basically the code from the help file example on getHistory(), with a bit of trace/debug code added. Also, I am using the technique of using the bookmark so that I can go back to the correct period. This also no longer works in the latest version (the bookmark seems disappear). I can work around the bookmark issue by storing the date, and then using findDate(), but since bookmarks are supposed to be the suggested method it should probably work.
code
- Code: Select all
function Init()
indicator:name("Sample oscillator");
indicator:description(" ");
indicator:requiredSource(core.Bar);
indicator:type(core.Oscillator);
indicator.parameters:addString("INST", "The instrument to load", "", "");
indicator.parameters:setFlag("INST", core.FLAG_INSTRUMENTS);
end
local source; -- the indicator source
local other; -- the additional data stream
local loading; -- flag indicating the other data stream is being loaded
local load_from; -- the date/time the data was loaded the last time from
local instrument; -- the instrument to be loaded
local output; -- the indicator output stream;
local host;
local dummy;
function Prepare()
source = instance.source;
host = core.host;
instrument = instance.parameters.INST;
assert(instrument ~= instance.source:instrument(), "Please choose different instrument");
local name;
name = profile:id() .. "(" .. instrument .. ")";
instance:name(name);
output = instance:addStream("other", core.Line, name, "other", core.rgb(255, 0, 0), source:first());
dummy = instance:addInternalStream(source:first());
end
function Update(period, mode)
local from, to;
if period < source:first() then
return ;
end
if period == source:first() then
host:trace(string.format("period == %d, mode = %d", period, mode));
end
if other == nil then
-- if the data is not loaded yet at all
-- load the data
from = source:date(source:first()); -- oldest data to load
if source:isAlive() then -- newest data to load or 0 if the source is "alive"
to = 0;
else
to = source:date(source:size() - 1);
end
load_from = from;
loading = true;
other = core.host:execute("getHistory", 1, instrument, source:barSize(), from, to, source:isBid());
return ;
end
if loading then
return ;
end
local curr_date = source:date(period);
if curr_date < load_from then
-- if the data we are trying to get is oldest than previously loaded
-- the extend the history to the oldest data we can request
from = source:date(source:first()); -- load from the oldest data we have in source
if other:size() > other:first() then
to = other:date(other:first()); -- to the oldest data we have in other instrument
else
to = load_from;
end
load_from = from;
loading = true;
core.host:execute("extendHistory", 1, other, from, to);
dummy:setBookmark(1, period);
return ;
end
-- the date is in the loaded range
-- try to find it
local other_period = core.findDate(other, curr_date, true);
if other_period ~= -1 then
output[period] = other.close[other_period];
end
end
function AsyncOperationFinished(cookie, success, message)
if cookie == 1 then
loading = false;
-- update the indicator output when loading is finished
-- Get the bookmarked period
local period = dummy:getBookmark(1);
if period == -1 then
host:trace("Bookmark was not found");
period = source:first();
end
host:trace("updating from ".. period);
instance:updateFrom(period);
return ;
end
end
here's the Event log after running (oldest at the bottom)
5: UK100 TEST Trace: 'period == 0, mode = 9'. 11/10/2013 19:17:17
4: UK100 TEST Trace: 'period == 0, mode = 7'. 11/10/2013 19:17:17
3: UK100 TEST Trace: 'updating from 0'. 11/10/2013 19:17:17
2: UK100 TEST Trace: 'Bookmark was not found'. 11/10/2013 19:17:17
1: UK100 TEST Trace: 'period == 0, mode = 9'. 11/10/2013 19:17:15
Line 1 is the first call to the update with period = 0
Line 2 is in the Async function, and the bookmark no longer exists !
Line 3 is in the Async function and we are asking to update from 0
Line 4 is the update() as a result of line 3
Line 5 is totally spurious and un-requested call of update() that seems to occur whenever getHistory was used. WHY? It means the indicator is making 2 passes (you can add debug code and see that this is the case).
This particular indicator still works because:
a) it always starts from 0 anyway. If it it started from say period = 10, then the bookmark method would have failed, and it would have started from 0 again.
b) the getHistory() is only called once, and so after the 2nd pass, the indicator works. In my case I want to call getHistory() again, and since each call to getHistory() seems to cause the spurious call to upate I end up in a loop.