溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JavaScript中怎么實(shí)現(xiàn)一個(gè)布林軌策略

發(fā)布時(shí)間:2021-07-06 16:40:19 來(lái)源:億速云 閱讀:267 作者:Leah 欄目:互聯(lián)網(wǎng)科技

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)JavaScript中怎么實(shí)現(xiàn)一個(gè)布林軌策略,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

策略簡(jiǎn)介

布林帶也稱為布林通道,英文簡(jiǎn)稱BOLL。它是最常用的技術(shù)指標(biāo)之一,由約翰·包寧杰(John Bollinger)在1980年代發(fā)明。理論上,價(jià)格總是圍繞著價(jià)值在一定范圍內(nèi)上下波動(dòng),布林帶正是根據(jù)這個(gè)理論基礎(chǔ),又引入了“價(jià)格通道”的概念。

其計(jì)算方式是利用統(tǒng)計(jì)學(xué)原理,先計(jì)算一段時(shí)間價(jià)格的“標(biāo)準(zhǔn)差”,再由均線加/減2倍的標(biāo)準(zhǔn)差,求出價(jià)格的“信賴區(qū)間”。其基本的型態(tài)是由三條軌道線組成的帶狀通道(中軌、上軌、下軌)。中軌為價(jià)格的平均成本,上軌和下軌分別代表價(jià)格的壓力線和支撐線。如下圖所示:

JavaScript中怎么實(shí)現(xiàn)一個(gè)布林軌策略

由于采用了標(biāo)準(zhǔn)差的概念,使得布林通道的寬度會(huì)根據(jù)近期價(jià)格的波動(dòng)而做出動(dòng)態(tài)調(diào)整。波動(dòng)小,布林通道會(huì)變窄;波動(dòng)大,布林通道會(huì)變寬。當(dāng)BOLL通道由寬變窄,說(shuō)明價(jià)格逐漸向均值回歸。當(dāng)BOLL通道由窄變寬,意味著行情開始發(fā)生變化,如果價(jià)格上穿上軌,表明買力增強(qiáng),如果價(jià)格下穿下軌,表明賣力增強(qiáng)。

布林帶指標(biāo)計(jì)算方法

在所有的技術(shù)指標(biāo)中,布林帶的計(jì)算方法是最復(fù)雜之一,其中引進(jìn)了統(tǒng)計(jì)學(xué)中的標(biāo)準(zhǔn)差概念,涉及到中軌線(MB)、上軌線(UP)和下軌線(DN)的計(jì)算。其計(jì)算方法如下:

  • 中軌 = N時(shí)間段的簡(jiǎn)單移動(dòng)平均線

  • 上軌 = 中軌 + K × N時(shí)間段的標(biāo)準(zhǔn)差

  • 下軌 = 中軌 ? K × N時(shí)間段的標(biāo)準(zhǔn)差

function main() {  // 主函數(shù),程序從這里開始執(zhí)行
    while(true){   // 進(jìn)入循環(huán)
        exchange.SetContractType('MA888');    // 設(shè)置合約
        var records = exchange.GetRecords();  // 獲取K線數(shù)組
        var boll = TA.BOLL(records, 50);      // 獲取50周期BOLL指標(biāo)數(shù)組
        top = boll[0];      // 獲取BOLL指標(biāo)上軌數(shù)組
        ma = boll[1];       // 獲取BOLL指標(biāo)中軌數(shù)組
        bottom = boll[2];   // 獲取BOLL指標(biāo)下軌數(shù)組
        Log(top);       // 把BOLL指標(biāo)上軌數(shù)組打印到日志中
        Log(ma);        // 把BOLL指標(biāo)中軌數(shù)組打印到日志中
        Log(bottom);    // 把BOLL指標(biāo)下軌數(shù)組打印到日志中
    }
}

策略邏輯

