用.NET语言写一个计算股票技术指标DMI的函数,第一个参数为datatable类型,另外两个参数为int型;日期列名为“日期”,开盘价列名为“开盘”,收盘价列名为“收盘”,最高价列名为“最高”,最低价列名为“最低”,返回值为datatable类型,返回值包含PDI,MDI,ADX,ADXR四列,datatable列名不要包含+-等特殊符号,double类型全部四舍五入保留3位小数,加上try-catch出错处理,如果出错直接返回null,写好详细注释。
时间: 2024-03-27 15:41:16 浏览: 15
好的,下面是用.NET语言写计算股票技术指标DMI的函数的代码:
```csharp
using System;
using System.Data;
namespace StockIndicator
{
public static class DMI
{
public static DataTable Calculate(DataTable data, int n, int m)
{
try
{
// 检查输入参数是否合法
if (data == null || n <= 0 || m <= 0)
{
return null;
}
// 初始化计算所需变量
int rowcount = data.Rows.Count;
double[] tr = new double[rowcount];
double[] dmplus = new double[rowcount];
double[] dmminus = new double[rowcount];
double[] diplus = new double[rowcount];
double[] diminus = new double[rowcount];
double[] dx = new double[rowcount];
double[] adx = new double[rowcount];
double[] adxr = new double[rowcount];
// 计算TR、DM和DI值
for (int i = 0; i < rowcount; i++)
{
double high = Convert.ToDouble(data.Rows[i]["最高"]);
double low = Convert.ToDouble(data.Rows[i]["最低"]);
double preclose = i > 0 ? Convert.ToDouble(data.Rows[i - 1]["收盘"]) : 0;
double tr1 = Math.Max(high - low, Math.Abs(high - preclose));
double tr2 = Math.Abs(low - preclose);
tr[i] = Math.Max(tr1, tr2);
if (i > 0)
{
double upmove = high - Convert.ToDouble(data.Rows[i - 1]["最高"]);
double downmove = Convert.ToDouble(data.Rows[i - 1]["最低"]) - low;
if (upmove > downmove && upmove > 0)
{
dmplus[i] = upmove;
}
else if (downmove > upmove && downmove > 0)
{
dmminus[i] = downmove;
}
}
if (i >= n)
{
double sumtr = 0;
double sumdmplus = 0;
double sumdmminus = 0;
for (int j = i - n + 1; j <= i; j++)
{
sumtr += tr[j];
sumdmplus += dmplus[j];
sumdmminus += dmminus[j];
}
diplus[i] = 100 * sumdmplus / sumtr;
diminus[i] = 100 * sumdmminus / sumtr;
}
}
// 计算DX、ADX和ADXR值
for (int i = 0; i < rowcount; i++)
{
if (i >= n + m - 1)
{
double sumdiplus = 0;
double sumdiminus = 0;
for (int j = i - m + 1; j <= i; j++)
{
sumdiplus += diplus[j];
sumdiminus += diminus[j];
}
double dx1 = 100 * Math.Abs(sumdiplus - sumdiminus) / (sumdiplus + sumdiminus);
dx[i] = dx1;
if (i == n + m - 1)
{
double sumdx = 0;
for (int k = i - m + 1; k <= i; k++)
{
sumdx += dx[k];
}
adx[i] = sumdx / m;
}
else
{
adx[i] = (adx[i - 1] * (m - 1) + dx[i]) / m;
}
if (i >= n + m)
{
adxr[i] = (adx[i] + adx[i - m]) / 2;
}
}
}
// 构造返回值
DataTable result = new DataTable();
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 = 0; i < rowcount; i++)
{
double pdi = diplus[i];
double mdi = diminus[i];
double adxval = adx[i];
double adxrval = adxr[i];
if (!double.IsNaN(pdi) && !double.IsNaN(mdi) && !double.IsNaN(adxval) && !double.IsNaN(adxrval))
{
pdi = Math.Round(pdi, 3, MidpointRounding.AwayFromZero);
mdi = Math.Round(mdi, 3, MidpointRounding.AwayFromZero);
adxval = Math.Round(adxval, 3, MidpointRounding.AwayFromZero);
adxrval = Math.Round(adxrval, 3, MidpointRounding.AwayFromZero);
result.Rows.Add(pdi, mdi, adxval, adxrval);
}
}
return result;
}
catch
{
return null;
}
}
}
}
```
在这里,我们使用了一个静态类 `DMI`,其中包含一个静态方法 `Calculate`。这个方法接受一个 `DataTable` 类型的数据表作为输入参数,同时还接受两个整型变量 `n` 和 `m`,表示计算的周期数。在计算过程中,我们首先根据输入的数据表计算出 TR、DM 和 DI 值,然后再根据这些值计算 DX、ADX 和 ADXR 值。最后,我们将计算结果存储到一个新的数据表中,并将其作为输出返回。
在代码实现中,我们采用了一些优化措施,例如使用数组存储中间变量,避免在循环中频繁访问数据表,以提高计算效率。同时,在计算过程中,我们还判断了各种异常情况,如输入参数非法、计算结果无效等,并通过 `try-catch` 语句进行了出错处理,以保证程序的健壮性和稳定性。