I learn how to program indicator and i have made a RSI divergence for training.
The code include the RSI and the search on divergence.
It's work!
I am not sure if is good. i like advice by programmer (thank apprentice if you can).
I can help to program indicator but i'am a beginner and necessary to correct me.
the calcul of peak is different because i use only one period on each size.
(I don't wait 2 periods only one to have signal)
I don't use overbought/oversold levels, and price nivel.
I can hide divergence by type of divergence.
I have difficulty to determine if my firstperiod is good.
I have difficulty to understand what realy do extent option in addstream.
sorry for my english.
good day.
- Code: Select all
-- RSI avec Divergente
function Init()
indicator:name(resources:get("name"));
indicator:description(resources:get("description"));
indicator:requiredSource(core.Tick);
indicator:type(core.Oscillator);
indicator:setTag("group", "Classic Oscillators");
indicator.parameters:addGroup("Calculation");
indicator.parameters:addInteger("N", resources:get("R_number_of_periods_name"), resources:get("R_number_of_periods_desciption"), 14, 2, 1000);
indicator.parameters:addGroup("Style");
indicator.parameters:addColor("clrRSI", resources:get("R_line_color_name"),
string.format(resources:get("R_color_of_PARAM_description"), resources:get("param_RSI_line_name")), core.rgb(255, 255, 128));
indicator.parameters:addInteger("widthRSI", resources:get("R_line_width_name"),
string.format(resources:get("R_width_of_PARAM_description"), resources:get("param_RSI_line_name")), 1, 1, 5);
indicator.parameters:addInteger("styleRSI", resources:get("R_line_style_name"),
string.format(resources:get("R_style_of_PARAM_description"), resources:get("param_RSI_line_name")), core.LINE_SOLID);
indicator.parameters:setFlag("styleRSI", core.FLAG_LEVEL_STYLE);
indicator.parameters:addBoolean("Affiche_Div_Classique", resources:get("Div_name_class"), resources:get("Div_desc_class"), true);
indicator.parameters:addBoolean("Affiche_Div_Cache", resources:get("Div_name_cache"), resources:get("Div_desc_cache", true);
indicator.parameters:addColor("UP_color", resources:get("R_line_color_name"),
string.format(resources:get("R_color_of_PARAM_description"), resources:get("param_UP_color_line_name")), core.rgb(0, 255, 0));
indicator.parameters:addColor("DN_color", resources:get("R_line_color_name"),
string.format(resources:get("R_color_of_PARAM_description"), resources:get("param_DN_color_line_name")), core.rgb(255, 0, 0));
indicator.parameters:addGroup("Levels");
indicator.parameters:addInteger("overbought", resources:get("R_overbought_level_name"), resources:get("R_overbought_level_description"), 70, 0, 100);
indicator.parameters:addInteger("oversold", resources:get("R_oversold_level_name"), resources:get("R_oversold_level_description"), 30, 0, 100);
indicator.parameters:addInteger("level_overboughtsold_width", string.format(resources:get("R_width_of_PARAM_name"), resources:get("R_overbought_oversold_name")),
string.format(resources:get("R_width_of_PARAM_description"), resources:get("R_overbought_oversold_description")), 1, 1, 5);
indicator.parameters:addInteger("level_overboughtsold_style", string.format(resources:get("R_style_of_PARAM_name"), resources:get("R_overbought_oversold_name")),
string.format(resources:get("R_style_of_PARAM_description"), resources:get("R_overbought_oversold_description")), core.LINE_SOLID);
indicator.parameters:addColor("level_overboughtsold_color", string.format(resources:get("R_color_of_PARAM_name"), resources:get("R_overbought_oversold_name")),
string.format(resources:get("R_color_of_PARAM_description"), resources:get("R_overbought_oversold_description")), core.rgb(128,128,128));
indicator.parameters:setFlag("level_overboughtsold_style", core.FLAG_LEVEL_STYLE);
end
local n;
local first;
local source = nil;
local pos = nil;
local neg = nil;
local periode_precedent_sommet=nil;
local periode_sommet=nil;
local periode_precedent_creux=nil;
local periode_creux=nil;
local ligne_id = 0; -- compteur de ligne servant d'identifiant
local Affiche_Div_Cache = true;
local Affiche_Div_Classique = true;
local RSI = nil;
local UP = nil;
local DN = nil;
function Prepare()
assert(instance.parameters.oversold < instance.parameters.overbought, resources:get("Erreur: verifier les niveaux de surachat et survente"));
n = instance.parameters.N;
source = instance.source;
first = source:first() + n;
UP_color = instance.parameters.UP_color;
DN_color = instance.parameters.DN_color;
Affiche_Div_Cache = instance.parameters.Affiche_Div_Cache;
Affiche_Div_Classique = instance.parameters.Affiche_Div_Classique;
local name = profile:id() .. "(" .. source:name() .. ", " .. n .. ")";
instance:name(name);
pos = instance:addInternalStream(0, 0);
neg = instance:addInternalStream(0, 0);
RSI = instance:addStream("RSI", core.Line, name, "RSI", instance.parameters.clrRSI, first);
RSI:setWidth(instance.parameters.widthRSI);
RSI:setStyle(instance.parameters.styleRSI);
RSI:setPrecision(2);
UP = instance:createTextOutput ("Up", "Up", "Wingdings", 10, core.H_Center, core.V_Bottom, UP_color);
DN = instance:createTextOutput ("Dn", "Dn", "Wingdings", 10, core.H_Center, core.V_Top, DN_color);
RSI:addLevel(0);
RSI:addLevel(instance.parameters.oversold, instance.parameters.level_overboughtsold_style, instance.parameters.level_overboughtsold_width, instance.parameters.level_overboughtsold_color);
RSI:addLevel(50);
RSI:addLevel(instance.parameters.overbought, instance.parameters.level_overboughtsold_style, instance.parameters.level_overboughtsold_width, instance.parameters.level_overboughtsold_color);
RSI:addLevel(100);
end
local pperiode = nil;
function Update(periode)
-- efface si recalcule et reinitia
if pperiode ~= nil and pperiode > periode then
core.host:execute("removeAll");
ligne_id=0;
periode_precedent_sommet=nil;
periode_sommet=nil;
periode_precedent_creux=nil;
periode_creux=nil;
end
pperiode = periode;
if periode >= first then
local i = 0;
local sump = 0;
local sumn = 0;
local positive = 0;
local negative = 0;
local diff = 0;
--calcul du RSI
if (periode == first) then
for i = periode - n + 1, periode do
diff = source[i] - source[i - 1];
if (diff >= 0) then
sump = sump + diff;
else
sumn = sumn - diff;
end
end
positive = sump / n;
negative = sumn / n;
else
diff = source[periode] - source[periode - 1];
if (diff > 0) then
sump = diff;
else
sumn = -diff;
end
positive = (pos[periode - 1] * (n - 1) + sump) / n;
negative = (neg[periode - 1] * (n - 1) + sumn) / n;
end
pos[periode] = positive;
neg[periode] = negative;
if (negative == 0) then
RSI[periode] = 0;
else
RSI[periode] = 100 - (100 / (1 + positive / negative));
end
-- fin calcul RSI
if periode > first+2 then
--detection des sommets
if (RSI[periode-1] > RSI[periode]) and (RSI[periode-1] > RSI[periode-2]) then
periode_precedent_sommet=periode_sommet;
periode_sommet=periode-1;
--detections des divergences
if periode_precedent_sommet ~= nil then
-- div baissiere
if Affiche_Div_Classique == true then
if (RSI[periode_precedent_sommet]>RSI[periode_sommet]) and (source[periode_precedent_sommet] < source[periode_sommet]) then
DN:set(periode_sommet, RSI[periode_sommet], "\226", "Div B");
ligne_id = ligne_id + 1;
core.host:execute("drawLine", ligne_id, source:date(periode_precedent_sommet), RSI[periode_precedent_sommet], source:date(periode_sommet), RSI[periode_sommet], DN_color);
end
end
-- div baissiere cache
if Affiche_Div_Cache == true then
if (RSI[periode_precedent_sommet]<RSI[periode_sommet]) and (source[periode_precedent_sommet] > source[periode_sommet]) then
DN:set(periode_sommet, RSI[periode_sommet], "\226", "Div B cache");
ligne_id = ligne_id + 1;
core.host:execute("drawLine", ligne_id, source:date(periode_precedent_sommet), RSI[periode_precedent_sommet], source:date(periode_sommet), RSI[periode_sommet], DN_color);
end
end
end
-- detection creux
elseif (RSI[periode-1] < RSI[periode]) and (RSI[periode-1] < RSI[periode-2]) then
periode_precedent_creux=periode_creux;
periode_creux=periode-1;
--detection divergence
if periode_precedent_creux ~= nil then
-- div haussiere
if Affiche_Div_Classique == true then
if (RSI[periode_precedent_creux]<RSI[periode_creux]) and (source[periode_precedent_creux] > source[periode_creux]) then
UP:set(periode_creux, RSI[periode_creux], "\225", "Div H");
ligne_id = ligne_id + 1;
core.host:execute("drawLine", ligne_id, source:date(periode_precedent_creux), RSI[periode_precedent_creux], source:date(periode_creux), RSI[periode_creux], UP_color);
end
end
--div haussiere cache
if Affiche_Div_Cache == true then
if (RSI[periode_precedent_creux]>RSI[periode_creux]) and (source[periode_precedent_creux] < source[periode_creux])then
UP:set(periode_creux, RSI[periode_creux], "\225", "Div H cache");
ligne_id = ligne_id + 1;
core.host:execute("drawLine", ligne_id, source:date(periode_precedent_creux), RSI[periode_precedent_creux], source:date(periode_creux), RSI[periode_creux], UP_color);
end
end
end
end
end
end
end
and the ressource file
- Code: Select all
include=common.lua.rc
default=enu
[enu]
codepage=1252
name=Relative Strength Index with divergence
description=Shows price strength by comparing upward and downward close-to-close movements. And Divergences between indicator and price.
param_RSI_line_name=Relative Strength Index line
param_UP_color_line_name=Divergence Up
param_DN_color_line_name=Divergence Down
Div_name_class=Shows classic Divergence
Div_desc_class=True: Shows classic Divergences. False: to hide
Div_name_cache=Shows hidden divergence
Div_desc_cache=True:Shows hidden Divergences. False: to hide
[fra]
codepage=1252
name=Indice de la force relative Avec Divergence
description=Montre la force du prix en le comparant aux mouvement vers son plus haut et son plus bas d'une clôture à l'autre.
param_RSI_line_name=ligne de l'Indice de force relative
param_UP_color_line_name=Divergence Hausse
param_DN_color_line_name=Divergence Baisse
Div_name_class=Affiche les divergences classiques
Div_desc_class=Vrai: pour afficher les divergences classiques
Div_name_cache=Affiche les divergences cachees
Div_desc_cache=Vrai: pour afficher les divergences cachees