股票量化交易軟件:價格速度測量方法

簡介

市場研究和分析有多種不同的方法,主要是技術分析和基礎分析。在技術分析中,交易者收集、處理和分析與市場有關的數(shù)字數(shù)據(jù)和參數(shù),包括價格、數(shù)量等。在基本面分析中,交易者分析直接或間接影響市場的事件和新聞。在分析基礎數(shù)據(jù)時,主要問題是解釋一個事件對市場的影響。這種解釋可能會受到交易員的意見和期望的影響。相反,技術數(shù)據(jù)通常不會產(chǎn)生各種解釋,然而,在評估技術分析結果時也存在人為因素。
發(fā)現(xiàn)問題
說到市場的技術分析,我們赫茲股票量化指的是使用來自不同科學領域的任何評估系統(tǒng),無論是數(shù)學還是物理。數(shù)學在技術分析中的必要性是相當明確的,而將各種物理現(xiàn)象應用于市場則更為有趣。因此,在本文中,赫茲股票量化將考慮這樣一個眾所周知的物理現(xiàn)象,即速度,它是一個單位時間內(nèi)運動的度量。當我們看外匯和其他圖表時,我們不僅可以清楚地看到當前的價格方向,而且可以看到它的速度,特別是在高波動期。任何人都可以直觀地分析圖表,并確定當前的價格變化是快還是慢。然而,由于人們的認知差異,這種視覺估計仍然具有高度的主觀性。
現(xiàn)實生活中的一個簡單例子是一個視覺技巧,在這個技巧中,一輛小型車輛似乎以較慢的速度移動,而一輛大型卡車似乎以較高的速度移動。這個問題是通過速度表來解決的,它以數(shù)字顯示所有的東西,這對任何人來說都是完全相同的。
價格速度測量方法
在考慮各種測量價格速度的方法之前,讓赫茲股票量化回想一下速度實際上是什么。
根據(jù)維基百科:
物體的速度是物體相對于一個參照系位置變化的速率,是時間的函數(shù)。速度是一個物理向量量;定義它需要大小和方向。
赫茲股票量化如何將這個定義應用于外匯?最簡單的方法是用一個價格替換一個物體,并設定一個時間,在這個時間內(nèi)形成一根棒子或一根蠟燭,作為參照系。從價格圖的角度來看,如下所示:

編輯
圖 1. 在 H1 時間段將價格顯示為日式燭形
在這種情況下,簡單的速度測量如下所示:
平均速度 = (收盤價格 — 開盤價格) / 小時數(shù)
關于價格隨時間變化的確切觀察和結論如下:

赫茲股票量化定義了價格每小時通過的平均點數(shù)。然而,測量只在一根蠟燭的框架內(nèi)進行,我們無法在此框架內(nèi)獲得總體趨勢圖。
但是,如果我們將速度從每小時的點轉換為每分鐘的點、5分鐘的點等,赫茲股票量化就可以在這個H1小時內(nèi)獲得更有價值的價格變動數(shù)據(jù)。
因此,下面兩個結論是顯而易見的:在較低的時間段上確定速度對于較高的時間段更為方便。當通過測量價格變動來測量當前時間段的平均速度時,我們應該使用幾個燭形。
最后,用這種簡單的方法測量速度的要點是,它不提供燭形內(nèi)部價格動態(tài)的深入數(shù)據(jù),只顯示最終的平均結果。例如,如果知道 H1 燭形的平均速度,赫茲股票量化就無法確定最初的價格是高的,到一個小時結束時價格會大幅下降。
為了清楚起見,讓我提供一個完美地說明上述結論的例子。圖2顯示了H1燭形,其每分鐘平均速度是使用Average Speed(平均速度)指標計算得出的。這里等于每分鐘2.53點。

編輯切換為居中
圖 2. 在 EURUSD H1 上計算平均速度
現(xiàn)在讓我們來看看M15上的同樣的燭形。

