a) The price range is shifted to the proper area because of Marketscope bug fixed in the Apr release.
b) The weighted price is added to the list. The price calculation procedure is removed because Marketscope support median, typical and weighted prices since the Apr release.
c) The default line color is changed from blue to cyan for easier reading
Update Feb, 22: The type of the indicator was incorrectly specified as "Indicator" instead of "Oscillator". The problem is fixed. Many thanks to the user Stardom from http://www.fxprogrammers.com!
The COG oscillator is a John Ehler's FIR filer applied on the price. Center of Gravity actually has a zero lag and allows to define turning points precisely. This indicator is the result of Ehler's study of adaptive filters. The indicator Center of Gravity allows to identify main pivot points almost without any lag as well.
Download:
- Code: Select all
-- Indicator profile initialization routine
function Init()
indicator:name("John Ehlers' Center Of Gravity Indicator");
indicator:description("");
indicator:requiredSource(core.Bar);
indicator:type(core.Oscillator);
indicator.parameters:addInteger("FIR_N", "FIR (LWMA) number of periods", "No description", 10);
indicator.parameters:addInteger("S_N", "Signal Line Smoothing Periods", "No description", 3);
indicator.parameters:addString("PM", "Price Mode", "", "C");
indicator.parameters:addStringAlternative("PM", "Close", "", "C");
indicator.parameters:addStringAlternative("PM", "Median", "", "M");
indicator.parameters:addStringAlternative("PM", "Typical", "", "T");
indicator.parameters:addStringAlternative("PM", "Weighted", "", "W");
indicator.parameters:addColor("CG_color", "Color of CG", "Color of CG", core.rgb(0, 255, 255));
indicator.parameters:addColor("SIG_color", "Color of SIG", "Color of SIG", core.rgb(255, 128, 64));
end
-- Indicator instance initialization routine
-- Processes indicator parameters and creates output streams
local FIR_N;
local S_N;
local PM;
local firstCG;
local firstSIG;
local source = nil;
-- Streams block
local CG = nil;
local SIG = nil;
local PRICE;
-- Routine
function Prepare()
FIR_N = instance.parameters.FIR_N;
S_N = instance.parameters.S_N;
PM = instance.parameters.PM;
source = instance.source;
firstCG = source:first() + FIR_N;
firstSIG = firstCG + S_N;
local name = profile:id() .. "(" .. source:name() .. ", " .. FIR_N .. ", " .. S_N .. ", " .. PM .. ")";
instance:name(name);
if PM == "C" then
PRICE = source.close;
elseif PM == "M" then
PRICE = source.median;
elseif PM == "T" then
PRICE = source.typical;
elseif PM == "W" then
PRICE = source.weighted;
end
CG = instance:addStream("CG", core.Line, name .. ".CG", "CG", instance.parameters.CG_color, firstCG);
SIG = instance:addStream("SIG", core.Line, name .. ".SIG", "SIG", instance.parameters.SIG_color, firstSIG);
end
-- Indicator calculation routine
function Update(period)
if period >= firstCG then
local k, i, s, w;
k = FIR_N;
s = 0;
w = 0;
for i = period - FIR_N + 1, period, 1 do
w = w + k * PRICE[i];
s = s + PRICE[i];
k = k - 1;
end
CG[period] = -w / s;
end
if period >= firstSIG then
SIG[period] = core.avg(CG, core.rangeTo(period, S_N));
end
end