布林線的使用方法有很多,可以單獨(dú)使用,也可以和其他指標(biāo)結(jié)合在一起使用。 本節(jié)教程我們將采用布林線一種最簡(jiǎn)單的使用方法。即:當(dāng)價(jià)格自下而上突破上軌,即突破上方壓力線時(shí),我們認(rèn)為多方力量正在走強(qiáng),一波上漲行情已經(jīng)形成,買入開倉(cāng)信號(hào)產(chǎn)生;當(dāng)價(jià)格自上而下跌破下軌,即跌破支撐線時(shí),我們認(rèn)為空方力量正在走強(qiáng),一波下跌趨勢(shì)已經(jīng)形成,賣出開倉(cāng)信號(hào)產(chǎn)生。

JavaScript中怎么實(shí)現(xiàn)一個(gè)布林軌策略

如果買入開倉(cāng)后,價(jià)格又重新跌回到了布林線中軌,我們認(rèn)為多方力量正在走弱,或者空方力量正在加強(qiáng),賣出平倉(cāng)信號(hào)產(chǎn)生;如果賣出開倉(cāng)后,價(jià)格又重新漲回到布林線中軌,我們認(rèn)為空方力量正在走弱,或者多方力量正在加強(qiáng),買入平倉(cāng)信號(hào)產(chǎn)生。

買賣條件

  • 多頭開倉(cāng):如果無(wú)持倉(cāng),并且收盤價(jià)大于上軌,并且時(shí)間非14:45

  • 空頭開倉(cāng):如果無(wú)持倉(cāng),并且收盤價(jià)小于下軌,并且時(shí)間非14:45

  • 多頭平倉(cāng):如果持多單,并且收盤價(jià)小于中軌,或者時(shí)間是14:45

  • 空頭平倉(cāng):如果持空單,并且收盤價(jià)大于中軌,或者時(shí)間是14:45

策略代碼實(shí)現(xiàn)

要想實(shí)現(xiàn)策略,首先需要考慮我們需要什么數(shù)據(jù)?通過(guò)什么API去獲?。咳缓笕绾斡?jì)算交易邏輯?最后通過(guò)哪些方式下單方式去交易?接下來(lái),讓我們一步一步來(lái)實(shí)現(xiàn)吧:

第一步:使用CTA策略框架

所謂的CTA策略框架是由發(fā)明者量化官方推出的一套標(biāo)準(zhǔn)框架,使用該框架可以不必考慮開發(fā)量化交易策略的瑣碎問(wèn)題,直接把精力放在編程交易邏輯上。比如,如果不使用該框架的話,在下單的時(shí)候,需要考慮換月移倉(cāng)、下單買賣價(jià)格、下單不成交時(shí)撤單或追單等等問(wèn)題......

function main() {
    $.CTA("rb000/rb888", function(st){
        //編寫策略
    })
}

上圖就是使用發(fā)明者量化工具的CTA策略框架。這是一個(gè)固定的代碼格式,所有的交易邏輯代碼從第3行開始編寫。在使用中除了需要修改品種代碼外(淺黃色),其他地方不用任何修改。

需要注意的是,上圖中的品種代碼是“rb000/rb888”它代表的意思是信號(hào)的數(shù)據(jù)使用的是“rb000”,交易數(shù)據(jù)使用的是“rb888”,并且自動(dòng)換月移倉(cāng)。當(dāng)然你也可以指定具體的品種代碼,比如把品種代碼“rb1910”,就是信號(hào)數(shù)據(jù)和交易數(shù)據(jù)都使用“rb1910”。

第二步:獲取各種數(shù)據(jù)

仔細(xì)想下,都需要哪些數(shù)據(jù)呢?從我們的策略交易邏輯中發(fā)現(xiàn):首先需要獲取當(dāng)前的持倉(cāng)狀態(tài),然后比較收盤價(jià)與布林帶指標(biāo)上中下軌的相互關(guān)系,最后判斷行情是不是即將收盤。那么接下來(lái)讓我們一以獲取這些數(shù)據(jù)吧。

  • 獲取K線數(shù)據(jù)

