Access to previous DATA from another TimeFrame
Posted:
Sat Apr 04, 2020 9:41 pm
by ReinaldoM
I wish you a wonderfull day,
I want to compare two points on a moving average from another time frame,(example: (MVA 50) I want to compare ma.DATA[ma.DATA:size() - 1] and ma.DATA[ma.DATA:size() - 10)] in order to know if moving average follos the trend of the first 40 points of the MVA) to show the result from DRAW
I can access just the first three of them, it works perfect, BUT, beyond ma.DATA[ma.DATA:size() - 3) there is SPECIFIED INDEX IS OUT OF RANGE
src = core.host:execute("getSyncHistory", source:instrument(), TF, source:isBid(), math.min(300, first), 1000, 2000);
function AsyncOperationFinished(cookie, success, error)
if cookie == 200 then
loading = true;
elseif cookie == 100 then
loading = false;
end
local FLAG = false;
if loading then
FLAG = true;
end
if cookie == 1 and (not FLAG) then
MA:update(core.UpdateLast);
txt = MA.DATA[ma.DATA:size() - 10];
end
if FLAG then
core.host:execute("setStatus", "Loading");
else
instance:updateFrom(0);
end
return core.ASYNC_REDRAW;
end
Re: Access to previous DATA from another TimeFrame
Posted:
Sun Apr 05, 2020 4:59 am
by Apprentice
I see several potential problems.
Can you provide a complete code?
I will fix them when you provide it.
For you try to add something like this.
Will ensure we have 10 elements.
if ( ma.DATA:size() ) < 11 then
return;
end
Re: Access to previous DATA from another TimeFrame
Posted:
Sun Apr 05, 2020 8:44 am
by ReinaldoM
Apprentice wrote:I see several potential problems.
Can you provide a complete code?
I will fix them when you provide it.
For you try to add something like this.
Will ensure we have 10 elements.
if ( ma.DATA:size() ) < 11 then
return;
end
Thanks for your time, I appreciate it, here is the code
- Code: Select all
function Init()
indicator:name("Slope");
indicator:description("Calculate slope of x percentage of MVA");
indicator:requiredSource(core.Bar);
indicator:type(core.Indicator);
indicator.parameters:addGroup("TimeFrame");
indicator.parameters:addString("TF", "Time frame", "", "m5");
indicator.parameters:setFlag("TF", core.FLAG_PERIODS);
indicator.parameters:addGroup("Moving Average");
chooseMA("MMethod", "M Method", "MVA", "EMA");
indicator.parameters:addInteger("MPeriod", "M Period", "", 10);
chooseMA("TMethod", "T Method", "MVA", "EMA");
indicator.parameters:addInteger("TPeriod", "T Period", "", 50);
chooseMA("QMethod", "Q Method", "MVA", "EMA");
indicator.parameters:addInteger("QPeriod", "Q Period", "", 30);
indicator.parameters:addGroup("Slope");
indicator.parameters:addDouble("MinSlopeChange", "Minimun Slope Change", "", 0.5);
indicator.parameters:addInteger("Percentage", "Change MA Percentage", "", 30);
indicator.parameters:addGroup("Assistant");
indicator.parameters:addInteger("Row", "Row", "", 0);
indicator.parameters:addString("Vertical", "Vertical placement","" , "Top");
indicator.parameters:addStringAlternative("Vertical", "Top", "" , "Top");
indicator.parameters:addStringAlternative("Vertical", "Bottom", "" , "Bottom");
indicator.parameters:addString("Horizontal", "Horizontal Placement","" , "Right");
indicator.parameters:addStringAlternative("Horizontal", "Right", "" , "Right");
indicator.parameters:addStringAlternative("Horizontal", "Left", "" , "Left");
indicator.parameters:addInteger("Size", "Font size", "", 8)
indicator.parameters:addColor("Color", "Color", "", core.rgb(255, 255, 255));
indicator.parameters:addGroup("Notification");
indicator.parameters:addBoolean("PlaySound", "Play Sound", "", true);
indicator.parameters:addBoolean("RecurrentSound", "Recurrent Sound", "", false);
indicator.parameters:addFile("SoundFile", "Sound File", "", "");
indicator.parameters:setFlag("SoundFile", core.FLAG_SOUND);
end
function chooseMA(ma, txt, x1, x2)
indicator.parameters:addString(ma, txt, "" , x1);
indicator.parameters:addStringAlternative(ma, x1, "" , x1);
indicator.parameters:addStringAlternative(ma, x2, "" , x2);
end
local source = nil;
local first;
local M, M1, MMethod, MPeriod;
local T, T1, TMethod, TPeriod;
local Q, Q1, QMethod, QPeriod;
local MinSlopeChange;
local Percentage;
local Row;
local Vertical;
local Horizontal;
local Size;
local Color;
local PlaySound;
local RecurrentSound;
local SoundFile;
local init = false;
local txt = "";
local last;
local loading = false;
local src = nil;
function Prepare(nameOnly)
source = instance.source;
first = source:first();
TF = instance.parameters.TF;
MMethod = instance.parameters.MMethod;
MPeriod = instance.parameters.MPeriod;
TPeriod = instance.parameters.TPeriod;
TMethod = instance.parameters.TMethod;
QPeriod = instance.parameters.QPeriod;
QMethod = instance.parameters.QMethod;
MinSlopeChange = instance.parameters.MinSlopeChange * source:pipSize();
Percentage = instance.parameters.Percentage / 100;
Row = instance.parameters.Row;
Vertical = instance.parameters.Vertical;
Horizontal = instance.parameters.Horizontal;
Size = instance.parameters.Size;
Color = instance.parameters.Color;
PlaySound = instance.parameters.PlaySound;
if PlaySound then
RecurrentSound = instance.parameters.RecurrentSound;
SoundFile = instance.parameters.SoundFile;
else
SoundFile = nil;
end
assert(not(PlaySound) or (PlaySound and SoundFile ~= ""), "Sound file must be specified");
local name = profile:id() .. "(" .. source:name() .. ")";
instance:name(name);
if nameOnly then
return;
end
M1 = core.indicators:create(MMethod, source, MPeriod);
T1 = core.indicators:create(TMethod, source, TPeriod);
Q1 = core.indicators:create(QMethod, source, QPeriod);
first = math.max(M1.DATA:first(), T1.DATA:first(), Q1.DATA:first());
src = core.host:execute("getSyncHistory", source:instrument(), TF, source:isBid(), math.min(300, first), 100, 200);
loading = true;
M = core.indicators:create(MMethod, src, MPeriod);
T = core.indicators:create(TMethod, src, TPeriod);
Q = core.indicators:create(QMethod, src, QPeriod);
core.host:execute("setTimer", 1, 1);
instance:ownerDrawn(true);
end
function Update(period, mode)
if period < first or (not source:hasData(period)) then
return ;
end
end
function ReleaseInstance()
core.host:execute("killTimer", 1);
end
function AsyncOperationFinished(cookie, success, error)
if cookie == 200 then
loading = true;
core.host:execute("setStatus", "Loading");
elseif cookie == 100 then
assert(success, error);
loading = false;
end
if not loading then
M:update(core.UpdateLast);
T:update(core.UpdateLast);
Q:update(core.UpdateLast);
soundFlag = false;
txt = process();
instance:updateFrom(0);
end
return core.ASYNC_REDRAW;
end
function process()
local msg = "";
signal = false;
local mSlope = slopeMA(M, MPeriod);
local TSlope = slopeMA(T, TPeriod);
local QSlope = slopeMA(Q, QPeriod);
msg = mSlope .. " " .. TSlope .. " " .. QSlope;
return msg;
end
function slopeMA(ma, maPeriod)
local curve = math.ceil(maPeriod * Percentage);
local repsUp = 0;
local repsDn = 0;
local slope = "";
for i = 1, curve do
if fetchData(ma, (i - 1)) > fetchData(ma, i) then
repsUp = repsUp + 1;
end
if fetchData(ma, (i - 1)) < fetchData(ma, i) then
repsDn = repsDn + 1;
end
end
if repsUp == curve and math.abs(lastData(ma) - fetchData(ma, curve)) > MinSlopeChange then
slope = "up";
elseif repsDn == curve and math.abs(lastData(ma) - fetchData(ma, curve)) > MinSlopeChange then
slope = "dn";
else
slope = "nt"
end
return slope;
end
function lastClose(x)
return x.close[x.close:size() - 2];
end
function lastData(x)
return x.DATA[x.DATA:size() - 2];
end
function fetchData(ma, p)
return ma.DATA[ma.DATA:size() - (2 - p)];
end
function decimal(n)
return string.format("%." .. 1 .. "f", n);
end
function greaterMA(x, y)
if lastData(x) > lastData(y) then
return true;
else
return false;
end
end
function notLess(x, y)
if lastData(x) >= lastData(y) then
return true;
else
return false;
end
end
function notMore(x, y)
if lastData(x) <= lastData(y) then
return true;
else
return false;
end
end
function candleTouch(ma)
local touch = false;
if src.high[src.high:size() - 2] >= lastData(Q) and src.low[src.low:size() - 2] <= lastData(Q) then
touch = true;
end
return touch;
end
function crossingMA(p)
local cross = "";
if core.crossesOver(M.DATA, T.DATA, p) then
cross = "up";
elseif core.crossesUnder(M.DATA, T.DATA, p) then
cross = "dn";
else
cross = "no";
end
return cross;
end
function soundAlert()
signal = true;
terminal:alertSound(SoundFile, RecurrentSound);
end
function Draw(stage, context)
if stage ~= 2 or loading then
return;
end
local top = context:top();
local bottom = context:bottom();
local right = context:right();
local left = context:left();
core.host:execute("setStatus", "Ready");
if not init then
context:createFont(1, "Verdana", context:pointsToPixels(Size / 2), context:pointsToPixels(Size), 0);
init = true;
end
local msg = " " .. txt .. " ";
local width, height = context:measureText (1, msg, 0);
context:drawText(1, msg, Color, -1,
horizontalAxis(left, right, width, 1), verticalAxis(top, bottom, height, 0),
horizontalAxis(left, right, width, 2), verticalAxis(top, bottom, height, 1),
context.CENTER, 0);
end
function verticalAxis(top, bottom, height, line)
if Vertical == "Top" then
return (top + height * (Row + 1)) - height + line * height;
else
return (bottom - height * Row) - height + line * height;
end
end
function horizontalAxis(left, right, width, x)
if Horizontal == "Left" then
return left + width * (x - 1);
else
return right - width * (1 - (x - 1));
end
end
Re: Access to previous DATA from another TimeFrame
Posted:
Sun Apr 05, 2020 9:40 am
by ReinaldoM
Apprentice wrote:I see several potential problems.
Can you provide a complete code?
I will fix them when you provide it.
For you try to add something like this.
Will ensure we have 10 elements.
if ( ma.DATA:size() ) < 11 then
return;
end
I found the problem, thank you for your time