量化交易軟件策略:使用計(jì)量經(jīng)濟(jì)學(xué)方法分析圖表
簡(jiǎn)介
我經(jīng)常聽到有關(guān)市場(chǎng)動(dòng)蕩不穩(wěn)的言論。這也解釋了為何無(wú)法實(shí)現(xiàn)成功的長(zhǎng)期交易。但事實(shí)果真如此嗎?讓我們嘗試從科學(xué)的角度分析這一問(wèn)題。赫茲量化將選擇計(jì)量經(jīng)濟(jì)學(xué)方法進(jìn)行分析。為何選擇計(jì)量經(jīng)濟(jì)學(xué)方法?首先,MQL 社區(qū)熱衷于追求精確性,而這只能通過(guò)數(shù)學(xué)和統(tǒng)計(jì)學(xué)予以實(shí)現(xiàn)。其次,如果我沒(méi)弄錯(cuò)的話,之前在這方面尚屬空白。
需要指出的是,成功的長(zhǎng)期交易問(wèn)題無(wú)法通過(guò)一篇文章就得以解決?,F(xiàn)在,我只打算介紹選定模型的幾種診斷方法,希望在以后的使用中能夠體現(xiàn)其價(jià)值。
此外,我將盡可能清楚介紹一些枯燥的理論知識(shí),包括公式、定理和假設(shè)。然而,我希望讀者已經(jīng)了解統(tǒng)計(jì)學(xué)的一些基本概念,例如:假設(shè)、統(tǒng)計(jì)顯著性、統(tǒng)計(jì)(統(tǒng)計(jì)標(biāo)準(zhǔn))、離差、分布、概率、回歸、自相關(guān)等。

編輯切換為居中
1. 時(shí)間序列的特性
顯而易見(jiàn),赫茲量化分析的對(duì)象是價(jià)格序列(及其派生物),這是一個(gè)時(shí)間序列。
計(jì)量經(jīng)濟(jì)學(xué)家從頻率法(頻譜分析、小波分析)和時(shí)域法(互相關(guān)分析、自相關(guān)分析)的角度研究時(shí)間序列。市面上已經(jīng)有了頻譜方法介紹方面的文章,讀者可自行查閱《構(gòu)建頻譜分析》一文。在此,我建議將注意力集中在時(shí)域方法、自相關(guān)分析尤其是條件方差分析上。
在價(jià)格時(shí)間序列表現(xiàn)的描述方面,非線性模型要優(yōu)于線性模型。這就是我們?cè)诒疚闹醒芯糠蔷€性模型的原因。
價(jià)格時(shí)間序列的一些特性只能通過(guò)特定的計(jì)量經(jīng)濟(jì)模型加以考慮。首先,這些特性包括:“肥尾”、波動(dòng)集群性和杠桿效應(yīng)。

編輯
圖 1. 具有不同峰度的分布。
圖 1 展示了具有不同峰度(峭度)的 3 個(gè)分布。其峭度小于正態(tài)分布峭度的分布具有“肥尾”的可能性要大于其他分布。該分布標(biāo)為粉紅色。
赫茲量化需要分布來(lái)顯示隨機(jī)值的概率密度,概率密度用于計(jì)算研究序列的值。
通過(guò)提到波動(dòng)的集群性(出自群集 - 群、集中),我們是指:高波動(dòng)時(shí)期后會(huì)出現(xiàn)高波動(dòng)時(shí)間周期,低波動(dòng)時(shí)期后面同樣會(huì)出現(xiàn)低波動(dòng)時(shí)期。如果昨天發(fā)生價(jià)格波動(dòng),則今天也很可能發(fā)生。因此,波動(dòng)存在慣性。圖 2 顯示波動(dòng)表現(xiàn)為群集性。