首先就是獲取K線數(shù)組和上根K線收盤價(jià),因?yàn)橛辛薑線數(shù)組,才能計(jì)算出布林帶指標(biāo)。用代碼寫出來(lái)是這樣的:

function main(){
    $.CTA("rb000/rb888", function(st){

        var r = st.records; // 獲取K線數(shù)組
        if (r.length < 20) return; // 過(guò)濾K線長(zhǎng)度
        var close = r[r.length - 2].close; // 獲取上根K線收盤價(jià)

    })
}

如以上代碼所示:

第4行:獲取K線數(shù)組,這是一個(gè)固定的格式。
第5行:過(guò)濾K線的長(zhǎng)度,因?yàn)槲覀冇?jì)算布林帶指標(biāo)用的參數(shù)是20,當(dāng)K線小于20根的時(shí)候,是無(wú)法計(jì)算布林帶指標(biāo)的。所以這里要過(guò)濾下K線的長(zhǎng)度,如果K線少于20根,就直接返回,繼續(xù)等待下一根K線。
第6行:從獲取的K線數(shù)組中,先獲取上根K線的對(duì)象,再?gòu)脑搶?duì)象中獲取收盤價(jià)。獲取一個(gè)數(shù)組的倒數(shù)第二個(gè)元素,就是這個(gè)數(shù)組的長(zhǎng)度減2(r[r.length - 2]);K線數(shù)組里面的元素都是一個(gè)個(gè)對(duì)象,對(duì)象包含了開盤價(jià)、最高價(jià)、最低價(jià)、收盤價(jià)、成交量、時(shí)間,要獲取收盤價(jià)就直接在后面加上“.”和屬性名就可以了(r[r.length - 2].Close)。

  • 獲取K線時(shí)間數(shù)據(jù)

因?yàn)槲覀兪侨諆?nèi)策略,需要在收盤前平掉倉(cāng)位,所以要判斷當(dāng)前K線是不是臨近收盤,如果是臨近收盤的K線就平掉倉(cāng)位,如果不是臨近收盤的K線就可以開倉(cāng),用代碼寫出來(lái)是這樣的:

function main(){
    $.CTA("rb000/rb888", function(st){

        var r = st.records; // 獲取K線數(shù)組
        if (r.length < 20) return; // 過(guò)濾K線長(zhǎng)度
        var close = r[r.length - 2].close; // 獲取上根K線收盤價(jià)

        var time = new Date(r[r.length - 1].Time);  // 根據(jù)當(dāng)根K線時(shí)間戳,創(chuàng)建一個(gè)時(shí)間對(duì)象
        var isClose = time.getHours() == 14 && time.getMinutes() == 45; // 判斷時(shí)間是否14:45

    })
}

如以上代碼所示:

第8行:獲取當(dāng)根K線的時(shí)間戳屬性,然后創(chuàng)建一個(gè)時(shí)間對(duì)象(new Date(時(shí)間戳))。
第9行:根據(jù)時(shí)間對(duì)象,分別計(jì)算小時(shí)和分鐘數(shù),并判斷當(dāng)根K線的時(shí)間是不是14:45。

  • 獲取持倉(cāng)數(shù)據(jù)

持倉(cāng)信息是量化交易策略中一個(gè)很重要的條件,當(dāng)交易條件成立時(shí),還需要通過(guò)持倉(cāng)狀態(tài)和持倉(cāng)數(shù),來(lái)判斷是否下單。比如:當(dāng)買入開倉(cāng)交易條件成立時(shí),如果有持倉(cāng),就不必在重復(fù)下單了;如果無(wú)持倉(cāng),就可以下單。用代碼寫出來(lái)是這樣的:

