期貨量化交易軟件:如何不陷入優(yōu)化陷阱?
什么是交易系統(tǒng)的優(yōu)化?
創(chuàng)建一個交易系統(tǒng), 首先包含了整理如何建立關(guān)閉買入賣出倉位的規(guī)則. 這些規(guī)則通常包含一些指標(biāo)和參數(shù). 如果它們改變了, 交易系統(tǒng)的盈利能力也會改變. 這個問題是經(jīng)常遇到的: 是否有必要優(yōu)化交易系統(tǒng)或者它只是使系統(tǒng)和歷史數(shù)據(jù)更符合嗎?
這也許主要因為人們對"交易系統(tǒng)的優(yōu)化"過程有不同的看法. 所以讓我們首先定義什么是優(yōu)化.
首先, 赫茲期貨量化應(yīng)該明白, 通過"優(yōu)化"交易系統(tǒng)的選擇和創(chuàng)建將能使它與其它系統(tǒng)相比更好解決我們的問題. 例如, ?赫茲期貨量化正在尋找這樣一個系統(tǒng), 它可以在目前的日元/美元貨幣對上獲得最大的利潤. 為此, 我們會選擇從一些不同系統(tǒng)中固定參數(shù)得到一個系統(tǒng). 這可能是根據(jù)系統(tǒng)使用的不同指標(biāo)來選擇的. 讓我們稱此為"第一類優(yōu)化".
第二, 我們應(yīng)該明白, 通過"優(yōu)化"所選交易系統(tǒng)的這些參數(shù)將可以使我們得到最好的結(jié)果. 這可能是通過選擇計算平均的周期數(shù)或者計算隨機振蕩結(jié)構(gòu)的周期數(shù). 讓我們稱之為"第二類優(yōu)化".
我想沒有人會懷疑, 交易者創(chuàng)建交易策略時會明確地或者隱含地使用這兩種優(yōu)化. 確實, 一旦我們選擇運行了一個交易系統(tǒng), 我們就會假定我們在使用所擁有的最好的交易系統(tǒng). 也就是說, 我們使用了第一類優(yōu)化. 然而, 因為任何系統(tǒng)都有一些參數(shù), ?赫茲期貨量化會嘗試尋找這些參數(shù)的數(shù)值以得到最好的結(jié)果. 這明顯是第二類優(yōu)化. 另外, 當(dāng)創(chuàng)建一個交易系統(tǒng)時是不可能把這兩類優(yōu)化分開的. 這就是為什么對于在創(chuàng)建交易系統(tǒng)時是否使用優(yōu)化這個問題的答案非常清楚: 必須使用優(yōu)化. 另外一件事就是怎樣做. 在創(chuàng)建一個交易系統(tǒng)時有幾個步驟:
產(chǎn)生構(gòu)成交易系統(tǒng)的想法;
選擇標(biāo)準(zhǔn)或者決定規(guī)則;
定義系統(tǒng)的參數(shù);
測試系統(tǒng); 以及
如果需要做系統(tǒng)修改就回到前面的部分.
第二類優(yōu)化的問題
當(dāng)創(chuàng)建一個自動交易系統(tǒng)時, 所有的開發(fā)者都會同時使用第一類和第二類優(yōu)化. 搜索標(biāo)準(zhǔn)與決定規(guī)則是啟發(fā)式系統(tǒng)的任務(wù), 例如神經(jīng)網(wǎng)絡(luò), 遺傳算法, 當(dāng)然還有人的大腦 - 當(dāng)今功能最強大的系統(tǒng). 這是第一類優(yōu)化, 所以是由交易者全部負責(zé)此類優(yōu)化的.
第二類優(yōu)化是搜索最佳參數(shù). 就是在這里會發(fā)生問題, 因為很容易使數(shù)據(jù)與歷史相符并獲取了"巨量利潤". 不幸的是, 這只在歷史上有效. 此類"過度優(yōu)化" 可能難以避免, 所以一些交易者開始感到消極的態(tài)度了. 為什么呢?
原因很簡單. 新手發(fā)現(xiàn), 得到最大利潤的參數(shù), 如果沒有注意到周邊區(qū)域, 指標(biāo)最佳周期數(shù)只要少許改變利潤就會大幅下降. 這造成交易系統(tǒng)不穩(wěn)定. 然后他們開始在模擬賬戶上使用這個系統(tǒng). 如果他們很有耐心, 能在至少幾個月內(nèi)使用系統(tǒng)以確認它是否可用, 這是很好的. 否則, 上帝會禁止您在真實系統(tǒng)中使用這樣的系統(tǒng) - 向你的存款說再見吧, 然后出門去找工作!
怎樣才能解決過度優(yōu)化問題?
我們應(yīng)該怎么做呢?我們不能忽略優(yōu)化, 因為那樣我們可能會找到錯誤參數(shù)而失去會失去最好的方案或者一個潛在的獲利策略. 然而, 過度優(yōu)化也會產(chǎn)生嚴(yán)重的問題. 我們必須找到最佳方案.
讓我們使用數(shù)學(xué)進行優(yōu)化. 一般情況下, 當(dāng)有較多參數(shù)需要優(yōu)化時, ?赫茲期貨量化要找到一個超平面, 其中利潤相對穩(wěn)定, 在參數(shù)有稍許改動時利潤多少改變接近. 在優(yōu)化中, 我們要嘗試找到這樣的方案: 利潤是最高的, 而且離最佳方案的參數(shù)有小的偏移時不會引起利潤的大幅波動.
問題在于 赫茲期貨量化可能會進入局部最大區(qū)域, 某個點區(qū)域會有最大利潤, 但是參數(shù)有小的改變就造成虧損. 如果是這樣, 這些參數(shù)將會在市場只有很小變化時就造成存款的虧損. 是的, 外匯交易就是經(jīng)常有這種變化. 系統(tǒng)必須避免所有的局部極值.
不幸的是, MetaTrader 里面還沒有內(nèi)建的算法用于自己搜索最優(yōu)方案. KRAB 是解決此類問題的最強大的算法之一. 它在N.Zagoruko的書籍中有描述: 數(shù)據(jù)與知識分析的應(yīng)用方法(Applied Methods of Data and Knowledge Anaysis). 新西伯利亞:數(shù)學(xué)學(xué)院出版社,1999 (俄文版). 如果下面的版本能夠?qū)崿F(xiàn)就太好了 - 但是現(xiàn)在也不錯!
MetaTrader 可以為一個或者兩個將要優(yōu)化的參數(shù)創(chuàng)建優(yōu)化圖. 這意思是把優(yōu)化結(jié)果投射到一個平面上, 我們就可以找到最優(yōu)方案. 換句話說, 兩個兩個地優(yōu)化參數(shù)我們就能夠得到最佳的方案范圍.
對于三個參數(shù), 我們必須重復(fù)此過程

