FXCM Forex Trading

Trading Session Hours Highlight (closed)

Here you can post and download custom indicators. PLEASE: Do not start topics unless you are posting your own indicator, they will be moved to appropriate section even if you do.

Moderator: admin

Trading Session Hours Highlight (closed)

Postby Nikolay.Gekht » Mon May 03, 2010 5:35 pm

The post is closed. Please read the post about new version of the indicator for August, 27 2010 trading station release: viewtopic.php?f=17&t=1974.

The indicator highlights the trading sessions for the New York, London and Tokyo

Sidney Trading Session: 5:00 PM - 2:00 AM (EDT/EST)
Tokyo Trading Session: 7:00 PM - 4:00 AM (EDT/EST)
London Trading Session: 3:00 AM - 12:00 PM (EDT/EST)
New York Trading Session: 8:00 AM - 5:00 PM (EDT/EST)

See more about the trading session here: http://www.fxwords.com/f/fx-market-hours.html and here: http://www.forexmarkethours.com/

You can choose any combination of these three sessions to show. The session also highlights the highest and the lowest price during the session.

Because N-hours candles are always aligned against the FXCM's trading day (17:00EDT/EST), the indicator cannot highlight the trading sessions on the time frames higher than 1 hour.

tradingsession.png


Download the indicator:
TRADESESSIONS.lua
(11.29 KiB) Downloaded 7261 times


Code: Select all
-- Indicator profile initialization routine
-- Defines indicator profile properties and indicator parameters
function Init()
    indicator:name("The indicator highlights trade sessions");
    indicator:description("The indicator can be applied on 1-minute to 1-hour charts");
    indicator:requiredSource(core.Bar);
    indicator:type(core.Indicator);

    indicator.parameters:addBoolean("NY_S", "Show New York session (8:00 am - 5:00 pm EST/EDT)", "", true);
    indicator.parameters:addColor("NY_C", "New York session color", "", core.rgb(255, 0, 0));
    indicator.parameters:addBoolean("LO_S", "Show London session (3:00 am - 12:00 pm EST/EDT)", "", true);
    indicator.parameters:addColor("LO_C", "New York session color", "", core.rgb(0, 255, 0));
    indicator.parameters:addBoolean("TO_S", "Show Tokyo session (7:00 pm - 4:00 am EST/EDT)", "", true);
    indicator.parameters:addColor("TO_C", "Tokyo session color", "", core.rgb(0, 0, 255));
    indicator.parameters:addBoolean("SI_S", "Show Sidney session (5:00 pm - 2:00 am EST/EDT)", "", true);
    indicator.parameters:addColor("SI_C", "Sidney session color", "", core.rgb(0, 255, 255));
    indicator.parameters:addInteger("HL", "Highlight transparency (%)", "", 90, 0, 100);
end

-- Indicator instance initialization routine
-- Processes indicator parameters and creates output streams
-- Parameters block
local first;
local source = nil;
local host;
local new_york = nil;
local london = nil;
local tokyo = nil;
local sidney = nil;
local dummy = nil;
local day_offset, week_offset;

-- Routine
function Prepare()
    source = instance.source;
    first = source:first();
    host = core.host;
    day_offset = host:execute("getTradingDayOffset");
    week_offset = host:execute("getTradingWeekOffset");


    local s, e;
    s, e = core.getcandle(source:barSize(), 0, 0, 0);
    s = math.floor(s * 86400 + 0.5);  -- >>in seconds
    e = math.floor(e * 86400 + 0.5);  -- >>in seconds
    assert((e - s) < 3600, "The source time frame must not be bigger than 1 hour");

    local name = profile:id() .. "()";
    instance:name(name);
    if instance.parameters.NY_S then
        -- 8 am to 5 pm
        new_york = CreateSession(8, 9, instance.parameters.NY_C, "NewYork", name);
    end
    if instance.parameters.LO_S then
        -- 3 am to 12 pm
        london = CreateSession(3, 9, instance.parameters.LO_C, "London", name);
    end
    if instance.parameters.TO_S then
        -- 7 pm of yesterday to 4 am of today
        tokyo = CreateSession(-5, 9, instance.parameters.TO_C, "Tokyo", name);
    end
    if instance.parameters.SI_S then
        -- 5 pm of yesterday to 2 am of today
        sidney = CreateSession(-7, 9, instance.parameters.SI_C, "Sidney", name);
    end

    dummy = instance:addInternalStream(0, 0);   -- the stream for bookmarking