function main(){
    $.CTA("rb000/rb888", function(st){

        var r = st.records; // 獲取K線數(shù)組
        if (r.length < 20) return; // 過(guò)濾K線長(zhǎng)度
        var close = r[r.length - 2].close; // 獲取上根K線收盤價(jià)

        var time = new Date(r[r.length - 1].Time);  // 根據(jù)當(dāng)根K線時(shí)間戳,創(chuàng)建一個(gè)時(shí)間對(duì)象
        var isClose = time.getHours() == 14 && time.getMinutes() == 45; // 判斷時(shí)間是否14:45

        var mp = st.position.amount; // 獲取持倉(cāng)信息

    })
}

如以上代碼所示:
第11行:獲取當(dāng)前的持倉(cāng)狀態(tài)。如果有多單,則值是1;如果有空單,則值是-1;如果無(wú)持倉(cāng),則值是0。

  • 獲取布林帶數(shù)據(jù)

接著就需要計(jì)算布林帶指標(biāo)上軌、中軌、下軌的數(shù)值了。那就要先獲取布林帶數(shù)組,在從數(shù)組中獲取上中下軌的數(shù)值。在發(fā)明者量化工具中,獲取布林帶數(shù)組還很簡(jiǎn)單,直接調(diào)用布林帶的API就可以了,難的是獲取上中下軌的數(shù)值,因?yàn)椴剂謳?shù)組是一個(gè)二維數(shù)組。

二維數(shù)組其實(shí)很好理解,它就是數(shù)組中的數(shù)組,那么獲取的順序就是:先獲取數(shù)組中指定的數(shù)組,然后在從指定的數(shù)組中獲取指定的元素,如以下代碼所示:

var arr = [[100, 200, 300], [10, 20, 30], [1, 2, 3]]; // 這是一個(gè)二維數(shù)組
var test = arr[0]; // 先獲取這個(gè)二維數(shù)組里面的第一個(gè)數(shù)組,并把結(jié)果設(shè)置給test
var demo1 = test[0]; // 再?gòu)膖est數(shù)組中,獲取第一個(gè)數(shù)值
demo1;  // 結(jié)果是:100

var demo2 = arr[0][0] // 我們也可以這樣寫
demo2; // 結(jié)果同樣為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; // 過(guò)濾K線長(zhǎng)度
        var close = r[r.length - 2].close; // 獲取上根K線收盤價(jià)

        var time = new Date(r[r.length - 1].Time);  // 根據(jù)當(dāng)根K線時(shí)間戳,創(chuàng)建一個(gè)時(shí)間對(duì)象
        var isClose = time.getHours() == 14 && time.getMinutes() == 45; // 判斷時(shí)間是否14:45

        var mp = st.position.amount; // 獲取持倉(cāng)信息

        var boll = TA.BOLL(r, 20, 2); // 計(jì)算布林帶指標(biāo)
        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ù),就可以編寫交易邏輯以及下單交易的代碼了。格式也非常簡(jiǎn)單,最常用到的是“if語(yǔ)句”,用文字可以描述為:如果條件1和條件2成立,下單;如果條件3或條件4成立,下單。如以下代碼所示:

function main(){
    $.CTA("rb000/rb888", function(st){

        var r = st.records; // 獲取K線數(shù)組
        if (r.length < 20) return; // 過(guò)濾K線長(zhǎng)度
        var close = r[r.length - 2].close; // 獲取上根K線收盤價(jià)

        var time = new Date(r[r.length - 1].Time);  // 根據(jù)當(dāng)根K線時(shí)間戳,創(chuàng)建一個(gè)時(shí)間對(duì)象
        var isClose = time.getHours() == 14 && time.getMinutes() == 45; // 判斷時(shí)間是否14:45

        var mp = st.position.amount; // 獲取持倉(cāng)信息

        var boll = TA.BOLL(r, 20, 2); // 計(jì)算布林帶指標(biāo)
        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; //如果持多單,并且收盤價(jià)小于中軌,或者時(shí)間是14:45,平多
        if (mp == -1 && (close > midPrice || isClose)) return 1; //如果持空單,并且收盤價(jià)大于中軌,或者時(shí)間是14:45,平空
        if (mp == 0 && close > upPrice && !isClose) return 1; //如果無(wú)持倉(cāng),并且收盤價(jià)大于上軌,并且時(shí)間是14:45,開多
        if (mp == 0 && close < downPrice && !isClose) return -1; //如果無(wú)持倉(cāng),并且收盤價(jià)小于下軌,并且時(shí)間是14:45,開空
        
    })
}

