用.NET语言写出计算股票技术指标DMI的函数,第一个参数为datatable类型,返回值为datatable类型。所有double类型保留3位小数,写好注释
时间: 2024-03-27 07:41:13 浏览: 38
好的,以下是.NET语言写出计算股票技术指标DMI的函数,第一个参数为datatable类型,返回值为datatable类型。所有double类型保留3位小数,并加上注释:
```csharp
/// <summary>
/// 计算股票技术指标DMI
/// </summary>
/// <param name="dt">行情数据表</param>
/// <returns>计算结果表</returns>
public static DataTable CalculateDMI(DataTable dt)
{
// 创建结果表
DataTable resultDt = new DataTable();
resultDt.Columns.Add("日期", typeof(string)); // 日期
resultDt.Columns.Add("PDI", typeof(double)); // 上升指标线
resultDt.Columns.Add("MDI", typeof(double)); // 下降指标线
resultDt.Columns.Add("ADX", typeof(double)); // 平均动向指数
resultDt.Columns.Add("ADXR", typeof(double)); // 平均动向指数评估值
// 计算TR、HD和LD
double[] trArr = new double[dt.Rows.Count]; // TR数组
double[] hdArr = new double[dt.Rows.Count]; // HD数组
double[] ldArr = new double[dt.Rows.Count]; // LD数组
for (int i = 0; i < dt.Rows.Count; i++)
{
double h = Convert.ToDouble(dt.Rows[i]["最高"]); // 最高价
double l = Convert.ToDouble(dt.Rows[i]["最低"]); // 最低价
double pc = i > 0 ? Convert.ToDouble(dt.Rows[i - 1]["收盘"]) : 0; // 前一日收盘价
double tr = Math.Max(h - l, Math.Max(Math.Abs(h - pc), Math.Abs(l - pc))); // 真实波幅
double hd = h - pc; // 高低价差
double ld = pc - l; // 低高价差
trArr[i] = tr;
hdArr[i] = hd;
ldArr[i] = ld;
}
// 计算PDI、MDI、ADX和ADXR
double[] pdiArr = new double[dt.Rows.Count]; // PDI数组
double[] mdiArr = new double[dt.Rows.Count]; // MDI数组
double[] dxArr = new double[dt.Rows.Count]; // DX数组
double[] adxArr = new double[dt.Rows.Count]; // ADX数组
double[] adxrArr = new double[dt.Rows.Count]; // ADXR数组
double pdi = 0; // 上升方向指标
double mdi = 0; // 下降方向指标
double dx = 0; // 动向指标
double adx = 0; // 平均动向指数
double sumPdi = 0; // PDI的累加和
double sumMdi = 0; // MDI的累加和
double sumDx = 0; // DX的累加和
double sumAdx = 0; // ADX的累加和
for (int i = 0; i < dt.Rows.Count; i++)
{
if (i < 14) // 前14日不计算指标
{
pdiArr[i] = 0;
mdiArr[i] = 0;
dxArr[i] = 0;
adxArr[i] = 0;
adxrArr[i] = 0;
continue;
}
if (i == 14) // 第14日初始化累加和
{
sumPdi = pdiArr.Take(14).Sum();
sumMdi = mdiArr.Take(14).Sum();
sumDx = dxArr.Take(14).Sum();
sumAdx = adxArr.Take(14).Sum();
}
else // 计算累加和
{
sumPdi = sumPdi - pdiArr[i - 15] + pdiArr[i - 1];
sumMdi = sumMdi - mdiArr[i - 15] + mdiArr[i - 1];
sumDx = sumDx - dxArr[i - 15] + dxArr[i - 1];
sumAdx = sumAdx - adxArr[i - 15] + adxArr[i - 1];
}
double trSum = trArr.Skip(i - 14).Take(14).Sum();
double hdSum = hdArr.Skip(i - 14).Take(14).Sum();
double ldSum = ldArr.Skip(i - 14).Take(14).Sum();
pdi = hdSum / trSum * 100; // 上升方向指标
mdi = ldSum / trSum * 100; // 下降方向指标
double diff = Math.Abs(pdi - mdi);
double sum = pdi + mdi;
dx = diff / sum * 100; // 动向指标
adx = sumDx / 14; // 平均动向指数
adxr = (adx + adxArr[i - 1]) / 2; // 平均动向指数评估值
pdiArr[i] = Math.Round(pdi, 3);
mdiArr[i] = Math.Round(mdi, 3);
dxArr[i] = Math.Round(dx, 3);
adxArr[i] = Math.Round(adx, 3);
adxrArr[i] = Math.Round(adxr, 3);
}
// 将计算结果添加到结果表中
for (int i = 0; i < dt.Rows.Count; i++)
{
DataRow row = resultDt.NewRow();
row["日期"] = dt.Rows[i]["日期"];
row["PDI"] = pdiArr[i];
row["MDI"] = mdiArr[i];
row["ADX"] = adxArr[i];
row["ADXR"] = adxrArr[i];
resultDt.Rows.Add(row);
}
return resultDt;
}
```
以上函数将计算每日的TR、HD和LD,再根据14日计算PDI、MDI、DX、ADX和ADXR,并将计算结果添加到结果表中,最后返回该结果表。
希望这个函数能够满足你的需求,如果有任何问题,欢迎随时向我提出。
阅读全文