end

local ref = nil;    -- the reference 1-hour source

-- Indicator calculation routine
function Update(period)
    if period >= first then
        if ref == nil then
            ref = registerStream(0, "H1", 24);  -- open 1-hour stream which returns 24 bars BEFORE the start of the source collection.
        end
    end

    Process(new_york, period);
    Process(london, period);
    Process(tokyo, period);
    Process(sidney, period);
end

-- Process the specified session
function Process(session, period)
    if session == nil then
        return ;
    end
    -- find the start of the session
    local date = source:date(period);       -- bar date;
    local sfrom, sto;

    -- 1) calculate the session to which the specified date belongs
    local t;
    t = math.floor(date * 86400 + 0.5);     -- date/time in seconds

    -- shift the date so it is in the virtual time zone in which 0:00 is the begin of the session
    t = t - session.from * 3600;
    -- truncate to the day only.
    t = math.floor(t / 86400 + 0.5) * 86400;
    -- and shift it back to est time zone
    t = t + session.from * 3600;

    sfrom = t;                          -- begin of the session
    sto = sfrom + session.len * 3600;   -- end of the session

    sfrom = sfrom / 86400;
    sto = sto / 86400;

    -- process only if the date/time is inside the session
    if date >= sfrom and date < sto then
        -- find the hour bar of the beginning of the day
        local ref_period, loading;
        ref_period, loading = getDate(0, sfrom, false, period);
        if ref_period == -1 then
            -- the first bar is not found at all
            -- or the date is being loaded
            return ;
        end
        local hi = 0;
        local lo = 100000000000000;
        while true do
            local t = ref:date(ref_period);
            if t >= sfrom then
                if t >= sto then
                    break;
                end
                if ref.high[ref_period] > hi then
                    hi = ref.high[ref_period];
                end
                if ref.low[ref_period] < lo then
                    lo = ref.low[ref_period];
                end
            end
            ref_period = ref_period + 1;
            if ref_period >= ref:size() then
                break;
            end
        end
        if hi ~= 0 then
            session.begin[period] = sfrom;
            session.high[period] = hi;
            session.highband[period] = hi;
            session.low[period] = lo;
            session.lowband[period] = lo;
            while period > 1 and session.begin[period] == session.begin[period - 1] do
                if session.high[period] ~= hi or
                   session.low[period] ~= low then
                    session.high[period - 1] = hi;
                    session.highband[period - 1] = hi;
                    session.low[period - 1] = lo;
                    session.lowband[period - 1] = lo;
                    period = period - 1;
                else
                    break;
                end   
            end
        end
    else
        session.begin[period] = 0;
    end
end

-- Create the session description
-- from - the offset in hours again 0:00 of the EST canlendar day
-- len - length of the session in hours
-- color - color for lines and fill area
-- name - of the session
-- iname - the name of the indicator
function CreateSession(from, len, color, name, iname)
    local session = {};
    local n;
    session.name = name;
    session.from = from;
    session.len = len;
    n = name .. "_H";
    session.high = instance:addStream(n, core.Line, iname .. "." .. n, n, color, first);
    n = name .. "_L";
    session.low = instance:addStream(n, core.Line, iname .. "." .. n, n, color, first);
    n = name .. "_HB";
    session.highband = instance:addStream(n, core.Line, iname .. "." .. n, n, color, first);
    n = name .. "_LB";
    session.lowband = instance:addStream(n, core.Line, iname .. "." .. n, n, color, first);
    session.begin = instance:addInternalStream(0, 0);
    instance:createChannelGroup(name, name, session.highband, session.lowband, color, 100 - instance.parameters.HL);
    return session;
end

local streams = {}

-- register stream
-- @param barSize       Stream's bar size
-- @param extent        The size of the required extent (number of periods to look the back)
-- @return the stream reference
function registerStream(id, barSize, extent)
    local stream = {};
    local s1, e1, length;
    local from, to;

    s1, e1 = core.getcandle(barSize, 0, 0, 0);
    length = math.floor((e1 - s1) * 86400 + 0.5);

    stream.data = nil;
    stream.barSize = barSize;
    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 = from;
    stream.data = host:execute("getHistory", id, source:instrument(), barSize, from, to, source:isBid());
    setBookmark(0);

    streams[id] = stream;
    return stream.data;
end

