c#.net開發金融行情分析軟體k線圖蠟燭圖之布林線名額計算
首先我們看一下,百度關于布林線名額的計算公式
在所有的名額計算中,BOLL名額的計算方法是最複雜的之一,其中引進了統計學中的标準差概念,涉及到中軌線(MB)、上軌線(UP)和下軌線(DN)的計算。另外,和其他名額的計算一樣,由于選用的計算周期的不同,BOLL名額也包括日BOLL名額、周BOLL名額、月BOLL名額年BOLL名額以及分鐘BOLL名額等各種類型。經常被用于股市研判的是日BOLL名額和周BOLL名額。雖然它們的計算時的取值有所不同,但基本的計算方法一樣。 以日BOLL名額計算為例,其計算方法如下:
日BOLL名額的計算公式
中軌線=N日的移動平均線
上軌線=中軌線+兩倍的标準差
下軌線=中軌線-兩倍的标準差
日BOLL名額的計算過程
1)計算MA
MA=N日内的收盤價之和÷N
2)計算标準差MD
MD=平方根N日的(C-MA)的兩次方之和除以N
3)計算MB、UP、DN線
MB=N日的MA
UP=MB+2×MD
DN=MB-2×MD
各大股票交易軟體預設N是20,是以MB等于當日20日均線值
在股市分析軟體中,BOLL名額一共由四條線組成,即上軌線UP 、中軌線MB、下軌線DN和價格線。其中上軌線UP是UP數值的連線,用黃色線表示;中軌線MB是MB數值的連線,用白色線表示;下軌線DN是DN數值的連線,用紫色線表示;價格線是以美國線表示,顔色為淺藍色。和其他技術名額一樣,在實戰中,投資者不需要進行BOLL名額的計算,主要是了解BOLL的計算方法和過程,以便更加深入地掌握BOLL名額的實質,為運用名額打下基礎。
筆者對上述計算公式研究了一下,還是看不懂,踩坑了很久,才弄了代碼,代碼并不複雜,隻是邏輯上容易了解錯誤。
public void GetBollUp()
{
List<float> klineBollUp = new List<float>();
List<float> klineBollMiddle = new List<float>();
List<float> klineBollDown = new List<float>();
///首先根據公式,計算一系列ma,存放在清單中,取值N 為28日
for (int i=0;i<allcount;i++)
{
float ma28 = 0;
if ((i + 28) < allcount)
{
for (int j = i; j < (i + 28); j++)
{
ma28 += klineAllClose[j];
}
ma28 /= 28;
klineBollMiddle.Add(ma28);
}
else
{
break;
}
}
//按照公式,循環計算 上軌,下軌值
for (int i = 0; i < allcount; i++)
{
float ebiaozhuncha = 0;
if ((i + 28) < allcount)
{
for (int j = i; j < (i + 28); j++)
{
try
{
//方差和計算
float linshiflostdown = klineAllClose[j] - klineBollMiddle[i];
ebiaozhuncha += linshiflostdown * linshiflostdown;
}
catch(Exception )
{
}
}
//方差均值
ebiaozhuncha /= 28;
///按照公式, 上軌取值,ma+2*平方根(方差),下軌取值,ma-2*平方根(方差)
klineBollUp.Add(klineBollMiddle[i] + 2*(float)Math.Sqrt(ebiaozhuncha));
klineBollDown.Add(klineBollMiddle[i] - 2* (float)Math.Sqrt(ebiaozhuncha));
}
else
{
break;
}
}
//判斷圖表可呈現區域的 數量
int kejiandatecount = klineXoint.Length;
int kejiandabollcount = klineBollUp.Count;
int kejiancount = 0;
if(kejiandatecount< kejiandabollcount)
{
kejiancount = kejiandatecount;
}
else
{
kejiancount = kejiandabollcount;
}
pointFsUp = new PointF[kejiancount];
pointFsMiddl = new PointF[kejiancount];
pointFsDown = new PointF[kejiancount];
if (kejiandatecount > 0 && kejiandabollcount>0)
{
///傳回圖表可見數量
for (int i = 0; i < kejiancount; i++)
{
///傳回一系列計算好的 上軌,中規,下軌 點的位置 pointf,如果右側是價格,則要根據價格,計算y的像素位置
if (kejiandatecount < kejiandabollcount)
{
pointFsUp[i] = new PointF(klineXoint[kejiancount - i - 1], (highestprice - klineBollUp[i]) / tickprice);
pointFsMiddl[i] = new PointF(klineXoint[kejiancount - i - 1], (highestprice - klineBollMiddle[i]) / tickprice);
pointFsDown[i] = new PointF(klineXoint[kejiancount - i - 1], (highestprice - klineBollDown[i]) / tickprice);
}
else
{
pointFsUp[i] = new PointF(klineXoint[kejiandatecount - i - 1], (highestprice - klineBollUp[i]) / tickprice);
pointFsMiddl[i] = new PointF(klineXoint[kejiandatecount - i - 1], (highestprice - klineBollMiddle[i]) / tickprice);
pointFsDown[i] = new PointF(klineXoint[kejiandatecount - i - 1], (highestprice - klineBollDown[i]) / tickprice);
}
}
}
}
效果圖: