Закрытый бар и активный бар

From FxCodeBaseWiki
Jump to: navigation, search

Проблема

Как вы, наверное, заметили, большинство сигналов, применяемых к определенному интервалу, проверяют рыночные условия и показывают сигналы только после полного закрытия бара. Например, в случае применения к почасовым барам сигнал, который появился в 15:00, будет показан в 16:00, т. е. только тогда, когда закроется бар 15:00. Это кажется неудобным, поскольку выглядит как часовая задержка сигнала.

Верно? Возможно, да. Но давайте представим, что произойдет, если мы будем проверять рыночные условия по активному бару, который изменяется всякий раз, когда появляется новая цена (т. е. тик). Создадим простой индикатор, показывающий стрелку на барах, у которых цена закрытия выше, чем у предшественников.

function Init()
    indicator:name("Show bars where current close is higher than previous");
    indicator:description("");
    indicator:requiredSource(core.Bar);
    indicator:type(core.Indicator);

    indicator.parameters:addColor("clr", "Label Color", "", core.COLOR_LABEL);
end

local source;
local mark;
local first;

function Prepare()
    source = instance.source;
    local name = profile:id();
    instance:name(name);
    first = source:first() + 1;
    mark = instance:createTextOutput ("Mark", "Mark", "Wingdings", 10, core.H_Center, core.V_Top, instance.parameters.clr, 0);
end

function Update(period, mode)
    if period > first then
        if source.close[period] > source.close[period - 1] then
            mark:set(period, source.close[period], "\226");
        end
    end
end

Теперь применим этот индикатор к графику. Рекомендует использовать 1-минутный интервал, поскольку тогда вы получите результат, который я покажу вам через несколько минут. После применения индикатора все выглядит нормально. Бары с более высокой ценой закрытия отмечаются стрелками. Оставим индикатор на несколько минут. Ой… Появляются странные ложные сигналы. Почему? По правде говоря, все просто. Индикатор вызывается всякий раз, когда появляется новая цена. В момент вызова последняя цена отображается как цена закрытия последнего бара… поэтому, даже если какой-либо бар не соответствует условиям рынка в конечном итоге, он может им соответствовать в середине интервала. Посмотрите на снимок экрана:

CloseandlivebarRU.png

(нажмите на изображение, чтобы увидеть его в полном размере)

Ложные сигналы появляются, как только индикатор начинает работать с активными данными.

Давайте посмотрим. Пока индикатор применяется к историческим данным, функция обновления вызывается только один раз и получает итоговую версию бара. Но для активных баров индикатор вызывается столько раз, сколько тиков появляется за время бара. Если вы вспомните, как выглядел бар до его завершения (посмотрите на последний ложный сигнал на приведенном выше снимке экрана), то увидите, что иногда он действительно СООТВЕТСТВОВАЛ условиям рынка.

Иначе говоря, почти для всех сигналов и для многих индикаторов индикатор способен производить «шум» – выдавать ложный сигнал, даже если в итоговой версии бара сигнал не появляется. Такие ложные сигналы могут привести к ошибочным решениям, поэтому лучше всего дождаться, пока бар завершится, и можно будет точно проверить, выполнено ли условие сигнала во время бара или нет.

Что делать в такой ситуации?

В индикаторах

Лучше всего обрабатывать бар только в том случае, если он закрывается. Проверить, закрыт ли бар, можно по «серийному номеру», а обрабатывать последний бар активной истории следует только в том случае, если он полностью завершен (перестал быть активным). Внесем соответствующие изменения в приведенный выше индикатор:

function Init()
    indicator:name("Show bars where current close is higher than previous");
    indicator:description("");
    indicator:requiredSource(core.Bar);
    indicator:type(core.Indicator);

    indicator.parameters:addColor("clr", "Label Color", "", core.COLOR_LABEL);
end

local source;
local mark;
local first;

function Prepare()
    source = instance.source;
    local name = profile:id();
    instance:name(name);
    first = source:first() + 1;
    mark = instance:createTextOutput ("Mark", "Mark", "Wingdings", 10, core.H_Center, core.V_Top, instance.parameters.clr, 0);
end

local serial = nil;

function Update(period, mode)
    if period > first then
        if source:isAlive() and                                 -- if the history we applied to is alive
           period == source:size() - 1 then                     -- and this is the last value (live bar)
           if serial ~= source:serial(source:size() - 1) then   -- and the last bar is a new bar
                serial = source:serial(source:size() - 1);      -- remember a new last bar
                period = period - 1;                            -- and force to process the previous (e.g. the most
                                                                -- recently finished bar
            else
                return;                                         -- the bar is not changed, so
                                                                -- just do not process it
            end
        end
        if source.close[period] > source.close[period - 1] then
            mark:set(period, source.close[period], "\226");
        end
    end
end


Готово, больше никакого шума!

В стратегиях

Если вы используете управление подписками с помощью helper.lua, ничего делать не нужно. Помощник будет отправлять вам уведомления только после того, как бар полностью закроется.

Если вы включили подписку самостоятельно, поступайте так же, как с индикаторами – не проверяйте рыночные условия, пока в подписанном интервале не появится новый бар.

Эта Статья На Других Языках

Language: English  • español • français • русский • 中文 • 中文(繁體)‎