FXCM Forex Trading

PPO (Percentage Price Oscillator)

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

PPO (Percentage Price Oscillator)

Postby Nikolay.Gekht » Wed Nov 03, 2010 7:20 pm

stockcharts.com wrote:The Percentage Price Oscillator (PPO) is a momentum oscillator that measures the difference between two moving averages as a percentage of the larger moving average. As with its cousin, MACD, the Percentage Price Oscillator is shown with a signal line, a histogram and a centerline. Signals are generated with signal line crossovers, centerline crossovers and divergences.
read more...


Formula:
PPO = (EMA(12) - EMA(26)) / EMA(26)
SIGNAL = EMA(PPO, 9)
HISTOGRAM = PPO - SIGNAL


PPO.png


Download:
PPO.lua
(6.08 KiB) Downloaded 602 times


Code: Select all
function Init()
    indicator:name("Percentage Price Oscillator");
    indicator:description("A momentum oscillator that measures the difference between two moving averages as a percentage of the larger moving average.");
    indicator:requiredSource(core.Tick);
    indicator:type(core.Oscillator);

    indicator.parameters:addGroup("Calculation");
    indicator.parameters:addInteger("SN", "Fast MA", "", 12, 2, 1000);
    indicator.parameters:addInteger("LN", "Slow MA", "", 26, 2, 1000);
    indicator.parameters:addInteger("IN", "Signal Line", "", 9, 2, 1000);
    indicator.parameters:addString("MA", "Smoothing Method", "The methods marked by an asterisk (*) require the appropriate indicators to be loaded.", "EMA");
    indicator.parameters:addStringAlternative("MA", "MVA", "", "MVA");
    indicator.parameters:addStringAlternative("MA", "EMA", "", "EMA");
    indicator.parameters:addStringAlternative("MA", "LWMA", "", "LWMA");
    indicator.parameters:addStringAlternative("MA", "TMA", "", "TMA");
    indicator.parameters:addStringAlternative("MA", "SMMA*", "", "SMMA");
    indicator.parameters:addStringAlternative("MA", "Vidya (1995)*", "", "VIDYA");
    indicator.parameters:addStringAlternative("MA", "Vidya (1992)*", "", "VIDYA92");
    indicator.parameters:addStringAlternative("MA", "Wilders*", "", "WMA");
    indicator.parameters:addString("SMA", "Signal smoothing Method", "The methods marked by an asterisk (*) require the appropriate indicators to be loaded.", "EMA");
    indicator.parameters:addStringAlternative("MA", "MVA", "", "MVA");
    indicator.parameters:addStringAlternative("MA", "EMA", "", "EMA");
    indicator.parameters:addStringAlternative("MA", "LWMA", "", "LWMA");
    indicator.parameters:addStringAlternative("MA", "TMA", "", "TMA");
    indicator.parameters:addStringAlternative("MA", "SMMA*", "", "SMMA");
    indicator.parameters:addStringAlternative("MA", "Vidya (1995)*", "", "VIDYA");
    indicator.parameters:addStringAlternative("MA", "Vidya (1992)*", "", "VIDYA92");
    indicator.parameters:addStringAlternative("MA", "Wilders*", "", "WMA");
    indicator.parameters:addGroup("Style");
    indicator.parameters:addColor("PPO_color", "PPO line color", "", core.rgb(255, 0, 0));
    indicator.parameters:addInteger("widthPPO", "PPO line width", "", 1, 1, 5);
    indicator.parameters:addInteger("stylePPO", "PPO line style", "", core.LINE_SOLID);
    indicator.parameters:setFlag("stylePPO", core.FLAG_LINE_STYLE);
    indicator.parameters:addColor("SIGNAL_color", "Signal line color", "", core.rgb(0, 0, 255));
    indicator.parameters:addInteger("widthSIGNAL", "Signal line width", "", 1, 1, 5);
    indicator.parameters:addInteger("styleSIGNAL", "Signal line style", "", core.LINE_SOLID);
    indicator.parameters:setFlag("styleSIGNAL", core.FLAG_LINE_STYLE);
    indicator.parameters:addColor("HISTOGRAM_color", "Historgram color", "", core.rgb(0, 255, 0));
