This is absolutely the easiest example, the reference and comparison of MVA data obtained by means of external functions.
- Code: Select all
-- Indicator profile initialization routine
-- Defines indicator profile properties and indicator parameters
-- TODO: Add minimal and maximal value of numeric parameters and default color of the streams
function Init()
indicator:name("MVA CrossOver");
indicator:description("MVA CrossOver");
indicator:requiredSource(core.Tick);
indicator:type(core.Oscillator);
--////////////////////////////////////////////////////////////////////
indicator.parameters:addInteger("Frame", "Period", "Period", 20,2,2000);
--/////////////////////////////////////////////////////////////////////
indicator.parameters:addColor("UP", "Color of UP", "Color of UP", core.rgb(0, 255, 0));
indicator.parameters:addColor("DOWN", "Color of DOWN", "Color of DOWN", core.rgb(255, 0, 0));
end
-- Indicator instance initialization routine
-- Processes indicator parameters and creates output streams
-- TODO: Refine the first period calculation for each of the output streams.
-- TODO: Calculate all constants, create instances all subsequent indicators and load all required libraries
-- Parameters block
--////////////
local Frame;
--////////////
local first;
local source = nil;
-- Streams block
local S1 = nil;
local S2 = nil;
--/////////////
local MVA=nil;
--/////////////
-- Routine
function Prepare()
Frame = instance.parameters.Frame;
source = instance.source;
first = source:first();
--//////////////////////////////////////////////////////
MVA= core.indicators:create("MVA", source, Frame);
--/////////////////////////////////////////////////////
local name = profile:id() .. "(" .. source:name() .. ", " .. Frame .. ")";
instance:name(name);
S1 = instance:addStream("S1", core.Bar, name, "Up", instance.parameters.UP, first);
S2 = instance:addStream("S2", core.Bar, name, "Down", instance.parameters.DOWN, first);
end
-- Indicator calculation routine
-- TODO: Add your code for calculation output values
function Update(period,mode)
-- make sure you add mode i (period) like in this line above
if period >= Frame and source:hasData(period) then
--///////////////////////
MVA:update(mode);
--//////////////////////
if source[period] > MVA.DATA[period] then
S1[period] = 1;
end
if source[period] < MVA.DATA[period] then
S2[period] = 1;
end
end
end
You'll get the same result using core.avg functions, but I advise you that you use the first example, namely, in this way invite the other functions that you will use in future work.
Moving average is basically just average.
- Code: Select all
-- Indicator profile initialization routine
-- Defines indicator profile properties and indicator parameters
-- TODO: Add minimal and maximal value of numeric parameters and default color of the streams
function Init()
indicator:name("MVA CrossOver");
indicator:description("MVA CrossOver");
indicator:requiredSource(core.Tick);
indicator:type(core.Oscillator);
--////////////////////////////////////////////////////////////////////
indicator.parameters:addInteger("Frame", "Period", "Period", 20,2,2000);
--/////////////////////////////////////////////////////////////////////
indicator.parameters:addColor("UP", "Color of UP", "Color of UP", core.rgb(0, 255, 0));
indicator.parameters:addColor("DOWN", "Color of DOWN", "Color of DOWN", core.rgb(255, 0, 0));
end
-- Indicator instance initialization routine
-- Processes indicator parameters and creates output streams
-- TODO: Refine the first period calculation for each of the output streams.
-- TODO: Calculate all constants, create instances all subsequent indicators and load all required libraries
-- Parameters block
--////////////
local Frame;
--////////////
local first;
local source = nil;
-- Streams block
local S1 = nil;
local S2 = nil;
-- Routine
function Prepare()
Frame = instance.parameters.Frame;
source = instance.source;
first = source:first();
local name = profile:id() .. "(" .. source:name() .. ", " .. Frame .. ")";
instance:name(name);
S1 = instance:addStream("S1", core.Bar, name, "Up", instance.parameters.UP, first);
S2 = instance:addStream("S2", core.Bar, name, "Down", instance.parameters.DOWN, first);
end
-- Indicator calculation routine
-- TODO: Add your code for calculation output values
function Update(period)
if period >= Frame and source:hasData(period) then
local Range = core.range(period-Frame, period);
if source[period] > core.avg(source, Range) then
S1[period] = 1;
end
if source[period] < core.avg(source, Range) then
S2[period] = 1;
end
end
end
Key parts of the code.
1.Defining the types of source data.- Code: Select all
indicator:requiredSource(core.Tick);
Can be core.Tick or Core.Bar
In this example, the MVA requires Tick Data.
If you use the "Bar" option, you can get a Tick if you write source.close
2.Calling external functions
- Code: Select all
MVA= core.indicators:create("MVA", source, Frame);
MVA - The name of the function you call, always have to use capital letters.
Frame - Parameter MVA function.
Functions - should not necessarily have parameters, can have multiple parameters.
3. Calling external functions
- Code: Select all
MVA:update(mode);
4. Calling external function data.
- Code: Select all
MVA.DATA[period]
If a function has only one stream, data can be called using the "Data" identifier.
If a function has multiple streams, you must identify each separately.
5. Do not forget to add mode parameter for main function
- Code: Select all
function Update(period,mode)
if you do not call external functions main function parameter looks like this.
- Code: Select all
function Update(period)