|
|
|
Forum Newbie
      
Group: Forum Members
Last Login: 12/29/2010 10:44:34 AM
Posts: 3,
Visits: 28
|
|
Hi - I'm looking to construct a custom indicator and I'm running into problems with the code. If you think you're up for this please have a look at the code and see if you can work out whats wrong here:
Essentially what I'm looking to do is code the Stocastic RSI indicator and them to provide a further smoothing with the addition of two SMAs to it. The look back period is say 8, initial SMA of 5, then I'd like to double smooth this with a 3 period SMA and a further 3 period SMA. (8,5,3,3) The indicator plotted on the screen would be the 8,5,3 fast line and the 8,5,3,3 slow line.
I've listed the code from custom indicators previously posted (Stochastic Indicator and the MA of RSI Indicator). Both of these work fine but my fat fingered typing seems to be compiling fine but hitting an index exception when run. Oh BTW the double MAs aren't coded in yet.
Thanks for whatever help you can supply.
const
IndicatorName = 'NJA';
Layout = Separated;
var
GraphK, GraphD: TLineGraph;
TSMA, SMAD: TSMAStatistics;
IsSlow: Boolean;
Period, AvPeriod: Integer;
//RSI variables added here
Average: TLineGraph;
MySMA: TSMAStatistics;
procedure CreateSettings;
begin
AddSetting('period', 'Period', '5');
AddSetting('avperiod', 'AveragePeriod', '3');
AddSetting('type', 'Type', 'Fast');
AddSetting('color', '%K Color', 'clGreen');
AddSetting('color2', '%D Color', 'clBlue');
end;
procedure ApplySettings;
begin
Period := StrToInt(GetSetting('period'));
AvPeriod := StrToInt(GetSetting('avperiod'));
if GetSetting('type') = 'Slow' then IsSlow := True
else IsSlow := False;
GraphK.Color := StrToColor(GetSetting('color'));
GraphD.Color := StrToColor(GetSetting('color2'));
SetTitle(IndicatorName + ': ' + GetSetting('period') + ', ' + GetSetting('avperiod')+ ', ' + GetSetting('type'));
end;
procedure Init;
begin
GraphK := TLineGraph.Create;
GraphD := TLineGraph.Create;
TSMA := TSMAStatistics.Create;
SMAD := TSMAStatistics.Create;
SetYScale(0, 100);
// Addition init elements from RSI
Average:= TLineGraph.Create();
MySMA:= TSMAStatistics.Create;
end;
procedure Add(const ValueIndex: Integer);
var
n, i: Integer;
High, Low, HighI, LowI, KValue: Double;
IsKValue: Boolean;
//RSI variable added here
change, pos, neg, RSIValues: Double;
Av: Double;
j: Integer;
begin
//RSI coding section placed here
begin
//calculation of the RSI indicator values
if ValueIndex > Period-2 then
begin
pos :=0;
neg :=0;
for j:=0 to Period-2 do
begin
change := SourceGraph.CloseValue(ValueIndex-i) - SourceGraph.CloseValue(ValueIndex-i-1);
if change > 0 then pos := pos + change;
if change < 0 then neg := neg - change;
end;
if neg = 0 then
begin
if pos = 0 then RSIValues := 50
else RSIValues := 100;
end;
RSIValues := 100 - (100/(1+ (pos/neg)));
//plotting the RSI indicator
// RSI.AddXY(SourceGraph.XValue(ValueIndex), RSiValues);
//calculation of the Moving Average
MySMA.AddValue(RSIValues);
//plotting the Moving Average
if MySMA.HasValues then
Average.AddXY(SourceGraph.XValue(ValueIndex), MySMA.LastValue);
end;
end;
//End of RSI coding section
n := Trunc(Period) - 1;
if ValueIndex >= n then
begin
High := Average.YValue(ValueIndex);
Low := Average.YValue(ValueIndex);
for i := ValueIndex - n to ValueIndex - 1 do
begin
HighI := Average.YValue(i);
LowI := Average.YValue(i);
if HighI > High then High := HighI;
if LowI < Low then Low := LowI;
end;
if High <> Low then
KValue := 100.0 * (Average.YValue(ValueIndex) - Low) / (High - Low)
else
KValue := 0;
if IsSlow then
begin
TSMA.AddValue(KValue);
IsKValue := TSMA.HasValues;
if IsKValue then KValue := TSMA.LastValue;
end
else
IsKValue := True;
if IsKValue then
begin
GraphK.AddXY(Average.XValue(ValueIndex), KValue);
SMAD.AddValue(KValue);
if SMAD.HasValues then
GraphD.AddXY(Average.XValue(ValueIndex), SMAD.LastValue);
end;
end;
end;
procedure Recalculate;
begin
TSMA.Period := AvPeriod;
SMAD.Period := TSMA.Period;
FullRecalculation;
end;
procedure Draw;
var
Height, Y: Integer;
begin
Height := Bottom - Top;
Canvas.Pen.Color := clWhite;
Y := Bottom - Round(0.2 * Height);
Canvas.Line(Left, Y, Right, Y);
Y := Bottom - Round(0.8 * Height);
Canvas.Line(Left, Y, Right, Y);
end;
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 1/27/2012 12:53:25 PM
Posts: 201,
Visits: 295
|
|
Hi, Chilliconcarni.
I’ve looked at your code and tried to fix it. Well I’ve got something, but I don’t know whether it is exactly what you want. So if there are any questions, I’m glad to help.
Best regards.
Best regards!
|
|
|
|