end

-- Indicator instance initialization routine
-- Processes indicator parameters and creates output streams
-- Parameters block
local SN;
local LN;
local IN;

local firstPeriodPPO;

local firstPeriodSIGNAL;
local source = nil;

local EMAS = nil;
local EMAL = nil;
local MVAI = nil;

-- Streams block
local PPO = nil;
local SIGNAL = nil;
local HISTOGRAM = nil;

-- Routine
function Prepare()
    SN = instance.parameters.SN;
    LN = instance.parameters.LN;
    IN = instance.parameters.IN;
    source = instance.source;

    assert(core.indicators:findIndicator(instance.parameters.MA) ~= nil, "Please download and install " ..  instance.parameters.MA .. ".lua");
    assert(core.indicators:findIndicator(instance.parameters.SMA) ~= nil, "Please download and install " ..  instance.parameters.SMA .. ".lua");

    -- Check parameters
    if (LN <= SN) then
       assert(false, "The short MA period must be smaller than long MA period");
    end

    -- Create short and long EMAs for the source
    EMAS = core.indicators:create(instance.parameters.MA, source, SN);
    EMAL = core.indicators:create(instance.parameters.MA, source, LN);

    -- Base name of the indicator.
    local name = profile:id() .. "(" .. source:name() .. ", " .. SN .. ", " .. LN .. ", " .. IN .. "," .. instance.parameters.MA .. "," .. instance.parameters.SMA .. ")";
    instance:name(name);

    local precision = math.max(2, source:getPrecision());

    -- Create the output stream for the PPO. The first period is equal to the
    -- biggest first period of source EMA streams
    firstPeriodPPO = math.max(EMAS.DATA:first(), EMAL.DATA:first());
    PPO = instance:addStream("PPO", core.Line, name .. ".PPO", "PPO", instance.parameters.PPO_color, firstPeriodPPO);
    PPO:setWidth(instance.parameters.widthPPO);
    PPO:setStyle(instance.parameters.stylePPO);
    --PPO:setPrecision(precision);

    -- Create MVA for the PPO output stream.
    MVAI = core.indicators:create(instance.parameters.SMA, PPO, IN);
    -- Create output for the signal and histogram
    firstPeriodSIGNAL = MVAI.DATA:first();

    SIGNAL = instance:addStream("SIGNAL", core.Line, name .. ".SIGNAL", "SIGNAL", instance.parameters.SIGNAL_color, firstPeriodSIGNAL);
    SIGNAL:setWidth(instance.parameters.widthSIGNAL);
    SIGNAL:setStyle(instance.parameters.styleSIGNAL);
    --SIGNAL:setPrecision(precision);
    HISTOGRAM = instance:addStream("HISTOGRAM", core.Bar, name .. ".HISTOGRAM", "HISTOGRAM", instance.parameters.HISTOGRAM_color, firstPeriodSIGNAL);
    HISTOGRAM:setPrecision(precision);
end

-- Indicator calculation routine
function Update(period, mode)
    -- and update short and long EMAs for the source.
    EMAS:update(mode);
    EMAL:update(mode);

    if (period >= firstPeriodPPO) then
        -- calculate PPO output
         PPO[period] = (EMAS.DATA[period] - EMAL.DATA[period]) / EMAL.DATA[period] * 100;
    end

    -- update MVA on the PPO
    MVAI:update(mode);
    if (period >= firstPeriodSIGNAL) then
        SIGNAL[period] = MVAI.DATA[period];
        -- calculate histogram as a difference between PPO and signal
        HISTOGRAM[period] = PPO[period] - SIGNAL[period];
    end
end
Nikolay.Gekht
FXCodeBase: Base Builder
 
Posts: 1230
Joined: Wed Dec 16, 2009 6:39 pm
Location: Cary, NC

Return to Custom Indicators

Who is online

Users browsing this forum: Bing [Bot], chunkyglasses, Yahoo [Bot] and 6 guests