// All rights reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR
// FITNESS FOR A PARTICULAR PURPOSE.
using System;
using Trader.Data;
namespace Trader.Study {
/// <summary>
/// Represents a relative strgenth index indicator.
/// </summary>
public class RSI : Indicator {
private double avgGain = 0;
private double avgLoss = 0;
private double rsi;
private int period;
/// <summary>
/// ctor.
/// </summary>
public RSI() : base("RSI") {
base.Position = ChartPosition.Lower;
this.period = 14;
}
/// <summary>
/// ctor.
/// </summary>
public RSI(int period) : base("RSI") {
base.Position = ChartPosition.Lower;
this.period = period;
}
/// <summary>
/// Gets the period.
/// </summary>
[IndicatorParameter]
public int Period {
get {
return this.period;
}
set {
this.period = value;
}
}
/// <summary>
/// Calculates the RSI at index.
/// </summary>
/// <param name="index"></param>
/// <param name="series"></param>
public override double Calculate(int index, Series series) {
if (index == 0) {
base.Maximum = 0;
base.Minimum = 0;
this.avgGain = 0;
this.avgLoss = 0;
}
if (index < this.period) {
this.rsi = 50;
return this.rsi;
}
if (index == this.period) {
for (int i=0; i<index; i++) {
if (series[i+1] >= series[i]) {
this.avgGain += series[i+1] - series[i];
}
else {
avgLoss += series[i] - series[i+1];
}
}
this.avgGain = this.avgGain/this.period;
this.avgLoss = this.avgLoss/this.period;
//Console.WriteLine("gain {0}, loss {1}", this.avgGain, this.avgLoss);
this.rsi = 100 - 100/(1+this.avgGain/this.avgLoss);
return this.rsi;
}
double currentGain = 0;
double currentLoss = 0;
if (series[index] >= series[index-1])
currentGain = series[index] - series[index-1];
else
currentLoss = series[index-1] - series[index];
this.avgGain = (this.avgGain*(this.period-1) + currentGain)/this.period;
this.avgLoss = (this.avgLoss*(this.period-1)+currentLoss)/this.period;
//Console.WriteLine("gain {0}, loss {1}", this.avgGain, this.avgLoss);
this.rsi = 100 - 100/(1+this.avgGain/this.avgLoss);
return this.rsi;
}
}
}