這期內(nèi)容當中小編將會給大家?guī)碛嘘PJavaScript中怎么實現(xiàn)一個布林軌策略,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
卡若網(wǎng)站建設公司成都創(chuàng)新互聯(lián),卡若網(wǎng)站設計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為卡若上千多家提供企業(yè)網(wǎng)站建設服務。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設公司要多少錢,請找那個售后服務好的卡若做網(wǎng)站的公司定做!
策略簡介
布林帶也稱為布林通道,英文簡稱BOLL。它是最常用的技術指標之一,由約翰·包寧杰(John Bollinger)在1980年代發(fā)明。理論上,價格總是圍繞著價值在一定范圍內(nèi)上下波動,布林帶正是根據(jù)這個理論基礎,又引入了“價格通道”的概念。
其計算方式是利用統(tǒng)計學原理,先計算一段時間價格的“標準差”,再由均線加/減2倍的標準差,求出價格的“信賴區(qū)間”。其基本的型態(tài)是由三條軌道線組成的帶狀通道(中軌、上軌、下軌)。中軌為價格的平均成本,上軌和下軌分別代表價格的壓力線和支撐線。如下圖所示:
由于采用了標準差的概念,使得布林通道的寬度會根據(jù)近期價格的波動而做出動態(tài)調整。波動小,布林通道會變窄;波動大,布林通道會變寬。當BOLL通道由寬變窄,說明價格逐漸向均值回歸。當BOLL通道由窄變寬,意味著行情開始發(fā)生變化,如果價格上穿上軌,表明買力增強,如果價格下穿下軌,表明賣力增強。
布林帶指標計算方法
在所有的技術指標中,布林帶的計算方法是最復雜之一,其中引進了統(tǒng)計學中的標準差概念,涉及到中軌線(MB)、上軌線(UP)和下軌線(DN)的計算。其計算方法如下:
中軌 = N時間段的簡單移動平均線
上軌 = 中軌 + K × N時間段的標準差
下軌 = 中軌 ? K × N時間段的標準差
function main() { // 主函數(shù),程序從這里開始執(zhí)行 while(true){ // 進入循環(huán) exchange.SetContractType('MA888'); // 設置合約 var records = exchange.GetRecords(); // 獲取K線數(shù)組 var boll = TA.BOLL(records, 50); // 獲取50周期BOLL指標數(shù)組 top = boll[0]; // 獲取BOLL指標上軌數(shù)組 ma = boll[1]; // 獲取BOLL指標中軌數(shù)組 bottom = boll[2]; // 獲取BOLL指標下軌數(shù)組 Log(top); // 把BOLL指標上軌數(shù)組打印到日志中 Log(ma); // 把BOLL指標中軌數(shù)組打印到日志中 Log(bottom); // 把BOLL指標下軌數(shù)組打印到日志中 } }
策略邏輯
布林線的使用方法有很多,可以單獨使用,也可以和其他指標結合在一起使用。 本節(jié)教程我們將采用布林線一種最簡單的使用方法。即:當價格自下而上突破上軌,即突破上方壓力線時,我們認為多方力量正在走強,一波上漲行情已經(jīng)形成,買入開倉信號產(chǎn)生;當價格自上而下跌破下軌,即跌破支撐線時,我們認為空方力量正在走強,一波下跌趨勢已經(jīng)形成,賣出開倉信號產(chǎn)生。
如果買入開倉后,價格又重新跌回到了布林線中軌,我們認為多方力量正在走弱,或者空方力量正在加強,賣出平倉信號產(chǎn)生;如果賣出開倉后,價格又重新漲回到布林線中軌,我們認為空方力量正在走弱,或者多方力量正在加強,買入平倉信號產(chǎn)生。
買賣條件
多頭開倉:如果無持倉,并且收盤價大于上軌,并且時間非14:45
空頭開倉:如果無持倉,并且收盤價小于下軌,并且時間非14:45
多頭平倉:如果持多單,并且收盤價小于中軌,或者時間是14:45
空頭平倉:如果持空單,并且收盤價大于中軌,或者時間是14:45
策略代碼實現(xiàn)
要想實現(xiàn)策略,首先需要考慮我們需要什么數(shù)據(jù)?通過什么API去獲???然后如何計算交易邏輯?最后通過哪些方式下單方式去交易?接下來,讓我們一步一步來實現(xiàn)吧:
第一步:使用CTA策略框架
所謂的CTA策略框架是由發(fā)明者量化官方推出的一套標準框架,使用該框架可以不必考慮開發(fā)量化交易策略的瑣碎問題,直接把精力放在編程交易邏輯上。比如,如果不使用該框架的話,在下單的時候,需要考慮換月移倉、下單買賣價格、下單不成交時撤單或追單等等問題......
function main() { $.CTA("rb000/rb888", function(st){ //編寫策略 }) }
上圖就是使用發(fā)明者量化工具的CTA策略框架。這是一個固定的代碼格式,所有的交易邏輯代碼從第3行開始編寫。在使用中除了需要修改品種代碼外(淺黃色),其他地方不用任何修改。
需要注意的是,上圖中的品種代碼是“rb000/rb888”它代表的意思是信號的數(shù)據(jù)使用的是“rb000”,交易數(shù)據(jù)使用的是“rb888”,并且自動換月移倉。當然你也可以指定具體的品種代碼,比如把品種代碼“rb1910”,就是信號數(shù)據(jù)和交易數(shù)據(jù)都使用“rb1910”。
第二步:獲取各種數(shù)據(jù)
仔細想下,都需要哪些數(shù)據(jù)呢?從我們的策略交易邏輯中發(fā)現(xiàn):首先需要獲取當前的持倉狀態(tài),然后比較收盤價與布林帶指標上中下軌的相互關系,最后判斷行情是不是即將收盤。那么接下來讓我們一以獲取這些數(shù)據(jù)吧。
獲取K線數(shù)據(jù)
首先就是獲取K線數(shù)組和上根K線收盤價,因為有了K線數(shù)組,才能計算出布林帶指標。用代碼寫出來是這樣的:
function main(){ $.CTA("rb000/rb888", function(st){ var r = st.records; // 獲取K線數(shù)組 if (r.length < 20) return; // 過濾K線長度 var close = r[r.length - 2].close; // 獲取上根K線收盤價 }) }
如以上代碼所示:
第4行:獲取K線數(shù)組,這是一個固定的格式。
第5行:過濾K線的長度,因為我們計算布林帶指標用的參數(shù)是20,當K線小于20根的時候,是無法計算布林帶指標的。所以這里要過濾下K線的長度,如果K線少于20根,就直接返回,繼續(xù)等待下一根K線。
第6行:從獲取的K線數(shù)組中,先獲取上根K線的對象,再從該對象中獲取收盤價。獲取一個數(shù)組的倒數(shù)第二個元素,就是這個數(shù)組的長度減2(r[r.length - 2]);K線數(shù)組里面的元素都是一個個對象,對象包含了開盤價、最高價、最低價、收盤價、成交量、時間,要獲取收盤價就直接在后面加上“.”和屬性名就可以了(r[r.length - 2].Close)。
獲取K線時間數(shù)據(jù)
因為我們是日內(nèi)策略,需要在收盤前平掉倉位,所以要判斷當前K線是不是臨近收盤,如果是臨近收盤的K線就平掉倉位,如果不是臨近收盤的K線就可以開倉,用代碼寫出來是這樣的:
function main(){ $.CTA("rb000/rb888", function(st){ var r = st.records; // 獲取K線數(shù)組 if (r.length < 20) return; // 過濾K線長度 var close = r[r.length - 2].close; // 獲取上根K線收盤價 var time = new Date(r[r.length - 1].Time); // 根據(jù)當根K線時間戳,創(chuàng)建一個時間對象 var isClose = time.getHours() == 14 && time.getMinutes() == 45; // 判斷時間是否14:45 }) }
如以上代碼所示:
第8行:獲取當根K線的時間戳屬性,然后創(chuàng)建一個時間對象(new Date(時間戳))。
第9行:根據(jù)時間對象,分別計算小時和分鐘數(shù),并判斷當根K線的時間是不是14:45。
獲取持倉數(shù)據(jù)
持倉信息是量化交易策略中一個很重要的條件,當交易條件成立時,還需要通過持倉狀態(tài)和持倉數(shù),來判斷是否下單。比如:當買入開倉交易條件成立時,如果有持倉,就不必在重復下單了;如果無持倉,就可以下單。用代碼寫出來是這樣的:
function main(){ $.CTA("rb000/rb888", function(st){ var r = st.records; // 獲取K線數(shù)組 if (r.length < 20) return; // 過濾K線長度 var close = r[r.length - 2].close; // 獲取上根K線收盤價 var time = new Date(r[r.length - 1].Time); // 根據(jù)當根K線時間戳,創(chuàng)建一個時間對象 var isClose = time.getHours() == 14 && time.getMinutes() == 45; // 判斷時間是否14:45 var mp = st.position.amount; // 獲取持倉信息 }) }
如以上代碼所示:
第11行:獲取當前的持倉狀態(tài)。如果有多單,則值是1;如果有空單,則值是-1;如果無持倉,則值是0。
獲取布林帶數(shù)據(jù)
接著就需要計算布林帶指標上軌、中軌、下軌的數(shù)值了。那就要先獲取布林帶數(shù)組,在從數(shù)組中獲取上中下軌的數(shù)值。在發(fā)明者量化工具中,獲取布林帶數(shù)組還很簡單,直接調用布林帶的API就可以了,難的是獲取上中下軌的數(shù)值,因為布林帶數(shù)組是一個二維數(shù)組。
二維數(shù)組其實很好理解,它就是數(shù)組中的數(shù)組,那么獲取的順序就是:先獲取數(shù)組中指定的數(shù)組,然后在從指定的數(shù)組中獲取指定的元素,如以下代碼所示:
var arr = [[100, 200, 300], [10, 20, 30], [1, 2, 3]]; // 這是一個二維數(shù)組 var test = arr[0]; // 先獲取這個二維數(shù)組里面的第一個數(shù)組,并把結果設置給test var demo1 = test[0]; // 再從test數(shù)組中,獲取第一個數(shù)值 demo1; // 結果是:100 var demo2 = arr[0][0] // 我們也可以這樣寫 demo2; // 結果同樣為100
如以下代碼中,第13行~19行就是用代碼獲取布林帶上軌、中軌、下軌的數(shù)值。其中第13行是直接使用發(fā)明者量化工具的API,直接獲取布林帶數(shù)組;第14行~16行是先分別獲取二維數(shù)組中的上軌數(shù)組、中軌數(shù)組、下軌數(shù)組;第17行~19行是分別從上軌數(shù)組、中軌數(shù)組、下軌數(shù)組中獲取上根K線的布林帶上軌、中軌、下軌數(shù)值。
function main(){ $.CTA("rb000/rb888", function(st){ var r = st.records; // 獲取K線數(shù)組 if (r.length < 20) return; // 過濾K線長度 var close = r[r.length - 2].close; // 獲取上根K線收盤價 var time = new Date(r[r.length - 1].Time); // 根據(jù)當根K線時間戳,創(chuàng)建一個時間對象 var isClose = time.getHours() == 14 && time.getMinutes() == 45; // 判斷時間是否14:45 var mp = st.position.amount; // 獲取持倉信息 var boll = TA.BOLL(r, 20, 2); // 計算布林帶指標 var upLine = boll[0]; //獲取上軌數(shù)組 var midLine = boll[1]; //獲取中軌數(shù)組 var downLine = boll[2]; //獲取下軌數(shù)組 var upPrice = upLine[upLine.length - 2]; //獲取上根K線的上軌數(shù)組 var midPrice = midLine[midLine.length - 2]; //獲取上根K線的中軌數(shù)組 var downPrice = downLine[downLine.length -2]; //獲取上根K線的下軌數(shù)組 }) }
第三步:下單交易
有了以上數(shù)據(jù),就可以編寫交易邏輯以及下單交易的代碼了。格式也非常簡單,最常用到的是“if語句”,用文字可以描述為:如果條件1和條件2成立,下單;如果條件3或條件4成立,下單。如以下代碼所示:
function main(){ $.CTA("rb000/rb888", function(st){ var r = st.records; // 獲取K線數(shù)組 if (r.length < 20) return; // 過濾K線長度 var close = r[r.length - 2].close; // 獲取上根K線收盤價 var time = new Date(r[r.length - 1].Time); // 根據(jù)當根K線時間戳,創(chuàng)建一個時間對象 var isClose = time.getHours() == 14 && time.getMinutes() == 45; // 判斷時間是否14:45 var mp = st.position.amount; // 獲取持倉信息 var boll = TA.BOLL(r, 20, 2); // 計算布林帶指標 var upLine = boll[0]; //獲取上軌數(shù)組 var midLine = boll[1]; //獲取中軌數(shù)組 var downLine = boll[2]; //獲取下軌數(shù)組 var upPrice = upLine[upLine.length - 2]; //獲取上根K線的上軌數(shù)組 var midPrice = midLine[midLine.length - 2]; //獲取上根K線的中軌數(shù)組 var downPrice = downLine[downLine.length -2]; //獲取上根K線的下軌數(shù)組 if (mp == 1 && (close < midPrice || isClose)) return -1; //如果持多單,并且收盤價小于中軌,或者時間是14:45,平多 if (mp == -1 && (close > midPrice || isClose)) return 1; //如果持空單,并且收盤價大于中軌,或者時間是14:45,平空 if (mp == 0 && close > upPrice && !isClose) return 1; //如果無持倉,并且收盤價大于上軌,并且時間是14:45,開多 if (mp == 0 && close < downPrice && !isClose) return -1; //如果無持倉,并且收盤價小于下軌,并且時間是14:45,開空 }) }
以上代碼中,第21行~24行就是交易邏輯以及下單交易的代碼。從上往下分別是:平多、平空、開多、開空。
以開多單(第23行)為例,這是一個“if語句”,在該語句中如果只執(zhí)行一行代碼,花括號“{}”是可以省略的。該語句翻譯成文字是:如果當前持倉是0,并且收盤價大于上軌,并且K線時間不是14:45,就“return 1”
細心的你可能會發(fā)現(xiàn),這幾行有“return 1”和“return -1”,這是一個固定的格式,意思就是:如果是買入的就寫“return 1”;如果是賣出的就寫“return -1”。開多和平空都是買入,所以寫“return 1”;開空和平多都是賣出,所以寫“return -1”。
完整的策略代碼
至此一個完整的策略代碼就寫完了,如果把交易框架、交易數(shù)據(jù)、交易邏輯、下單買賣等分開來寫是不是很簡單呢,以下就是這個策略的整個代碼:
function main(){ $.CTA("rb000/rb888", function(st){ var r = st.records; // 獲取K線數(shù)組 if (r.length < 20) return; // 過濾K線長度 var close = r[r.length - 2].close; // 獲取上根K線收盤價 var time = new Date(r[r.length - 1].Time); // 根據(jù)當根K線時間戳,創(chuàng)建一個時間對象 var isClose = time.getHours() == 14 && time.getMinutes() == 45; // 判斷時間是否14:45 var mp = st.position.amount; // 獲取持倉信息 var boll = TA.BOLL(r, 20, 2); // 計算布林帶指標 var upLine = boll[0]; //獲取上軌數(shù)組 var midLine = boll[1]; //獲取中軌數(shù)組 var downLine = boll[2]; //獲取下軌數(shù)組 var upPrice = upLine[upLine.length - 2]; //獲取上根K線的上軌數(shù)組 var midPrice = midLine[midLine.length - 2]; //獲取上根K線的中軌數(shù)組 var downPrice = downLine[downLine.length -2]; //獲取上根K線的下軌數(shù)組 if (mp == 1 && (close < midPrice || isClose)) return -1; //如果持多單,并且收盤價小于中軌,或者時間是14:45,平多 if (mp == -1 && (close > midPrice || isClose)) return 1; //如果持空單,并且收盤價大于中軌,或者時間是14:45,平空 if (mp == 0 && close > upPrice && !isClose) return 1; //如果無持倉,并且收盤價大于上軌,并且時間是14:45,開多 if (mp == 0 && close < downPrice && !isClose) return -1; //如果無持倉,并且收盤價小于下軌,并且時間是14:45,開空 }) }
有兩個地方需要注意:
1、盡量(但不是必須)把策略邏輯寫成當根K線條件成立,下根K線發(fā)單,或者上根K線條件成立,當根K線發(fā)單,這樣回測的結果與實盤的結果相差不大。不這樣寫也可以,但是要注意策略邏輯是否正確。
2、一般而言,把平倉的邏輯寫在開倉邏輯的前面,這樣做的目的是,盡量讓策略邏輯符合你的預期。比如:如果策略邏輯剛好趕上反手的時候,反手的規(guī)則是,先平倉再開新倉。而不是先開新倉,再平倉。如果我們直接把平倉邏輯寫到開倉邏輯前面,就不會出現(xiàn)這種問題。
上述就是小編為大家分享的JavaScript中怎么實現(xiàn)一個布林軌策略了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道。