以上代碼中,第21行~24行就是交易邏輯以及下單交易的代碼。從上往下分別是:平多、平空、開多、開空。

以開多單(第23行)為例,這是一個(gè)“if語(yǔ)句”,在該語(yǔ)句中如果只執(zhí)行一行代碼,花括號(hào)“{}”是可以省略的。該語(yǔ)句翻譯成文字是:如果當(dāng)前持倉(cāng)是0,并且收盤價(jià)大于上軌,并且K線時(shí)間不是14:45,就“return 1”

細(xì)心的你可能會(huì)發(fā)現(xiàn),這幾行有“return 1”和“return -1”,這是一個(gè)固定的格式,意思就是:如果是買入的就寫“return 1”;如果是賣出的就寫“return -1”。開多和平空都是買入,所以寫“return 1”;開空和平多都是賣出,所以寫“return -1”。

完整的策略代碼

至此一個(gè)完整的策略代碼就寫完了,如果把交易框架、交易數(shù)據(jù)、交易邏輯、下單買賣等分開來(lái)寫是不是很簡(jiǎn)單呢,以下就是這個(gè)策略的整個(gè)代碼:

function main(){
    $.CTA("rb000/rb888", function(st){
        var r = st.records; // 獲取K線數(shù)組
        if (r.length < 20) return; // 過(guò)濾K線長(zhǎng)度
        var close = r[r.length - 2].close; // 獲取上根K線收盤價(jià)
        var time = new Date(r[r.length - 1].Time);  // 根據(jù)當(dāng)根K線時(shí)間戳,創(chuàng)建一個(gè)時(shí)間對(duì)象
        var isClose = time.getHours() == 14 && time.getMinutes() == 45; // 判斷時(shí)間是否14:45
        var mp = st.position.amount; // 獲取持倉(cāng)信息
        var boll = TA.BOLL(r, 20, 2); // 計(jì)算布林帶指標(biāo)
        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; //如果持多單,并且收盤價(jià)小于中軌,或者時(shí)間是14:45,平多
        if (mp == -1 && (close > midPrice || isClose)) return 1; //如果持空單,并且收盤價(jià)大于中軌,或者時(shí)間是14:45,平空
        if (mp == 0 && close > upPrice && !isClose) return 1; //如果無(wú)持倉(cāng),并且收盤價(jià)大于上軌,并且時(shí)間是14:45,開多
        if (mp == 0 && close < downPrice && !isClose) return -1; //如果無(wú)持倉(cāng),并且收盤價(jià)小于下軌,并且時(shí)間是14:45,開空
        
    })
}

有兩個(gè)地方需要注意:

1、盡量(但不是必須)把策略邏輯寫成當(dāng)根K線條件成立,下根K線發(fā)單,或者上根K線條件成立,當(dāng)根K線發(fā)單,這樣回測(cè)的結(jié)果與實(shí)盤的結(jié)果相差不大。不這樣寫也可以,但是要注意策略邏輯是否正確。
2、一般而言,把平倉(cāng)的邏輯寫在開倉(cāng)邏輯的前面,這樣做的目的是,盡量讓策略邏輯符合你的預(yù)期。比如:如果策略邏輯剛好趕上反手的時(shí)候,反手的規(guī)則是,先平倉(cāng)再開新倉(cāng)。而不是先開新倉(cāng),再平倉(cāng)。如果我們直接把平倉(cāng)邏輯寫到開倉(cāng)邏輯前面,就不會(huì)出現(xiàn)這種問(wèn)題。

上述就是小編為大家分享的JavaScript中怎么實(shí)現(xiàn)一個(gè)布林軌策略了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI