-- 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("MAE Fibo");
indicator:description("MVA Enveloped Fibo");
indicator:requiredSource(core.Tick);
indicator:type(core.Indicator);
-- Period
indicator.parameters:addInteger("N", "Period", "Number of Periods", 34, 2, 1000);
-- 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 n;
Hi, Here is my first indicator with Indicator SDK. The BB channel width indicator . The Up/Down color is defined by DMI (I take the data from DMI built-in indicator). There is channel width SMA also. When the Histogram break up/down the SMA, it tell, the BB channel width is broader/tighter than average. As a note, the DMI uses core.Bar, while the BB is actually suitable with core.Tick. Then for the compability, I should put the applied price as a parameter. Hope this useful for us.
Code:
-- 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(resources:get("name"));
indicator:description(resources:get("description"));
indicator:requiredSource(core.Bar);
indicator:type(core.Oscillator);
indicator.parameters:addInteger("BBP", resources:get("param_BBP_name"), resources:get("param_BBP_description"), 20);
indicator.parameters:addInteger("BBSD", resources:get("param_BBSD_name"), resources:get("param_BBSD_description"), 2);
indicator.parameters:addInteger("BBPR", resources:get("param_BBPR_name"), resources:get("param_BBPR_description"), 0);
indicator.parameters:addInteger("DMIP", resources:get("param_DMIP_name"), resources:get("param_DMIP_description"), 14);
indicator.parameters:addInteger("MAP", resources:get("param_MAP_name"), resources:get("param_MAP_description"), 60);
indicator.parameters:addColor("BBUp_color", resources:get("param_BBUp_color_name"), resources:get("param_BBUp_color_description"), core.rgb(0, 168, 0));
indicator.parameters:addColor("BBDn_color", resources:get("param_BBDn_color_name"), resources:get("param_BBDn_color_description"), core.rgb(168, 0, 0));
indicator.parameters:addColor("BBLine_color", resources:get("param_BBLine_color_name"), resources:get("param_BBLine_color_description"), core.rgb(255, 255, 0));
indicator.parameters:addColor("MALine_color", resources:get("param_MALine_color_name"), resources:get("param_MALine_color_description"), core.rgb(128, 128, 128));
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 BBP;
local BBSD;
local BBPR;
local DMIP;
local MAP;
local first;
local source = nil;
-- dmi
local dmi = nil;
-- Streams block
local BBUp = nil;
local BBDn = nil;
local BBLine = nil;
local MALine = nil;
-- Routine
function Prepare()
BBP = instance.parameters.BBP;
BBSD = instance.parameters.BBSD;
BBPR = instance.parameters.BBPR;
DMIP = instance.parameters.DMIP;
MAP = instance.parameters.MAP;
source = instance.source;
if BBP > DMIP then first = source:first() + BBP - 1; else first = source:first() + DMIP - 1; end
-- DMI prepare
dmi = core.indicators:create("DMI", source, DMIP);
local name = profile:id() .. "(" .. source:name() .. ", " .. BBP .. ", " .. BBSD .. ", " .. BBPR .. ", " .. DMIP .. ", " .. MAP .. ")";
instance:name(name);
BBUp = instance:addStream("BBUp", core.Bar, name .. ".BBUp", "BBUp", instance.parameters.BBUp_color, first);
BBDn = instance:addStream("BBDn", core.Bar, name .. ".BBDn", "BBDn", instance.parameters.BBDn_color, first);
BBLine = instance:addStream("BBLine", core.Line, name .. ".BBLine", "BBLine", instance.parameters.BBLine_color, first);
MALine = instance:addStream("MALine", core.Line, name .. ".MALine", "MALine", instance.parameters.MALine_color, first);
end
-- Indicator calculation routine
-- TODO: Add your code for calculation output values
function Update(period, mode)
dmi:update(mode);
if period >= first and source:hasData(period) then
local p = core.rangeTo(period, BBP);
-- Set Price because it use core.Bar
local ml;
local d;
if BBPR == 0 then ml = core.avg(source.close, p); d = core.stdev(source.close, p);
elseif BBPR == 1 then ml = core.avg(source.open, p); d = core.stdev(source.open, p);
elseif BBPR == 2 then ml = core.avg(source.high, p); d = core.stdev(source.high, p);
elseif BBPR == 3 then ml = core.avg(source.low, p); d = core.stdev(source.low, p);
end
local plus = dmi.DIP[period];
local minus = dmi.DIM[period];
local bbWidth = (ml + BBSD * d) - (ml - BBSD * d);
-- set to nil the histograms
BBUp[period] = nil; BBDn[period] = nil;
-- revalue the histograms based on DMI+/-
if plus>minus then BBUp[period] = bbWidth; else BBDn[period] = bbWidth; end
BBLine[period] = bbWidth;
MALine[period] = nil;
if period >= first + MAP then
local p = core.rangeTo(period, MAP);
local ml = core.avg(BBLine,p);
MALine[period] = ml;
end
end
end
Well done! The idea with colorful bars is excellent!
Thanks Nikolay.
Here is my other developing indicator. It's still raw and dirty. I code this as my practice with SDK. The point is, I want to share the idea, how to quantitativing the candlestick pattern. It show dot under the low price when the candlestick pattern occured. For pattern labeling, I wish, the next update of marketscope/SDK is able to show label/text object.
Code:
-- CAND (Quantitative Candlestick Patterns Recognizer)
-- Copyright @2009 by fruitaly
-- ******** NOTE *********
-- 1. The recognizer use colored dot etc.
-- e.g. The indicator dot with yellow color, it means, there is a candlestick one-bar pattern (doji, hammer, etc.)
-- The indicator dot with cyan color, it means there is a candlestick two-bar pattern (bullish engulfing, etc.)
-- etc.
-- 2. This indicator is very simple and for idea sharing only.
-- This should develope further to gain full candlestick analysis (e.g. gap, prior trend, meeting line, etc.)
-- 3. If you develop further base on this code, please share your development to the others.
-- DISCLAIMER: according to the note #2, this indicator is not complete, and you should use with your own risks.
-- ***********************
-- Indicator profile initialization routine
-- Defines indicator profile properties and indicator parameters
function Init()
indicator:name(resources:get("name"));
indicator:description(resources:get("description"));
indicator:requiredSource(core.Bar);
indicator:type(core.Indicator);
indicator.parameters:addInteger("BP", resources:get("param_BP_name"), resources:get("param_BP_description"), 100);
indicator.parameters:addDouble("BR", resources:get("param_BR_name"), resources:get("param_BR_description"), 2);
indicator.parameters:addColor("OneBar_color", resources:get("param_OneBar_color_name"), resources:get("param_OneBar_color_description"), core.rgb(168, 168, 0));
indicator.parameters:addColor("TwoBars_color", resources:get("param_TwoBars_color_name"), resources:get("param_TwoBars_color_description"), core.rgb(0, 168, 168));
indicator.parameters:addColor("ThreeBars_color", resources:get("param_ThreeBars_color_name"), resources:get("param_ThreeBars_color_description"), core.rgb(168, 0, 168));
indicator.parameters:addColor("FourBars_color", resources:get("param_FourBars_color_name"), resources:get("param_FourBars_color_description"), core.rgb(0, 0, 255));
end
-- Indicator instance initialization routine
-- Processes indicator parameters and creates output streams
-- Parameters block
local BP;
local BR;
local first;
local source = nil;
-- Bar size streams
local Body = nil;
local Upper = nil;
local Lower = nil;
-- Streams block
local OneBar = nil;
local TwoBars = nil;
local ThreeBars = nil;
local FourBars = nil;
-- Routine
function Prepare()
BP = instance.parameters.BP;
BR = instance.parameters.BR;
source = instance.source;
first = source:first() + BP - 1;
Body = instance:addInternalStream(first,0);
Upper = instance:addInternalStream(first,0);
Lower = instance:addInternalStream(first,0);
local name = profile:id() .. "(" .. source:name() .. ", " .. BP .. ", " .. BR .. ")";
instance:name(name);
OneBar = instance:addStream("OneBar", core.Dot, name .. ".OneBar", "OneBar", instance.parameters.OneBar_color, first);
TwoBars = instance:addStream("TwoBars", core.Dot, name .. ".TwoBars", "TwoBars", instance.parameters.TwoBars_color, first);
ThreeBars = instance:addStream("ThreeBars", core.Dot, name .. ".ThreeBars", "ThreeBars", instance.parameters.ThreeBars_color, first);
FourBars = instance:addStream("FourBars", core.Dot, name .. ".FourBars", "FourBars", instance.parameters.FourBars_color, first);
end
function Averaging(period)
local range = core.rangeTo(period, BP);
local b = 0;
local u = 0;
local l = 0;
local i;
for i = range.from, period, 1 do
b = b + math.abs(source.close[i] - source.open[i]);
u = u + source.high[i] - math.max(source.close[i],source.open[i]);
l = l + math.min(source.close[i],source.open[i])- source.low[i];
end
Body[period] = b / BP;
Upper[period] = u / BP;
Lower[period] = l / BP;
end
function Sizer(size, avgsize)
-- sizeLevel 5-very big 4-big 3-medium 2-small 1-very small 0-doji -1-NA
local sizelevel = -1;
local minverybig = avgsize * BR * 1.5;
local minbig = avgsize * BR;
local minmedium = avgsize * (1/BR);
local minsmall = avgsize * math.pow(1/BR,2);
if size >= minverybig then sizelevel = 5;
elseif size >= minbig then sizelevel = 4;
elseif size >= minmedium then sizelevel = 3;
elseif size >= minsmall then sizelevel = 2;
elseif size < minsmall then sizelevel = 1;
elseif size == 0 then sizelevel = 0;
end
return sizelevel;
end
function GetInside(bar1period, bar2period)
local inside = -1; --not inside bar
-- this below inside condition is not just as simple as :p. It will not suitable to check full analysis. For SAMPLE only
if source.high[bar1period] > source.high[bar2period] and source.low[bar1period] < source.low[bar2period] then inside = 0; end --full inside
return inside;
end
-- According to the note #2, this checks long bar & doji only
function OneBarPattern(period)
local pattern = -1; -- NA pattern
local bartype = source.close[period] - source.open[period]; -- + = green bar ; - = red bar
local b = math.abs(source.close[period] - source.open[period]);
local u = source.high[period] - math.max(source.close[period],source.open[period]);
local l = math.min(source.close[period],source.open[period])- source.low[period];
-- compare above sizes with the averages
local bodylevel = Sizer(b, Body[period]);
local upperlevel = Sizer(u, Upper[period]);
local lowerlevel = Sizer(l, Lower[period]);
--long bar
if bodylevel>4 and bartype>0 then pattern = 0; -- very long white
elseif bodylevel>4 and bartype<0 then pattern = 1; -- very long black
-- Doji variants check. ** I assume the very small body as a doji too :p **
elseif bodylevel<=1 and upperlevel<=2 and lowerlevel<=2 then pattern = 2; -- four price doji
elseif bodylevel<=1 and upperlevel<=2 and lowerlevel>=3 then pattern = 3; -- dragon fly doji
elseif bodylevel<=1 and upperlevel>=3 and lowerlevel>=3 then pattern = 4; -- long legged doji
elseif bodylevel<=1 and upperlevel>=3 and lowerlevel<=2 then pattern = 5; -- gravestone doji
end
return pattern;
end
-- According to the note #2, this checks bullish/bearish engulfing only
function TwoBarPattern(period)
local pattern = -1; -- NA pattern
--current bar
local bartype1 = source.close[period] - source.open[period]; -- + = green bar ; - = red bar
local b1 = math.abs(source.close[period] - source.open[period]);
local u1 = source.high[period] - math.max(source.close[period],source.open[period]);
local l1 = math.min(source.close[period],source.open[period])- source.low[period];
--prior bar
local bartype2 = source.close[period-1] - source.open[period-1]; -- + = green bar ; - = red bar
local b2 = math.abs(source.close[period-1] - source.open[period-1]);
local u2 = source.high[period-1] - math.max(source.close[period-1],source.open[period-1]);
local l2 = math.min(source.close[period-1],source.open[period-1])- source.low[period-1];
-- compare above sizes with the averages
--current bar
local bodylevel1 = Sizer(b1, Body[period]);
local upperlevel1 = Sizer(u1, Upper[period]);
local lowerlevel1 = Sizer(l1, Lower[period]);
--prior bar
local bodylevel2 = Sizer(b2, Body[period]);
local upperlevel2 = Sizer(u2, Upper[period]);
local lowerlevel2 = Sizer(l2, Lower[period]);
-- Engulfing check
if bodylevel2>=3 and bartype2>0 and GetInside(period,period-1)>-1 then pattern = 0; --bullish engulfing
elseif bodylevel2>=3 and bartype2<0 and GetInside(period,period-1)>-1 then pattern = 1; --bearish engulfing
end
return pattern;
end
-- Indicator calculation routine
function Update(period)
if period >= first and source:hasData(period) then
--averaging first
Averaging(period);
OneBar[period] = nil;
TwoBars[period] = nil;
ThreeBars[period] = nil;
FourBars[period] = nil;
-- I wish the next update of indicator SDK is able to create label/text object to show the pattern text.
if OneBarPattern(period) >= 0 then OneBar[period] = source.low[period] - 0.0004 * source.low[period]; end
if TwoBarPattern(period) >= 0 then TwoBars[period] = source.low[period] - 0.0007 * source.low[period]; end
end
end
Can anyone convert code to Lua for use in marketscope 2?
I have code designed for prorealtime software provided to gold clients at FXCM,but i was wandering if someone could help me convert it Lua for use in marketscope..
The code is a Volume Spread Analysis based indicator that identifies forex volume patterns..
Disclaimer: Trading foreign exchange on margin carries a high level of risk, and may not be suitable for all investors. The high degree of leverage can work against you as well as for you. Before deciding to trade foreign exchange you should carefully consider your investment objectives, level of experience, and risk appetite. The possibility exists that you could sustain a loss of some or all of your initial investment and therefore you should not invest money that you cannot afford to lose. You should be aware of all the risks associated with foreign exchange trading, and seek advice from an independent financial advisor if you have any doubts. Any opinions, news, research, analyses, prices, or other information contained on this website is provided as general market commentary and does not constitute investment advice. Forex Capital Markets LLC. will not accept liability for any loss or damage, including without limitation to, any loss of profit, which may arise directly or indirectly from use of or reliance on such information.