編輯切換為居中
圖 2. USDJPY 每日收益的波動(dòng)集群性。
下跌市場(chǎng)的波動(dòng)杠桿效應(yīng)要甚于上漲市場(chǎng)的該效應(yīng)。它受制于杠桿系數(shù)的增大,而杠桿系數(shù)取決于股價(jià)下跌時(shí)所借資產(chǎn)與自有資產(chǎn)的比率。然而,該效應(yīng)適用于股票市場(chǎng)而非期貨市場(chǎng)。因此,赫茲量化無(wú)需對(duì)其進(jìn)行更多考慮。
2. GARCH 模型
好了,赫茲量化的主要目標(biāo)是通過(guò)一些模型來(lái)預(yù)測(cè)匯率(價(jià)格)。計(jì)量經(jīng)濟(jì)學(xué)家使用數(shù)學(xué)模型來(lái)描述可進(jìn)行定量估計(jì)的某種效應(yīng)。簡(jiǎn)言之,他們根據(jù)事件選用不同公式,通過(guò)這種方式來(lái)描述事件。
考慮到所分析的時(shí)間序列具有上文提到的屬性,能將這些屬性考慮在內(nèi)的最佳模型就是非線性模型。最常用的非線性模型之一是 GARCH 模型。它將如何幫助我們?在其主體(函數(shù))內(nèi),它將考慮序列的波動(dòng),即離差在不同觀察周期的波動(dòng)。計(jì)量經(jīng)濟(jì)學(xué)家使用了一個(gè)晦澀的術(shù)語(yǔ)來(lái)命名該效應(yīng) - heteroscedasticity(出自希臘語(yǔ):hetero 表示“不同”,skedasis 表示“離差”)。
如果我們來(lái)觀察一下公式本身,赫茲量化會(huì)發(fā)現(xiàn)該模型表明離差的當(dāng)前波動(dòng) (σ2t)受參數(shù)先前的變化 (?2t-i) 和離差先前的估計(jì)(所謂的“舊消息”)(σ2t-i) 所影響:

編輯
限制為

編輯
其中:?t - 非標(biāo)準(zhǔn)化創(chuàng)新;α0、βi 、αi 、q(ARCH 成員 ?2 的階)、p(GARCH 成員 σ2 的階) - ?估計(jì)的參數(shù)和模型的階。
3. 回報(bào)指標(biāo)
實(shí)際上,赫茲量化要預(yù)測(cè)的不是價(jià)格序列本身,而是回報(bào)序列。價(jià)格變化的對(duì)數(shù)(不斷變化的回報(bào))確定為回報(bào)百分比的自然對(duì)數(shù):

