量化軟件:赫茲量化系統(tǒng)多周期指標緩沖區(qū)
今天,我將繼續(xù)工作,編排創(chuàng)建指標緩沖區(qū)和訪問其數(shù)據(jù)的方法。 我打算根據(jù)緩沖區(qū)對象中設置的 period 屬性(數(shù)據(jù)時間幀)實現(xiàn)當前品種/周期圖表對應的緩沖區(qū)數(shù)值的顯示。 如果緩沖區(qū)設置的時間幀與當前圖表不對應,則所有緩沖區(qū)數(shù)據(jù)均會正確地顯示在圖表上。 例如,如果當前圖表的數(shù)據(jù)周期為 M15,而緩沖區(qū)對象圖表設置為 H1,則緩沖區(qū)數(shù)據(jù)會顯示在當前 M15 圖表的每根柱線上,其時間落在 H1 圖表柱線內(nèi)的時間。 在本示例中,當前圖表的四根柱線填充的是相同數(shù)值,所請求的數(shù)值來自圖表周期為 H1 的柱線。赫茲量化國聯(lián)期貨極速版
這些改進令我們能夠舒服地創(chuàng)建多周期指標,因為我們只需要為緩沖區(qū)對象設置時間幀即可。 其余的由函數(shù)庫負責。 此外,我打算逐步完善指標緩沖區(qū)的創(chuàng)建。 它會被精簡為單一的代碼字符串,并在其中創(chuàng)建帶有請求屬性的所需指標緩沖區(qū)對象。 任何特定圖形類型的指標緩沖區(qū)都將按索引進行訪問。
“緩沖區(qū)索引”的概念如下:如果第一行先創(chuàng)建箭頭緩沖區(qū),然后再次創(chuàng)建箭頭緩沖區(qū),則緩沖區(qū)對象索引按創(chuàng)建對象的順序排列。 每種繪圖樣式都有其自己的索引序列。 在所提供的示例里,索引如下:創(chuàng)建的第一個箭頭緩沖區(qū)的索引為 0,第二個箭頭緩沖區(qū)的索引為 1,而緊接在第一個箭頭緩沖區(qū)之后創(chuàng)建的線條緩沖區(qū)的索引為 0,因為它是第一個具有“線條”繪制樣式的緩沖區(qū),盡管它依序是第二個創(chuàng)建的。
改進在多周期模式下操控指標緩沖區(qū)的類
從版本 2430 開始,赫茲量化國聯(lián)期貨極速版 可在市場觀察窗口中列出的品種名稱得以極大提升。 現(xiàn)在是 5000,取代了構建 2430 之前的 1000。 為了操控品種列表,我們在 Defines.mqh 文件中引入新的宏替換:
//+------------------------------------------------------------------+ //| Macro substitutions ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| //+------------------------------------------------------------------+ //--- Describe the function with the error line number .... //--- Symbol parameters #define CLR_DEFAULT ? ? ? ? ? ? ? ? ? ?(0xFF000000) ? ? ? ? ? ? ? // Default symbol background color in the navigator #ifdef __MQL5__ ? #define SYMBOLS_COMMON_TOTAL ? ? ? ?(TerminalInfoInteger(TERMINAL_BUILD)<2430 ? 1000 : 5000) ? // Total number of MQL5 working symbols #else ? #define SYMBOLS_COMMON_TOTAL ? ? ? ?(1000) ? ? ? ? ? ? ? ? ? ? // Total number of MQL4 working symbols #endif //--- Pending request type IDs #define PENDING_REQUEST_ID_TYPE_ERR ? ?(1) ? ? ? ? ? ? ? ? ? ? ? ?// Type of a pending request created based on the server return code #define PENDING_REQUEST_ID_TYPE_REQ ? ?(2) ? ? ? ? ? ? ? ? ? ? ? ?// Type of a pending request created by request //--- Timeseries parameters #define SERIES_DEFAULT_BARS_COUNT ? ? ?(1000) ? ? ? ? ? ? ? ? ? ? // Required default amount of timeseries data #define PAUSE_FOR_SYNC_ATTEMPTS ? ? ? ?(16) ? ? ? ? ? ? ? ? ? ? ? // Amount of pause milliseconds between synchronization attempts #define ATTEMPTS_FOR_SYNC ? ? ? ? ? ? ?(5) ? ? ? ? ? ? ? ? ? ? ? ?// Number of attempts to receive synchronization with the server //+------------------------------------------------------------------+ //| Enumerations ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | //+------------------------------------------------------------------+
在 \MQL5\Include\DoEasy\Collections\SymbolsCollection.mqh 里,為已用品種列表進行設置的方法中,將預留的品種數(shù)組大小從 1000 替換為新的宏替換數(shù)值:
//+------------------------------------------------------------------+ //| Set the list of used symbols ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | //+------------------------------------------------------------------+ bool CSymbolsCollection::SetUsedSymbols(const string &symbol_used_array[]) ?{ ? ::ArrayResize(this.m_array_symbols,0,SYMBOLS_COMMON_TOTAL); ? ::ArrayCopy(this.m_array_symbols,symbol_used_array);
在創(chuàng)建品種列表的方法里,于索引循環(huán)當中,將參考數(shù)值 1000 替換為新的宏替換:
//+------------------------------------------------------------------+ //| Creating the symbol list (Market Watch or the complete list) ? ? | //+------------------------------------------------------------------+ bool CSymbolsCollection::CreateSymbolsList(const bool flag) ?{ ? bool res=true; ? int total=::SymbolsTotal(flag); ? for(int i=0;i<total && i<SYMBOLS_COMMON_TOTAL;i++) ? ? {
以相同的方式,將所有用到的品種和時間幀寫入 \MQL5\Include\DoEasy\Engine.mqh 里的方法當中,將 1000 替換為宏替換:
//+------------------------------------------------------------------+ //| Write all used symbols and timeframes ? ? ? ? ? ? ? ? ? ? ? ? ? ?| //| to the ArrayUsedSymbols and ArrayUsedTimeframes arrays ? ? ? ? ? | //+------------------------------------------------------------------+ void CEngine::WriteSymbolsPeriodsToArrays(void) ?{ //--- Get the list of all created timeseries (created by the number of used symbols) ? CArrayObj *list_timeseries=this.GetListTimeSeries(); ? if(list_timeseries==NULL) ? ? ?return; //--- Get the total number of created timeseries ? int total_timeseries=list_timeseries.Total(); ? if(total_timeseries==0) ? ? ?return; //--- Set the size of the array of used symbols equal to the number of created timeseries, while //--- the size of the array of used timeframes is set equal to the maximum possible number of timeframes in the terminal ? if(::ArrayResize(ArrayUsedSymbols,total_timeseries,SYMBOLS_COMMON_TOTAL)!=total_timeseries || ::ArrayResize(ArrayUsedTimeframes,21,21)!=21) ? ? ?return; //--- Set both arrays to zero ? ::ZeroMemory(ArrayUsedSymbols); ? ::ZeroMemory(ArrayUsedTimeframes); //--- Reset the number of added symbols and timeframes to zero and, //--- in a loop by the total number of timeseries, ? int num_symbols=0,num_periods=0; ? for(int i=0;i<total_timeseries;i++) ? ? { ? ? ?//--- get the next object of all timeseries of a single symbol ? ? ?CTimeSeriesDE *timeseries=list_timeseries.At(i); ? ? ?if(timeseries==NULL || this.IsExistSymbol(timeseries.Symbol())) ? ? ? ? continue; ? ? ?//--- increase the number of used symbols and (num_symbols variable), and ? ? ?//--- write the timeseries symbol name to the array of used symbols by the num_symbols-1 index ? ? ?num_symbols++; ? ? ?ArrayUsedSymbols[num_symbols-1]=timeseries.Symbol(); ? ? ?//--- Get the list of all its timeseries from the object of all symbol timeseries ? ? ?CArrayObj *list_series=timeseries.GetListSeries(); ? ? ?if(list_series==NULL) ? ? ? ? continue; ? ? ?//--- In the loop by the total number of symbol timeseries, ? ? ?int total_series=list_series.Total(); ? ? ?for(int j=0;j<total_series;j++) ? ? ? ?{ ? ? ? ? //--- get the next timeseries object ? ? ? ? CSeriesDE *series=list_series.At(j); ? ? ? ? if(series==NULL || this.IsExistTimeframe(series.Timeframe())) ? ? ? ? ? ?continue; ? ? ? ? //--- increase the number of used timeframes and (num_periods variable), and ? ? ? ? //--- write the timeseries timeframe value to the array of used timeframes by num_periods-1 index ? ? ? ? num_periods++; ? ? ? ? ArrayUsedTimeframes[num_periods-1]=series.Timeframe(); ? ? ? ?} ? ? } //--- Upon the loop completion, change the size of both arrays to match the exact number of added symbols and timeframes ? ::ArrayResize(ArrayUsedSymbols,num_symbols,SYMBOLS_COMMON_TOTAL); ? ::ArrayResize(ArrayUsedTimeframes,num_periods,21); ?} //+------------------------------------------------------------------+