用.NET语言写一个计算股票技术指标DMI的函数,第一个参数为datatable类型,日期列名为“日期”,开盘价列名为“开盘”,收盘价列名为“收盘”,最高价列名为“最高”,最低价列名为“最低”,返回值为datatable类型,返回值包含PDI,MDI,ADX,ADXR等列,double类型全部四舍五入保留3位小数。
时间: 2024-03-27 13:41:29 浏览: 12
好的,以下是计算DMI指标的函数代码:
```csharp
public static DataTable CalculateDMI(DataTable dt)
{
// 计算方向线DI和动态区间范围TR
double[] DIp = new double[dt.Rows.Count];
double[] DIn = new double[dt.Rows.Count];
double[] TR = new double[dt.Rows.Count];
for (int i = 1; i < dt.Rows.Count; i++)
{
double high = Convert.ToDouble(dt.Rows[i]["最高"]);
double low = Convert.ToDouble(dt.Rows[i]["最低"]);
double pre_close = Convert.ToDouble(dt.Rows[i - 1]["收盘"]);
double pdm = Math.Max(high - pre_close, 0);
double ndm = Math.Max(pre_close - low, 0);
DIp[i] = pdm;
DIn[i] = ndm;
TR[i] = Math.Max(Math.Max(high - low, Math.Abs(high - pre_close)), Math.Abs(low - pre_close));
}
// 计算平均动向指标ADX和动向指标DI
double[] DX = new double[dt.Rows.Count];
double[] ADX = new double[dt.Rows.Count];
double[] ADXR = new double[dt.Rows.Count];
for (int i = 14; i < dt.Rows.Count; i++)
{
double sum_dip = 0, sum_din = 0, sum_tr = 0;
for (int j = i - 13; j <= i; j++)
{
sum_dip += DIp[j];
sum_din += DIn[j];
sum_tr += TR[j];
}
double pdi = 100 * sum_dip / sum_tr;
double ndi = 100 * sum_din / sum_tr;
double dx = 100 * Math.Abs(pdi - ndi) / (pdi + ndi);
DX[i] = dx;
if (i == 14 + 14 - 1)
{
double sum_dx = 0;
for (int j = i - 13; j <= i; j++)
{
sum_dx += DX[j];
}
ADX[i] = sum_dx / 14;
}
else if (i > 14 + 14 - 1)
{
ADX[i] = (ADX[i - 1] * 13 + DX[i]) / 14;
}
if (i >= 14 + 14 - 1 + 5)
{
ADXR[i] = (ADX[i] + ADX[i - 5]) / 2;
}
}
// 构造返回结果
DataTable result = new DataTable();
result.Columns.Add("日期", typeof(DateTime));
result.Columns.Add("PDI", typeof(double));
result.Columns.Add("MDI", typeof(double));
result.Columns.Add("ADX", typeof(double));
result.Columns.Add("ADXR", typeof(double));
for (int i = 14 + 14 - 1 + 5; i < dt.Rows.Count; i++)
{
DataRow row = result.NewRow();
row["日期"] = dt.Rows[i]["日期"];
row["PDI"] = Math.Round(100 * DIp[i] / TR[i], 3);
row["MDI"] = Math.Round(100 * DIn[i] / TR[i], 3);
row["ADX"] = Math.Round(ADX[i], 3);
row["ADXR"] = Math.Round(ADXR[i], 3);
result.Rows.Add(row);
}
return result;
}
```
需要注意的是,这个函数假定输入的数据表dt已经按照日期升序排列,而且至少包含14 + 14 - 1 + 5 = 32行数据(因为要计算ADX和ADXR需要至少32个数据点)。如果数据不足,函数会返回空的结果表。