編輯切換為居中
圖 3. 在 EURUSD M15 上計算平均速度
圖3顯示,在所選小時的前15分鐘(Average speed是 6.93)內(nèi),運動非常強烈,隨后顯著減速。當然,如果赫茲股票量化把平均速度的四個值加起來,每分鐘得到相同的2.53點。因此,將蠟燭分解成組件可以讓我們發(fā)現(xiàn)許多有關其動力學的數(shù)據(jù)。
將 H1 燭形分成 M1 間隔會產(chǎn)生更多的數(shù)據(jù)。

編輯切換為居中
圖 4. 在 EURUSD M1 上計算平均速度
還有另一種測量方法,用于計算M1時間段內(nèi)點的移動速度,
它涉及即時(當前)價格速度。一方面,它的值總是盡可能的相關。另一方面,與分時價格變化配合使用的示例指標如下所示:

編輯
圖 5. 即時價格速度指標
顯然,評估這樣一個混亂(盡管相關)的數(shù)據(jù),以便隨后在外匯交易中使用,是一個相當具有挑戰(zhàn)性的任務。
如赫茲股票量化所知,絕大多數(shù)指標都是價格或其分析儀的衍生產(chǎn)品,這些是一些與價格速度相關的著名指標:
動量指標衡量一段時間內(nèi)的價格變化量。極高或較低的動量值表示當前趨勢的延續(xù)。這意味著與指標的較大偏差表示當前特定方向的高價格速度。
ADX 趨勢指標. 平均定向運動指數(shù)顯示了當前趨勢的強度。實際上,它顯示當前的平均速度。
基于測量方法制定交易策略
因此,測試各種價格-速度測量的目標分為三大類:
以單位時間內(nèi)通過點的比率直接測量平均速度。
以通過的點數(shù)與分時數(shù)之比來測量速度。
使用跟隨趨勢的和其他指標進行間接速度測量。
交易策略 1要使用平均速度(Average Speed)指標根據(jù)測量速度(單位時間內(nèi)通過的點數(shù))來測試第一種方法,應將顯示趨勢方向的過濾器添加到測試策略中,因為指示器顯示單位時間內(nèi)的點數(shù),而不管趨勢方向。
我決定使用Coordinated ADX and MACD(協(xié)調(diào)的ADX和MACD,CAM)指標作為這樣的過濾器。交易策略看起來是這樣的:
參數(shù)
描述
使用的指標
平均速度
使用的指標
Coordinated ADX and MACD (CAM)
時間框架
任意
買入條件
燭形為綠色,而平均速度值高于閾值(參數(shù)中預先設置)。
賣出條件
燭形顏色為紅色,而平均速度值高于閾值(參數(shù)中預先設置)。
退場條件
獲利/止損
圖 6 顯示了買入和賣出的建立