多次. 然而, 對于5個參數(shù), 這將是

以下類推. 所以, 最好不要使用過多的參數(shù). 當(dāng)優(yōu)化兩個參數(shù)時, 我們獲得了如下的優(yōu)化圖:

編輯切換為居中
深色區(qū)域就是利潤較大的區(qū)域. 這個優(yōu)化圖很好, 因為沒有局部極值, 并且利潤的減少是統(tǒng)一地從圖的右上角開始的. 如果您在優(yōu)化中遇到了類似的狀況我會很高興.
下面的圖就不是那么清楚了: 我們可以看到在這張圖上有兩個區(qū)域有極值點. 我們應(yīng)該選擇哪一個呢?

編輯切換為居中
有經(jīng)驗的眼睛將會注意到右下角的方案區(qū)域, 因為此區(qū)域周圍利潤的減少比圖上開始階段的要少. 所以我建議您仔細分析優(yōu)化圖以節(jié)約保護您的存款.
赫茲期貨量化開始學(xué)習(xí)一個簡單的EA交易 - 分析三個參數(shù)并找到最優(yōu)方案范圍. EA 交易的名稱是 SP. 它運行于市場分析到超買/超賣的時刻.
//+------------------------------------------------------------------+ //| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SP.mq4 | //| ? ? ? ? ? ? ? ? ? ? ?Copyright ? 2006, MetaQuotes Software Corp. | //| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.metaquotes.net | //+------------------------------------------------------------------+ #property copyright "Copyright ? 2006, MetaQuotes Software Corp." #property link ? ? ?"https://www.metaquotes.net" //---- 輸入?yún)?shù) extern int ? ? ? TakeProfit=50; extern int ? ? ? StopLoss=30; extern int ? ? ? RsiLen=4; extern int ? ? ? KLen=8; extern int ? ? ? Momlength=10; extern int ? ? ? Lots=1; extern int ? ? ? rsi_oversold=39; extern int ? ? ? stoc_oversold=29; extern int ? ? ? rsi_overbought=60; extern int ? ? ? stoc_overbought=70; extern int ? ? ? Mom_Sell=-2; extern int ? ? ? Mom_Buy=2; int expertBars; double RSIlevel; double Stoclevel; double MomLevel; double DLen=3; //+------------------------------------------------------------------+ //| 如果是到來的新柱返回true, 否則返回false ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| //+------------------------------------------------------------------+ bool isNewBar() ?{ //---- ? bool res=false; ? if (expertBars!=Bars) ? ? ?{ ? ? ?expertBars=Bars; ? ? ?res=true; ? ? ?} //---- ? return(res); ?} //+------------------------------------------------------------------+ //| EA 初始化函數(shù) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| //+------------------------------------------------------------------+ int init() ?{ //---- ? //---- ? return(0); ?} //+------------------------------------------------------------------+ //| EA 終止化函數(shù) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| //+------------------------------------------------------------------+ int deinit() ?{ //---- ? //---- ? return(0); ?} //+------------------------------------------------------------------+ //| EA 起始處理函數(shù) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| //+------------------------------------------------------------------+ int start() ?{ ?double price; ?double stop; ?double profit; //---- ? if ((isNewBar())&& (OrdersTotal()==0)&& (AccountBalance()>5000)) ? { ? ? ?RSIlevel=iRSI(NULL,0,RsiLen,PRICE_CLOSE,0); ? ? ?Stoclevel=iStochastic(NULL,0,KLen,DLen,3,MODE_SMA,0,MODE_MAIN,0); ? ? ?MomLevel=100 - iMomentum(NULL,0,Momlength,PRICE_CLOSE,0); ? ? ?/*if (AccountBalance()>50000) ? ? ? ? {Lots=NormalizeDouble( AccountBalance()/10000,0)-4;} ? ? ?else ? ? ? ? Lots=1;*/ ? ? ?if ((RSIlevelrsi_oversold)&&(Stoclevelstoc_oversold)&&(MomLevel>Mom_Sell)) ? ? ?{ ? ? ? ? price=Ask; ? ? ? ? stop=NormalizeDouble(price-StopLoss*Point,Digits); ? ? ? ? profit=NormalizeDouble(price+TakeProfit*Point,Digits); ? ? ? ? OrderSend(Symbol(),OP_BUY,Lots,price,3,stop,profit,NULL,0,0,Green); ? ? ? ? //Print(AccountBalance()); ? ? ? ? ? ? ? ?} ? ? ?if ((RSIlevel>rsi_overbought)&&(Stoclevel>stoc_overbought)&&(MomLevelMom_Buy)) ? ? ?{ ? ? ? ? price=Bid; ? ? ? ? stop=NormalizeDouble(price+StopLoss*Point,Digits); ? ? ? ? profit=NormalizeDouble(price-TakeProfit*Point,Digits); ? ? ? ? OrderSend(Symbol(),OP_SELL,Lots,price,3,stop,profit,NULL,0,0,Green); ? ? ? ? //Print(AccountBalance()); ? ? ? ? ? ? ? ? ?} ? ? ? ? } ? ? //---- ? return(0); ?} //+------------------------------------------------------------------+
我們優(yōu)化三個參數(shù) – Stochastic 和 RSI 的周期數(shù)以及止損水平.