編輯
其中:
Pt - 是在時(shí)間 t處的價(jià)格序列的值;
Pt-1 - 是在時(shí)間 t-1處的價(jià)格序列的值;
pt = ln(Pt) ?- 是自然對(duì)數(shù) Pt。
實(shí)際上,使用回報(bào)要優(yōu)于使用價(jià)格的主要原因是回報(bào)具有更好的統(tǒng)計(jì)特性。
因此,赫茲量化來(lái)創(chuàng)建一個(gè)回報(bào)指標(biāo) ReturnsIndicator.mq5,它對(duì)我們非常有用。在這里,我要引用《面向新手的自定義指標(biāo)》一文,它以易于理解的方式介紹了創(chuàng)建指標(biāo)的算法。這就是為何在所提及公式已實(shí)施的情況下,我只提供代碼的原因。我認(rèn)為這非常簡(jiǎn)單,無(wú)需贅言。
//+------------------------------------------------------------------+ //| Custom indicator iteration function ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, ? ? ?// size of the array price[] ? ? ? ? ? ? ? ?const int prev_calculated, ?// number of bars available at the previous call ? ? ? ? ? ? ? ?const int begin, ? ? ? ? ? ?// index of the array price[] the reliable data starts from ? ? ? ? ? ? ? ?const double& price[]) ? ? ?// array for the calculation itself ?{ //--- ? int start; ? if(prev_calculated<2) start=1; ?// start filling ReturnsBuffer[] from the 1-st index, not 0. ? else start=prev_calculated-1; ? // set 'start' equal to the last index in the arrays ? for(int i=start;i<rates_total;i++) ? ? { ? ? ?ReturnsBuffer[i]=MathLog(price[i]/price[i-1]); ? ? } //--- return value of prev_calculated for next call ? return(rates_total); ?} //+------------------------------------------------------------------+
我唯一要強(qiáng)調(diào)的是回報(bào)序列始終比主序列少 1 個(gè)元素。這就是我們從第二個(gè)元素開始計(jì)算回報(bào)數(shù)組的原因,第一個(gè)元素始終等于 0。
因此,赫茲量化可以使用 ReturnsIndicator 指標(biāo)獲得一個(gè)隨機(jī)時(shí)間序列,并將該序列用于研究。
4. 統(tǒng)計(jì)檢驗(yàn)
現(xiàn)在是時(shí)候進(jìn)行統(tǒng)計(jì)檢驗(yàn)了。之所以進(jìn)行統(tǒng)計(jì)檢驗(yàn),是為了確定時(shí)間序列中是否有任何跡象表明,使用某個(gè)模型或其他模型更為合適。在我們的案例中,這個(gè)模型就是 GARCH 模型。
使用 Ljung-Box-Pierce Q 檢驗(yàn)檢查序列的自相關(guān)是隨機(jī)發(fā)生還是存在一種關(guān)聯(lián)性。為此,我們需要編寫一個(gè)新的函數(shù)。在這里,自相關(guān)指的是同一時(shí)間序列 X (t) 在 t1 和 t2 時(shí)刻的值之間的相互關(guān)系(概率連接)。如果 t1 和 t2 時(shí)刻彼此相鄰(一個(gè)接一個(gè)),則我們會(huì)尋找序列成員與按某個(gè)時(shí)間單位偏移的同一序列成員之間的關(guān)系:x1, x2, x3, ... и x1+1, x2+1, x3+1, ...移動(dòng)成員的這種效應(yīng)稱為滯后(時(shí)延、延遲)。滯后值可以是任意正數(shù)。
現(xiàn)在,我要作補(bǔ)充說(shuō)明,告訴您以下事項(xiàng)。據(jù)我所知,無(wú)論是 C++ 還是 MQL5,都沒(méi)有包含復(fù)雜統(tǒng)計(jì)計(jì)算和平均統(tǒng)計(jì)計(jì)算的標(biāo)準(zhǔn)程序庫(kù)。通常,此類計(jì)算需要使用專門的統(tǒng)計(jì)工具進(jìn)行。對(duì)我而言,使用 Matlab、STATISTICA 9 等工具解決問(wèn)題要更加容易。然而,我之所以決定不使用外部庫(kù),第一是為了展示 MQL5 語(yǔ)言在計(jì)算方面具有強(qiáng)大功能,第二是因?yàn)槲以诰帉?MQL 代碼時(shí)學(xué)到了不少知識(shí)。
現(xiàn)在我們需要進(jìn)行如下說(shuō)明。要執(zhí)行 Q 檢驗(yàn),赫茲量化需要使用復(fù)數(shù)。這正是我準(zhǔn)備復(fù)數(shù)類的原因。理想情況下,它應(yīng)該被稱為 CComplex。好啦,我讓自己放松一下吧。我確信讀者已有所準(zhǔn)備,不需要我解釋什么是復(fù)數(shù)了。就我個(gè)人而言,我不喜歡 MQL5 和 MQL4 中發(fā)布的計(jì)算傅里葉變換的函數(shù);復(fù)數(shù)在其中的使用不太明顯。此外,還有一個(gè)障礙,那就是無(wú)法用 MQL5 來(lái)覆蓋算術(shù)運(yùn)算符。因此我不得不尋求其他方法,并避免使用標(biāo)準(zhǔn) "C" 標(biāo)記。我通過(guò)以下方式實(shí)現(xiàn)復(fù)數(shù)類:
class Complex ?{ public: ? double ? ? ? ? ? ?re,im; //re -real component of the complex number, im - imaginary public: ? void ? ? ? ? ? ? ?Complex(){}; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //default constructor ? void ? ? ? ? ? ? ?setComplex(double rE,double iM){re=rE; im=iM;}; //set method (1-st variant) ? void ? ? ? ? ? ? ?setComplex(double rE){re=rE; im=0;}; ? ? ? ? ? //set method (2-nd variant) ? ? void ? ? ? ? ? ? ?~Complex(){}; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//destructor ? void ? ? ? ? ? ? ?opEqual(const Complex &y){re=y.re;im=y.im;}; ? //operator= ? void ? ? ? ? ? ? ?opPlus(const Complex &x,const Complex &y); ? ? ?//operator+ ? ? void ? ? ? ? ? ? ?opPlusEq(const Complex &y); ? ? ? ? ? ? ? ? ? ?//operator+= ? void ? ? ? ? ? ? ?opMinus(const Complex &x,const Complex &y); ? ? //operator- ? void ? ? ? ? ? ? ?opMult(const Complex &x,const Complex &y); ? ? ?//operator* ? ? void ? ? ? ? ? ? ?opMultEq(const Complex &y); ? ? ? ? ? ? ? ? ? ?//operator*= (1-st variant) ? ? ? void ? ? ? ? ? ? ?opMultEq(const double y); ? ? ? ? ? ? ? ? ? ? ? //operator*= (2-nd variant) ? ? ? void ? ? ? ? ? ? ?conjugate(const Complex &y); ? ? ? ? ? ? ? ? ? //conjugation of complex numbers ? double ? ? ? ? ? ?norm(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //normalization };
例如,兩個(gè)復(fù)數(shù)求和的操作可使用 opPlus 方法來(lái)進(jìn)行,減法可使用 opMinus 方法來(lái)執(zhí)行,等等。如果您只是編寫代碼 c = a + b(其中 a、b、c 是復(fù)數(shù)),則編譯器將顯示一個(gè)錯(cuò)誤。但它將接受以下表達(dá)方式:c.opPlus(a,b)。
必要時(shí),用戶可擴(kuò)展復(fù)數(shù)類的方法集。例如,您可以添加除法運(yùn)算符。
此外,我也需要用于處理復(fù)數(shù)數(shù)組的輔助函數(shù)。這就是我在復(fù)數(shù)類外部實(shí)現(xiàn)此類函數(shù)的原因——不是為了在其中循環(huán)處理數(shù)組元素,而是直接使用由引用傳遞的數(shù)組。共有三個(gè)這樣的函數(shù):
getComplexArr(從一個(gè)復(fù)數(shù)數(shù)組返回一個(gè)二維實(shí)數(shù)數(shù)組);
setComplexArr(從一個(gè)一維實(shí)數(shù)數(shù)組返回一個(gè)復(fù)數(shù)數(shù)組);
setComplexArr2(從一個(gè)二維實(shí)數(shù)數(shù)組返回一個(gè)復(fù)數(shù)數(shù)組)。
應(yīng)該注意的是,這些函數(shù)會(huì)返回通過(guò)引用傳遞的數(shù)組。這是為什么它們的主體中沒(méi)有包含 "return" 運(yùn)算符的原因。不過(guò),根據(jù)邏輯推理,盡管其類型為空,我想我們?nèi)钥梢杂懻摶貓?bào)的問(wèn)題。
復(fù)數(shù)類和輔助函數(shù)在頭文件 Complex_class.mqh 中進(jìn)行了說(shuō)明。
接下來(lái)在執(zhí)行檢驗(yàn)時(shí),赫茲量化將需要自相關(guān)函數(shù)和傅里葉變換函數(shù)。因此,赫茲量化需要一個(gè)新類,讓我們命名為 CFFT 吧。它將為傅里葉變換處理復(fù)數(shù)數(shù)組。傅里葉類如下所示:
class CFFT ?{ public: ? Complex ? ? ? ? ? Input[]; ?//input array of complex numbers ? Complex ? ? ? ? ? Output[]; //output array of complex numbers public: ? bool ? ? ? ? ? ? ?Forward(const uint N); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //direct Fourier transformation ? bool ? ? ? ? ? ? ?InverseT(const uint N,const bool Scale=true); ? ? ? ? ? ?//weighted reverse Fourier transformation ? bool ? ? ? ? ? ? ?InverseF(const uint N,const bool Scale=false); ? ? ? ? ? //non-weighted reverse Fourier transformation ? void ? ? ? ? ? ? ?setCFFT(Complex &data1[],Complex &data2[],const uint N); //set method(1-st variant) ? void ? ? ? ? ? ? ?setCFFT(Complex &data1[],Complex &data2[]); ? ? ? ? ? ? ?//set method (2-nd variant) protected: ? void ? ? ? ? ? ? ?Rearrange(const uint N); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // regrouping ? void ? ? ? ? ? ? ?Perform(const uint N,const bool Inverse); ? ? ? ? ? ? ? ?// implementation of transformation ? void ? ? ? ? ? ? ?Scale(const uint N); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // weighting ?};
應(yīng)該注意的是,所有傅里葉變換都通過(guò)數(shù)組執(zhí)行,數(shù)組的長(zhǎng)度符合條件 2^N(其中 N 是 2 的冪)。通常來(lái)說(shuō),數(shù)組的長(zhǎng)度不等于 2^N。本例中數(shù)組的長(zhǎng)度增加到 2^N 的值,2^N ?>= n,其中 n 是數(shù)組的長(zhǎng)度。添加的數(shù)組元素等于 0。這種數(shù)組處理是在 autocorr 函數(shù)的主體中使用輔助函數(shù) nextpow2 和 pow 函數(shù)實(shí)現(xiàn)的:
int nFFT=pow(2,nextpow2(ArraySize(res))+1); ? ? ?//power rate of two
因此,如果我們有一個(gè)初始數(shù)組,其長(zhǎng)度 (n) 等于 73585,則函數(shù) nextpow2 將返回值 17,其中 2^17 = 131072。換言之,返回的值比 n 大 pow(2, ceil(log(n)/log(2)))。接下來(lái)我們來(lái)計(jì)算 nFFT 的值:2^(17+1) = 262144. 這將是輔助數(shù)組的長(zhǎng)度,它從 73585 到 262143 之間的所有元素都等于 0。
傅里葉類在頭文件 FFT_class.mqh 中進(jìn)行了說(shuō)明。
為節(jié)省篇幅,我將跳過(guò)有關(guān)如何實(shí)現(xiàn) CFFT 類的說(shuō)明。感興趣的讀者可在隨附文件中找到這些說(shuō)明?,F(xiàn)在,赫茲量化來(lái)看一下自相關(guān)函數(shù)。
void autocorr(double &ACF[],double &res[],int nLags) ?//1-st variant of function /* selective autocorrelation function (ACF) ?for unidimensional stochastic time series ? ACF - output array of calculated values of the autocorrelation function; ? res - array of observation of stochastic time series; ? nLags - maximum number of lags the ACF is calculated for. */ ?{ ? Complex Data1[],Data21[], //input arrays of complex numbers ? Data2[],Data22[], ? ? ? ? //output arrays of complex numbers ? cData[]; ? ? ? ? ? ? ? ? ?//array of conjugated complex numbers ? ? ? ? ? ? double rA[][2]; ? ? ? ? ? //auxiliary two-dimensional array of real numbers ? int nFFT=pow(2,nextpow2(ArraySize(res))+1); ? ? ?//power rate of two ? ArrayResize(rA,nFFT);ArrayResize(Data1,nFFT); ? ?//correction of array sizes ? ArrayResize(Data2,nFFT);ArrayResize(Data21,nFFT); ? ArrayResize(Data22,nFFT);ArrayResize(cData,nFFT); ? double rets1[]; ? ? ? ? ? ? ? ? ? //an auxiliary array for observing the series ? double m=mean(res); ? ? ? ? ? ? ? //arithmetical mean of the array res ? ArrayResize(rets1,nFFT); ? ? ? ? ?//correction of array size ? for(int t=0;t<ArraySize(res);t++) //copy the initial array of observation ? ? ? // to the auxiliary one with correction by average ? ? rets1[t]=res[t]-m; ? setComplexArr(Data1,rets1); //set input array of complex numbers ? ? CFFT F,F1; ? ? ? ? ? ? ? ? ?//initialize instances of the CFFT class ? F.setCFFT(Data1,Data2); ? ? //initialize data-members for the instance F ? F.Forward(nFFT); ? ? ? ? ? ?//perform direct Fourier transformation ? for(int i=0;i<nFFT;i++) ? ? { ? ? ?Data21[i].opEqual(F.Output[i]);//assign the values of the F.Output array to the Data21 array; ? ? ?cData[i].conjugate(Data21[i]); //perform conjugation for the array Data21 ? ? ?Data21[i].opMultEq(cData[i]); ?//multiplication of the complex number by the one adjacent to it ? ? ? ? ? ? ? ? ? ? //results in a complex number that has only real component not equal to zero ? ? } ? F1.setCFFT(Data21,Data22); ? //initialize data-members for the instance F1 ? ? F1.InverseT(nFFT); ? ? ? ? ? //perform weighter reverse Fourier transformation ? getComplexArr(rA,F1.Output); //get the result in double format after ? ? ? ? ? ? ? ? ? ? //weighted reverse Fourier transformation ? ? for(int i=0;i<nLags+1;i++) ? ? { ? ? ?ACF[i]=rA[i][0]; ? ? ? ? ?//in the output ACF array save the calculated values ? ? ? ? ? ? ? ? ? ?//of autocorrelation function ? ? ?ACF[i]=ACF[i]/rA[0][0]; ? //normalization relatively to the first element ? ? } ?}
因此,赫茲量化已計(jì)算了指定滯后值的 ACF 值?,F(xiàn)在我們可以將自相關(guān)函數(shù)用于 Q 檢驗(yàn)。檢驗(yàn)函數(shù)本身會(huì)顯示如下:
void lbqtest(bool &H[],double &rets[]) /* Function that implements the Q test of Ljung-Box-Pierce ? H - output array of logic values, that confirm or disprove ? ?the zero hypothesis on the specified lag; ? rets - array of observations of the stochastic time series; */ ?{ ? double lags[3]={10.0,15.0,20.0}; ? ? ? //specified lags ? int maxLags=20; ? ? ? ? ? ? ? ? ? ? ? ?//maximum number of lags ? double ACF[]; ArrayResize(ACF,21); ? ? //epmty ACF array ? double acf[]; ArrayResize(acf,20); ? ? //alternate ACF array ? autocorr(ACF,rets,maxLags); ? ? ? ? ? ?//calculated ACF array ? for(int i=0;i<20;i++) acf[i]=ACF[i+1]; //remove the first element - one, fill ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//alternate array ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? double alpha[3]={0.05,0.05,0.05}; ? ? ?//array of levels of significance of the test /*Calculation of array of Q statistics for selected lags according to the formula: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?L ? ? ? ? ? ? ? ?|----| ? ? ? ? ? ? ? ? \ ? ? ? Q = T(T+2) || (rho(k)^2/(T-k)), ? ? ? ? ? ? ? ? / ? ? ? ? ? ? ? ? ?|----| ? ? ? ? ? ? ? ? ?k=1 ?where: T is range, L is the number of lags, rho(k) is the value of ACF at the k-th lag. */ ? double idx[]; ArrayResize(idx,maxLags); ? ? //auxiliary array of indexes ? int len=ArraySize(rets); ? ? ? ? ? ? ? ? ? ?//length of the array of observations ? int arrLags[];ArrayResize(arrLags,maxLags); //auxiliary array of lags ? double stat[]; ArrayResize(stat,maxLags); ? //array of Q statistics ? double sum[]; ArrayResize(sum,maxLags); ? ? //auxiliary array po sums ? double iACF[];ArrayResize(iACF,maxLags); ? ?//auxiliary ACF array ? for(int i=0;i<maxLags;i++) ? ? { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //fill: ? ? ?arrLags[i]=i+1; ? ? ? ? ? ? ? ? ? ? ? ? ?//auxiliary array of lags ? ? ? ? ?idx[i]=len-arrLags[i]; ? ? ? ? ? ? ? ? ? //auxiliary array of indexes ? ? ? ? ? ?iACF[i]=pow(acf[i],2)/idx[i]; ? ? ? ? ? ?//auxiliary ACF array ? ? ? ? } ? cumsum(sum,iACF); ? ? ? ? ? ? ? ? ? ? ? ? ? //sum the auxiliary ACF array ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //by progressive total ? ? ? ? ? ? ? ? ? ? ? ? ? for(int i=0;i<maxLags;i++) ? ? ?stat[i]=sum[i]*len*(len+2); ? ? ? ? ? ? ?//fill the array Q statistics ? double stat1[]; ? ? ? ? ? ? ? ? ? ? ? ? ? ? //alternate of the array of Q statistics ? ArrayResize(stat1,ArraySize(lags)); ? for(int i=0;i<ArraySize(lags);i++) ? ? ?stat1[i]=stat[lags[i]-1]; ? ? ? ? ? ? ? ?//fill the alternate array of specified lags ? double pValue[ArraySize(lags)]; ? ? ? ? ? ? //array of 'p' values ? for(int i=0;i<ArraySize(lags);i++) ? ? { ? ? ?pValue[i]=1-gammp(lags[i]/2,stat1[i]/2); //calculation of 'p' values ? ? ?H[i]=alpha[i]>=pValue[i]; ? ? ? ? ? ? ? ?//estimation of zero hypothesis ? ? } ?}
于是,赫茲量化的函數(shù)執(zhí)行 Ljung-Box-Pierce Q 檢驗(yàn)并返回指定滯后值的邏輯值數(shù)組。赫茲量化需要指出,Ljung-Box 檢驗(yàn)就是所謂的便利的檢定(綜合檢驗(yàn))。它意味著將不超過(guò)指定滯后值的一些滯后值組用于檢查自相關(guān)的存在。通常而言,自相關(guān)的檢查可包含第 10 個(gè)、第 15 個(gè)和第 20 個(gè)便利的滯后值?;?H 數(shù)組元素的最后的值(即從第 1 個(gè)到第 20 個(gè)滯后值)得出了整個(gè)序列中是否存在自相關(guān)的結(jié)論。
如果數(shù)組中的元素等于 false,則表示接受之前滯后值和選定滯后值無(wú)自相關(guān)這一零假設(shè)。換言之,當(dāng)值為 false 時(shí),則表示不存在自相關(guān)。否則,檢驗(yàn)會(huì)證明存在自相關(guān)。因此,當(dāng)值為 true 時(shí),零假設(shè)以外的假設(shè)將會(huì)被接受。
有時(shí)候,也會(huì)發(fā)生在回報(bào)序列中未找到自相關(guān)的情況。在這種情況下,為了提高精確度,可檢驗(yàn)回報(bào)的平方。檢驗(yàn)初始回報(bào)序列時(shí),也會(huì)以同樣的方式做出接受或拒絕零假設(shè)的最終決定。為什么要使用回報(bào)平方?- 通過(guò)這種方式,赫茲量化人為增加了分析序列可能具有的非隨機(jī)自相關(guān)要素,然后在受信限值的初始值的范圍內(nèi)對(duì)其進(jìn)一步確定。理論上來(lái)說(shuō),您可以使用回報(bào)的平方或其他次冪。但這是不必要的統(tǒng)計(jì)負(fù)載,導(dǎo)致檢驗(yàn)沒(méi)有意義。
在 Q 檢驗(yàn)函數(shù)主體的末尾,當(dāng)計(jì)算了 "p" 值后,函數(shù) gammp(x1/2,x2/2) 就會(huì)出現(xiàn)。它可以針對(duì)相應(yīng)元素進(jìn)行不完整的 gamma 函數(shù)計(jì)算。實(shí)際上,我們需要一個(gè) χ2 分布(卡方分布)的累積函數(shù)。但它是 Gamma 分布的一個(gè)特例。
一般而言,要證明使用 GARCH 模型是否合適,只需獲得 Q 檢驗(yàn)任何滯后值的一個(gè)正值即可。此外,計(jì)量經(jīng)濟(jì)學(xué)家也進(jìn)行了其他檢驗(yàn) - Engle 的 ARCH 檢驗(yàn),用于檢查是否存在傳統(tǒng)的異方差性。然而對(duì)于時(shí)間序列而言,我認(rèn)為 Q 檢驗(yàn)已經(jīng)足夠。它是最普遍的檢驗(yàn)。
現(xiàn)在我們已有了進(jìn)行檢驗(yàn)所需的所有函數(shù),需要考慮在屏幕上顯示所獲得的結(jié)果了。為此,我編寫了另一個(gè)函數(shù) lbqtestInfo,它將以消息窗口的形式顯示計(jì)量經(jīng)濟(jì)學(xué)結(jié)果,并在分析的交易品種的圖表上顯示自相關(guān)圖。
讓我們通過(guò)一個(gè)示例來(lái)看下結(jié)果。我選擇 USDJPY 作為分析的首個(gè)交易品種。首先,我打開該交易品種的線形圖(取收盤價(jià))并加載自定義指標(biāo) ReturnsIndicator 以說(shuō)明回報(bào)序列。圖表應(yīng)盡可能地簡(jiǎn)化,以更好地顯示指標(biāo)的波動(dòng)集群性。接下來(lái)我會(huì)執(zhí)行腳本 GarchTest?;蛟S您的屏幕分辨率與我的不同,腳本會(huì)詢問(wèn)您圖解所需的像素大小。我這邊的標(biāo)準(zhǔn)是 700*250。