Я пытаюсь рассчитать индекс относительной силы RSI для финансового инструмента. Когда я сравниваю свой расчет с расчетом, выполненным с помощью коммерческого программного обеспечения, они не выглядят одинаково. Я не могу понять, что я делаю неправильно. Кто-нибудь может помочь?
формула RSI:
{100} - (100/(1+РС)). Где RS — это AvgGain (N периодов)/AvgLoss (N периодов)
public DataTable RSI(string instrument, int period, string oper, int entryVal)
{
DataTable dtRSI = new DataTable(); //table to return
dtRSI.Columns.Add("Date");
dtRSI.Columns.Add("Instrument");
dtRSI.Columns.Add("Close");
dtRSI.Columns.Add("RSI");
//Load Datatable from database
DataTable dt = new DataTable();
dt = conn.ExtractDataFromDb(instrument);
int column = 1; //Close price
//variables to RSI formula
Queue<float> avgUp = new Queue<float>();
Queue<float> avgDown = new Queue<float>();
float close1, close2, rsi, rs;
float avgUp1, avgUp2, newAvgUp, avgDown1, avgDown2, newAvgDown;
string[] dateCloseRsi = new string[3]; //row of data to insert into new table
string date; //date of calculation
string[] splitDate = new string[2];
//get first close
close1 = float.Parse(dt.Rows[0][column].ToString());
dt.Rows.RemoveAt(0);
//get close for number of periods into the que-list
for (int i = 1; i <= period; i++)
{
close2 = float.Parse(dt.Rows[0][column].ToString());
//are todays close higher then yesterday?
if (close2 > close1)
{
avgUp.Enqueue(close2 - close1);
avgDown.Enqueue(0);
}
else if (close2<close1)
{
avgUp.Enqueue(0);
avgDown.Enqueue(close1 - close2);
}
else
{
avgUp.Enqueue(0);
avgDown.Enqueue(0);
}
close1 = close2;
dt.Rows.RemoveAt(0);
}
//iterate datatable and calculate RSI
foreach (DataRow rows in dt.Rows)
{
avgUp1 = float.Parse(avgUp.Average().ToString("n2")); //calculate yesterdays avg difference on up days
avgDown1 = float.Parse(avgDown.Average().ToString("n2")); //calculate yesterdays avg difference on down days
avgUp.Dequeue();
avgDown.Dequeue();
close2 = float.Parse(rows[column].ToString()); //todays close
//close today higher then yesterday?
if (close2 > close1)
{
avgUp.Enqueue(close2 - close1);
avgDown.Enqueue(0);
}
else if (close2 < close1)
{
avgDown.Enqueue(close1 - close2);
avgUp.Enqueue(0);
}
else
{
avgUp.Enqueue(0);
avgDown.Enqueue(0);
}
avgUp2 = float.Parse(avgUp.Average().ToString("n2")); //todays avg difference on up days
avgDown2 = float.Parse(avgDown.Average().ToString("n2")); //todays avg difference on down days
newAvgUp = ((avgUp1 * (period - 1)) + avgUp2) / period; //yesterdays and todays avg diff value on up days
newAvgDown = ((avgDown1 * (period - 1)) + avgDown2) / period; //yesterdays and todays avg diff value on down days
newAvgUp = float.Parse(newAvgUp.ToString("n2")); //round to 2 decimals
newAvgDown = float.Parse(newAvgDown.ToString("n2")); //round to 2 decimals
rs = newAvgUp / newAvgDown; //calc Relative Strength
rs = float.Parse(rs.ToString("n2")); //round to 2 decimals
rsi = 100 - (100 / (1 + rs)); //Calc RSI
rsi = float.Parse(rsi.ToString("n2")); //round to 2 decimals
close1 = close2; //todays close become yesterdays close for tomorrow
//remove time from date
date = rows[0].ToString();
splitDate = date.Split(' ');
date = splitDate[0];
//add data to dtRSI
DataRow rsiRow = dtRSI.NewRow();
rsiRow["Date"] = date;
rsiRow["Instrument"] = instrument;
rsiRow["Close"] = rows[column];
rsiRow["RSI"] = rsi;
dtRSI.Rows.Add(rsiRow);
}
return dtRSI; //returns a table with Date, Instrument, Close Price and RSI
}