CPermutedSymbolData 类赫兹量化软件脚本 PrepareSymbolsForPermutationTest 已更新,以反映对 CPermuteTicks 所做的更改和 CPermuteRates 的引入。脚本的功能包含在类 CPermutedSymbolData 中,它允许根据现有交易品种生成具有置换分时或报价的自定义交易品种。//+------------------------------------------------------------------+//|Permute rates or ticks of symbol |//+------------------------------------------------------------------+enum ENUM_RATES_TICKS { ENUM_USE_RATES=0,//Use rates ENUM_USE_TICKS//Use ticks };//+------------------------------------------------------------------+//| defines:max number of data download attempts and array resize |//+------------------------------------------------------------------+#define MAX_DOWNLOAD_ATTEMPTS 10#define RESIZE_RESERVE 100//+------------------------------------------------------------------+//|CPermuteSymbolData class |//| creates custom symbols from an existing base symbol's data |//| symbols represent permutations of base symbol's data |//+------------------------------------------------------------------+class CPermuteSymbolData {private: ENUM_RATES_TICKS m_use_rates_or_ticks;//permute either ticks or rates string m_basesymbol; //base symbol string m_symbols_id; //common identifier added to names of new symbols datetime m_datarangestart; //beginning date for range of base symbol's data datetime m_datarangestop; //ending date for range of base symbol's data uint m_permutations; //number of permutations and ultimately the number of new symbols to create MqlTick m_baseticks[]; //base symbol's tick MqlTick m_permutedticks[]; //permuted ticks; MqlRates m_baserates[]; //base symbol's rates MqlRates m_permutedrates[]; //permuted rates; CPermuteRates *m_rates_shuffler; //object used to shuffle rates CPermuteTicks *m_ticks_shuffler; //object used to shuffle ticks CNewSymbol *m_csymbols[]; //array of created symbolspublic: CPermuteSymbolData(const ENUM_RATES_TICKS mode); ~CPermuteSymbolData(void); bool Initiate(const string base_symbol,const string symbols_id,const datetime start_date,const datetime stop_date); uint Generate(const uint permutations); };这是通过在构造函数调用中指定要打乱的数据类型(分时或报价)来实现的。枚举 ENUM_RATES_TICKS 描述了构造函数的单个参数可用的选项。//+-----------------------------------------------------------------------------------------+//|set and check parameters for symbol creation, download data and initialize data shuffler |//+-----------------------------------------------------------------------------------------+bool CPermuteSymbolData::Initiate(const string base_symbol,const string symbols_id,const datetime start_date,const datetime stop_date) {//---reset number of permutations previously done m_permutations=0;//---set base symbol m_basesymbol=base_symbol;//---make sure base symbol is selected, ie, visible in WatchList if(!SymbolSelect(m_basesymbol,true)) { Print("Failed to select ", m_basesymbol," error ", GetLastError()); return false; }//---set symbols id m_symbols_id=symbols_id;//---check, set data date range if(start_date>=stop_date) { Print("Invalid date range "); return false; } else { m_datarangestart= start_date; m_datarangestop = stop_date; }//---download data Comment("Downloading data"); uint attempts=0; int downloaded=-1; while(attempts<MAX_DOWNLOAD_ATTEMPTS && !IsStopped()) { downloaded=(m_use_rates_or_ticks==ENUM_USE_TICKS)?CopyTicksRange(m_basesymbol,m_baseticks,COPY_TICKS_ALL,long(m_datarangestart)*1000,long(m_datarangestop)*1000):CopyRates(m_basesymbol,PERIOD_M1,m_datarangestart,m_datarangestop,m_baserates); if(downloaded<=0) { Sleep(500); ++attempts; } else break; }//---check download result if(downloaded<=0) { Print("Failed to download data for ",m_basesymbol," error ", GetLastError()); Comment(""); return false; }//Print(downloaded," Ticks downloaded ", " data start ",m_basedata[0].time, " data end ", m_basedata[m_basedata.Size()-1].time);//---return shuffler initialization result switch(m_use_rates_or_ticks) { case ENUM_USE_TICKS: { if(m_ticks_shuffler==NULL) m_ticks_shuffler=new CPermuteTicks(); return m_ticks_shuffler.Initialize(m_baseticks); } case ENUM_USE_RATES: { if(m_rates_shuffler==NULL) m_rates_shuffler=new CPermuteRates(); return m_rates_shuffler.Initialize(m_baserates); } default: return false; } }一旦创建了CPermutedSymbolData的实例,就应该调用Initiate()方法来指定交易品种和日期周期,定义置换将基于的分时或报价。//+------------------------------------------------------------------+//| generate symbols return newly created or refreshed symbols |//+------------------------------------------------------------------+uint CPermuteSymbolData::Generate(const uint permutations) {//---check permutations if(!permutations) { Print("Invalid parameter value for Permutations "); Comment(""); return 0; }//---resize m_csymbols if(m_csymbols.Size()!=m_permutations+permutations) ArrayResize(m_csymbols,m_permutations+permutations,RESIZE_RESERVE);//--- string symspath=m_basesymbol+m_symbols_id+"_PermutedData";//int exists;//---do more permutations for(uint i=m_permutations; i<m_csymbols.Size() && !IsStopped(); i++) { if(CheckPointer(m_csymbols)==POINTER_INVALID) m_csymbols=new CNewSymbol(); if(m_csymbols.Create(m_basesymbol+m_symbols_id+"_"+string(i+1),symspath,m_basesymbol)<0) continue; Comment("Processing Symbol "+m_basesymbol+m_symbols_id+"_"+string(i+1)); if(!m_csymbols.Clone(m_basesymbol) || (m_use_rates_or_ticks==ENUM_USE_TICKS && !m_ticks_shuffler.Permute(m_permutedticks)) || (m_use_rates_or_ticks==ENUM_USE_RATES && !m_rates_shuffler.Permute(m_permutedrates))) break; else { m_csymbols.Select(true); Comment("Adding permuted data"); if(m_use_rates_or_ticks==ENUM_USE_TICKS) m_permutations+=(m_csymbols.TicksReplace(m_permutedticks)>0)?1:0; else m_permutations+=(m_csymbols.RatesUpdate(m_permutedrates)>0)?1:0; } }//---return successfull number of permutated symbols Comment("");//--- if(IsStopped()) return 0;//--- return m_permutations; }//+------------------------------------------------------------------+如果Initiate()返回true,则可以调用具有所需置换数的Generate()方法。该方法将返回自定义交易品种的计数,这些交易品种的数据已成功地用置换的分时或报价进行了补充。//+------------------------------------------------------------------+//| PrepareSymbolsForPermutationTests.mq5 |//| Copyright 2023, MetaQuotes Ltd. |//| https://www.MQL5.com |//+------------------------------------------------------------------+#property copyright "Copyright 2023, MetaQuotes Ltd."#property link "https://www.MQL5.com"#property version "1.00"#include<PermutedSymbolData.mqh>#property script_show_inputs//--- input parametersinput string BaseSymbol="EURUSD";input ENUM_RATES_TICKS PermuteRatesOrTicks=ENUM_USE_RATES;input datetime StartDate=D'2022.01.01 00:00';input datetime EndDate=D'2023.01.01 00:00';input uint Permutations=100;input string CustomID="_p";//SymID to be added to symbol permutation names//---CPermuteSymbolData *symdata;//+------------------------------------------------------------------+//| Script program start function |//+------------------------------------------------------------------+void OnStart() { ulong startime = GetTickCount64(); uint permutations_completed=0; // number of successfully added permuted data//---intialize the permuted symbol object symdata = new CPermuteSymbolData(PermuteRatesOrTicks);//---set the properties of the permuted symbol object if(symdata.Initiate(BaseSymbol,CustomID,StartDate,EndDate)) permutations_completed = symdata.Generate(Permutations); // do the permutations//---print number of symbols whose bar or tick data has been replenished. Print("Number of permuted symbols is ", permutations_completed, ", Runtime ",NormalizeDouble(double(GetTickCount64()-startime)/double(60000),1),"mins");//---clean up delete symdata; }//+------------------------------------------------------------------+上面是脚本的代码。所有源代码都附在文章后面。9 P8 o v+ a- h# D. J' D! |( Q: s W5 G
应用置换测试在文章的引言中,赫兹量化软件谈到了许多想要购买 EA 交易的人面临的一个常见问题。无良卖家可能会采用欺骗手段来推销他们的产品。卖家通常会展示具有吸引力的净值曲线来代表潜在利润。许多人成为了这些策略的受害者,并艰难地了解到这些截图是由诱导策略产生的。在本节中,赫兹量化软件将了解代码库中一个臭名昭著的EA,该EA可用于生成误导性的净值曲线。并应用置换测试来揭开骗局。7 a: c1 w9 q3 }4 }" n7 `2 M
添加图片注释,不超过 140 字(可选) |