function getDate(id, candle, precise, period)
    local stream = streams[id];
    assert(stream ~= nil, "Stream is not registered");
    local from, dataFrom, to;
    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 = from;
        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, precise);
    return p, stream.loading;
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
Nikolay.Gekht
FXCodeBase: Base Builder
 
Posts: 1224
Joined: Wed Dec 16, 2009 6:39 pm
Location: Cary, NC

Re: Trading Session Hours Highlight

Postby a135711 » Mon May 03, 2010 6:24 pm

Outstanding!
a135711
 
Posts: 39
Joined: Fri Apr 30, 2010 12:01 pm

Re: Trading Session Hours Highlight

Postby a135711 » Mon May 03, 2010 6:38 pm

can it be extended to highlight an oscillator window in the exact same way?
a135711
 
Posts: 39
Joined: Fri Apr 30, 2010 12:01 pm

Re: Trading Session Hours Highlight

Postby cayantgee » Wed May 05, 2010 7:18 am

Hi this looks like a useful tool. WHen I load it has the following error
"4:attempt to index global indicator (a nil value)"

Any idea why this is so ?

Thanks
cayantgee
 
Posts: 3
Joined: Sat Apr 10, 2010 9:55 am

Re: Trading Session Hours Highlight

Postby Nikolay.Gekht » Wed May 05, 2010 10:07 am

cayantgee wrote:Any idea why this is so ?

Just use the Chart->Manage Custom Indicators.
The step-by-step instruction on how to install the indicator is here:
viewtopic.php?f=17&t=17

Do not be confused with signals:
viewtopic.php?f=29&t=602
Nikolay.Gekht
FXCodeBase: Base Builder
 
Posts: 1224
Joined: Wed Dec 16, 2009 6:39 pm
Location: Cary, NC

Re: Trading Session Hours Highlight

Postby cayantgee » Thu May 06, 2010 7:36 am

Thanks for the tip Nikolay. It worked.
cayantgee
 
Posts: 3
Joined: Sat Apr 10, 2010 9:55 am

Re: Trading Session Hours Highlight

Postby a135711 » Fri Jun 11, 2010 1:40 pm

hello, i need the following functionality on the tradesessions indicator

first, i need the session period divided into 5 time periods based with a line that is drawn from the session high to the session low from the session start to the session end.

second, i need the session range to be divided according to fibo, that is 38,50,62 lines and the extensions 1.38 , 1.5, 1.62. the extensions should be both above and below the range. there is no need for numbers or percents to be visible, just the lines.
thanks

Image
a135711
 
Posts: 39
Joined: Fri Apr 30, 2010 12:01 pm

Re: Trading Session Hours Highlight

Postby Nikolay.Gekht » Tue Jun 15, 2010 9:59 am

a135711 wrote:hello, i need the following functionality on the tradesessions indicator

As far as I can see, in that case, the session high/low will change during the session life time, especially during the start period, so these lines will also move and will get their final state when the session is finished. Shouldn't it be something like Breakout indicator?
Nikolay.Gekht
FXCodeBase: Base Builder
 
Posts: 1224
Joined: Wed Dec 16, 2009 6:39 pm
Location: Cary, NC

Re: Trading Session Hours Highlight

Postby a135711 » Tue Jun 15, 2010 3:10 pm

As far as I can see, in that case, the session high/low will change during the session life time, especially during the start period, so these lines will also move and will get their final state when the session is finished. Shouldn't it be something like Breakout indicator?


the start period of the session should be the start of the session fibo calculations. the end of the session should be the end of the fibo calculations. the fibo calculations and the lines that are drawn from them, like the high low calculations, will indeed, change dynamically over the session period, but are limited to the session only. unlike the breakout indicator, this modification gives me the fibo lines, internal and extended, of the current session only. something i use to to compare session to session price movement,

essentially, i am asking for an autolevels indicator that starts at session start and ends at session end and draws fibo lines, internal and extended, for the session only.
a135711
 
Posts: 39
Joined: Fri Apr 30, 2010 12:01 pm

Re: Trading Session Hours Highlight

Postby Nikolay.Gekht » Tue Jun 15, 2010 4:33 pm

Well. To more questions:
1) Do you want to see these lines for the chosen session only (e.g. NY or London only) or for all currently active sessions?
2) What to do with the lines when the session ends? Should line disappears until the next session begins?
Nikolay.Gekht
FXCodeBase: Base Builder
 
Posts: 1224
Joined: Wed Dec 16, 2009 6:39 pm
Location: Cary, NC

Next

Return to Custom Indicators

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 9 guests