Oracle存储过程实现BOLL(布林线)计算

BOLL公式

首先我们要了解布林线的计算公式,可以去百度百科或者维基百科上看
这是我整理的布林线公式:

布林线(BOLL):
上轨线(UP): MB + 2 * MD
中轨线(MB): N日的MA
下轨线(DN): MB – 2 * MD
MA: N日均值
MD: 平方根N日的(C – MA)的两次方和除以N

可以看到布林线的计算公式还是很简单的,中轨线(MB)就是当天的N日均值,一般都会使用20日作为参数,其中比较有难度的就是MD这个标准差的计算,C是N日内每日对应的收盘价,或者更直观一点
在这里插入图片描述
这个σ就是MD,xi就是N日内每日的均值, ̅x就是MA,n就是参数,一般为20,把对应的数据代进去,我们就能算出MD了;

数据准备

了解公式后没有数据也不能计算,大家可以去下面这篇文章看数据准备,而且布林线的计算也需要20日均线:
https://blog.csdn.net/qq_16186465/article/details/118059033

表准备

我是单独把数据存在一个独立的表里,所以要新建一个BOLL表,大家也可以在原数据表创建对应字段也行:

--创建BOLL表 create table BOLL (dates date, BOLLUP number, BOLLMB number, BOLLDN number); --把STOCKDATA表中的日期复制给BOLL表 insert into BOLL(dates) select dates from STOCKDATA;

里面这个STOCKDATA表就是上面数据准备的表,所以我这个关联性还是挺大的

存储过程

CREATE OR REPLACE PROCEDURE GETBOLL AS var_MD number; -- 近20日收盘价标准差 var_MB number; -- 中轨线, 也是当天20日均线值 var_UP number; -- 上轨线 var_DN number; -- 下轨线 var_count number := 0; -- 用作数组长度,或下标 var_sum number := 0; -- 用作标准差求和部分 type arr_num is table of number index by BINARY_INTEGER; -- 定义一个一维数组 arr_close arr_num; -- 用于存放近20日内收盘价 cursor stockdata is -- 声明游标stockdata select dates, closingrate from STOCKDATA order by dates asc; BEGIN -- 开始存储过程 for i in stockdata loop -- 游标FOR循环 var_count := var_count + 1; -- 数组下标 var_MB := GETMA(i.dates, 20); -- 调用GETMA函数,传入:当前日期,20日 意为获取当天的20日均线值 arr_close(var_count) := i.closingrate; -- 将当前收盘价存入数组 if var_count = 20 then -- 当数组长度达20时执行 for j in 1 .. 20 loop -- FOR循环从1到20,将数组中的数据求和,此处为计算标准差求和部分 var_sum := var_sum + power((arr_close(j) - var_MB), 2); end loop; -- 结束循环 for j in 1 .. 19 loop -- 数组中全部数据往前移动一个元素,留最后一个位置给下次的收盘价 arr_close(j) := arr_close(j + 1); end loop; -- 结束循环 var_MD := sqrt(var_sum / 20); -- 计算完整的标准差 var_UP := var_MB + 2 * var_MD; -- 公式 UP = MB + 2 * MD var_DN := var_MB - 2 * var_MD; -- 公式 DN = MB - 2 * MD var_count := 19; -- 数组长度变为19 var_sum := 0; -- 清空数据,方便下次求和 update BOLL set BOLLUP = round(var_UP,2), BOLLDN = round(var_DN,2), BOLLMB = var_MB -- 更新数据 where dates = i.dates; end if; -- 结束判断 end loop; -- 结束游标FOR循环 commit; -- 提交,使用update、delete、insert、alter时一定要提交 END; -- 结束存储过程

计算布林线的时候只要解决计算MD这个方差,其他都很容易就能代入公式计算了
其中我封装了一个GETMA获取均值的函数:

CREATE OR REPLACE FUNCTION GETMA(var_date in date, days in number) RETURN number AS var_MA number; var_exists number; var_sql varchar(100) := ''; BEGIN select count(*) into var_exists from user_tab_cols where table_name= 'STOCKDATA' and column_name= 'MA'||days; if var_exists = 0 then MA(days); end if; var_sql := 'select MA'||days||' from stockdata where dates = '''||var_date||''''; execute immediate var_sql into var_MA; RETURN var_MA; END;

这里面又有一个调用存储过程MA,是我之前写的计算日均线存储过程,所以关联性确实很大,大家也可以用自己的方法,我也只是给出一个参考,主要还是学习思路吧

结尾

我相信还有比我更好、更快的计算思路和方法,如果有小伙伴的更好可以分享出来大家互相学习