編輯
圖 6. 交易策略的入場條件
策略是按照下面的方法實現(xiàn)的:
//+------------------------------------------------------------------+ //| EA 的輸入?yún)?shù) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| //+------------------------------------------------------------------+ input string ? ? ? ? ? ? ? InpEaComment ? ? ? ? = ?"Strategy #1"; // EA Comment input int ? ? ? ? ? ? ? ? ?InpMagicNum ? ? ? ? ?= ?1111; ? ? ? ? ?// Magic number input double ? ? ? ? ? ? ? InpLot ? ? ? ? ? ? ? = ?0.1; ? ? ? ? ? // Lots input uint ? ? ? ? ? ? ? ? InpStopLoss ? ? ? ? ?= ?400; ? ? ? ? ? // StopLoss in points input uint ? ? ? ? ? ? ? ? InpTakeProfit ? ? ? ?= ?500; ? ? ? ? ? // TakeProfit in points input uint ? ? ? ? ? ? ? ? InpSlippage ? ? ? ? ?= ?0; ? ? ? ? ? ? // Slippage in points input ENUM_TIMEFRAMES ? ? ?InpInd_Timeframe ? ? = ?PERIOD_H1; ? ? // Timeframe for the calculation //--- 平均速度指標的參數(shù) input int ? ? ? ? ? ? ? ? ?InpBars ? ? ? ? ? ? ?= ?1; ? ? ? ? ? ? // Days input ENUM_APPLIED_PRICE ? InpPrice ? ? ? ? ? ? = ?PRICE_CLOSE; ? // Applied price input double ? ? ? ? ? ? ? InpTrendLev ? ? ? ? ?= ?2; ? ? ? ? ? ? // Trend Level //--- CAM 指標參數(shù) input uint ? ? ? ? ? ? ? ? InpPeriodADX ? ? ? ? = ?10; ? ? ? ? ? ?// ADX period input uint ? ? ? ? ? ? ? ? InpPeriodFast ? ? ? ?= ?12; ? ? ? ? ? ?// MACD Fast EMA period input uint ? ? ? ? ? ? ? ? InpPeriodSlow ? ? ? ?= ?26; ? ? ? ? ? ?// MACD Slow EMA period //--- CEngine ? ? ? ?engine; CTrade ? ? ? ? trade; //--- 聲明指標變量和句柄 double ? ? ? ? lot; ulong ? ? ? ? ?magic_number; uint ? ? ? ? ? stoploss; uint ? ? ? ? ? takeprofit; uint ? ? ? ? ? slippage; int ? ? ? ? ? ?InpInd_Handle1,InpInd_Handle2; double ? ? ? ? avr_speed[],cam_up[],cam_dn[]; //+------------------------------------------------------------------+ //| EA 交易初始化函數(shù) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | //+------------------------------------------------------------------+ int OnInit() ?{ //--- 初始化檢查 ? if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) ? ? { ? ? ?Print(InpEaComment,": 不允許進行交易!"); ? ? ?return(INIT_FAILED); ? ? } ? if(!TerminalInfoInteger(TERMINAL_CONNECTED)) ? ? { ? ? ?Print(InpEaComment,": 沒有連接!"); ? ? ?return(INIT_FAILED); ? ? } //--- 取得 Average Speed 指標句柄 ? InpInd_Handle1=iCustom(Symbol(),InpInd_Timeframe,"Speed Price\\average_speed", ? ? ? ? ? ? ? ? ? ? ? ? ?InpBars, ? ? ? ? ? ? ? ? ? ? ? ? ?InpPrice ? ? ? ? ? ? ? ? ? ? ? ? ?); ? if(InpInd_Handle1==INVALID_HANDLE) ? ? { ? ? ?Print(InpEaComment,": 獲取 average_speed 句柄失敗"); ? ? ?Print("Handle = ",InpInd_Handle1," ?error = ",GetLastError()); ? ? ?return(INIT_FAILED); ? ? } //--- 取得 CAM 指標句柄 ? InpInd_Handle2=iCustom(Symbol(),InpInd_Timeframe,"Speed Price\\CAM", ? ? ? ? ? ? ? ? ? ? ? ? ?InpPeriodADX, ? ? ? ? ? ? ? ? ? ? ? ? ?InpPeriodFast, ? ? ? ? ? ? ? ? ? ? ? ? ?InpPeriodSlow ? ? ? ? ? ? ? ? ? ? ? ? ?); ? if(InpInd_Handle2==INVALID_HANDLE) ? ? { ? ? ?Print(InpEaComment,": 獲取 average_speed 句柄失敗"); ? ? ?Print("Handle = ",InpInd_Handle2," ?error = ",GetLastError()); ? ? ?return(INIT_FAILED); ? ? } //--- ? ArrayInitialize(avr_speed,0.0); ? ArrayInitialize(cam_up,0.0); ? ArrayInitialize(cam_dn,0.0); ? ArraySetAsSeries(avr_speed,true); ? ArraySetAsSeries(cam_up,true); ? ArraySetAsSeries(cam_dn,true); //--- 設置交易參數(shù) ? lot=NormalizeLot(Symbol(),fmax(InpLot,MinimumLots(Symbol()))); ? magic_number=InpMagicNum; ? stoploss=InpStopLoss; ? takeprofit=InpTakeProfit; ? slippage=InpSlippage; //--- ? trade.SetDeviationInPoints(slippage); ? trade.SetExpertMagicNumber(magic_number); ? trade.SetTypeFillingBySymbol(Symbol()); ? trade.SetMarginMode(); ? trade.LogLevel(LOG_LEVEL_NO); //--- ? return(INIT_SUCCEEDED); ?} //+------------------------------------------------------------------+ //| 計時器函數(shù) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | //+------------------------------------------------------------------+ void OnTimer() ?{ ? if(!MQLInfoInteger(MQL_TESTER)) ? ? ?engine.OnTimer(); ?} //+------------------------------------------------------------------+ //| EA交易分時函數(shù) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | //+------------------------------------------------------------------+ void OnTick() ?{ //--- 如果在測試器中工作 ? if(MQLInfoInteger(MQL_TESTER)) ? ? ?engine.OnTimer(); ? if(!IsOpenedByMagic(InpMagicNum)) ? ? { ? ? ?//--- 取得計算數(shù)據(jù) ? ? ?if(!GetIndValue()) ? ? ? ? return; ? ? ?//--- ? ? ?if(BuySignal()) ? ? ? ?{ ? ? ? ? //--- 取得相對止損水平的正確止損和獲利價格 ? ? ? ? double sl=CorrectStopLoss(Symbol(),ORDER_TYPE_BUY,0,stoploss); ? ? ? ? double tp=CorrectTakeProfit(Symbol(),ORDER_TYPE_BUY,0,takeprofit); ? ? ? ? //--- 開啟買入倉位 ? ? ? ? trade.Buy(lot,Symbol(),0,sl,tp); ? ? ? ?} ? ? ?else if(SellSignal()) ? ? ? ?{ ? ? ? ? //--- 取得相對止損水平的正確止損和獲利價格 ? ? ? ? double sl=CorrectStopLoss(Symbol(),ORDER_TYPE_SELL,0,stoploss); ? ? ? ? double tp=CorrectTakeProfit(Symbol(),ORDER_TYPE_SELL,0,takeprofit); ? ? ? ? //--- 開啟賣出倉位 ? ? ? ? trade.Sell(lot,Symbol(),0,sl,tp); ? ? ? ?} ? ? } ?} //+------------------------------------------------------------------+ //| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| //+------------------------------------------------------------------+ bool BuySignal() ?{ ? return(avr_speed[0]>=InpTrendLev && cam_up[0]!=EMPTY_VALUE)?true:false; ?} //+------------------------------------------------------------------+ bool SellSignal() ?{ ? return(avr_speed[0]>=InpTrendLev && cam_dn[0]!=EMPTY_VALUE)?true:false; ?} //+------------------------------------------------------------------+ //| 取得當前指標值 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| //+------------------------------------------------------------------+ bool GetIndValue() ?{ ? return(CopyBuffer(InpInd_Handle2,0,0,1,cam_up)<1 || ? ? ? ? ?CopyBuffer(InpInd_Handle2,1,0,1,cam_dn)<1 || ? ? ? ? ?CopyBuffer(InpInd_Handle1,0,0,1,avr_speed)<1 ? ? ? ? ?)?false:true; ?} //+------------------------------------------------------------------+ //| 使用幻數(shù)檢查開啟的倉位 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | //+------------------------------------------------------------------+ bool IsOpenedByMagic(int MagicNumber) ?{ ? int pos=0; ? uint total=PositionsTotal(); //--- ? for(uint i=0; i<total; i++) ? ? { ? ? ?if(SelectByIndex(i)) ? ? ? ? if(PositionGetInteger(POSITION_MAGIC)==MagicNumber) ? ? ? ? ? ?pos++; ? ? } ? return((pos>0)?true:false); ?} //+------------------------------------------------------------------+ //| 根據(jù)索引選擇倉位 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| //+------------------------------------------------------------------+ bool SelectByIndex(const int index) ?{ ? ENUM_ACCOUNT_MARGIN_MODE margin_mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE); //--- ? if(margin_mode==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) ? ? { ? ? ?ulong ticket=PositionGetTicket(index); ? ? ?if(ticket==0) ? ? ? ? return(false); ? ? } ? else ? ? { ? ? ?string name=PositionGetSymbol(index); ? ? ?if(name=="") ? ? ? ? return(false); ? ? } //--- ? return(true); ?} //+------------------------------------------------------------------+