Access to previous DATA from another TimeFrame

Moderator: admin

Access to previous DATA from another TimeFrame

Postby ReinaldoM » Sat Apr 04, 2020 9:41 pm

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
ReinaldoM
 
Posts: 9
Joined: Sun Jul 01, 2018 4:12 pm

Re: Access to previous DATA from another TimeFrame

Postby Apprentice » Sun Apr 05, 2020 4:59 am

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
User avatar
Apprentice
FXCodeBase: Confirmed User
 
Posts: 25428
Joined: Thu Dec 31, 2009 11:59 am
Location: Zagreb, Croatia

Re: Access to previous DATA from another TimeFrame

Postby ReinaldoM » Sun Apr 05, 2020 8:44 am

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
ReinaldoM
 
Posts: 9
Joined: Sun Jul 01, 2018 4:12 pm

Re: Access to previous DATA from another TimeFrame

Postby ReinaldoM » Sun Apr 05, 2020 9:40 am

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
ReinaldoM
 
Posts: 9
Joined: Sun Jul 01, 2018 4:12 pm


Return to Indicator Development

Who is online

Users browsing this forum: No registered users and 3 guests