That depends on the strategy you coded.
If that runs on Tick then there could be a rather large difference, but if you coded it on a M1 bar then it would be close to the same.
So nothing can be said about it because it all depends on the way the application has been coded.
Hi Marco,
thanks for your reply.
So instead of using the OnTick Handle I should use OnTimer? Would it still be correct to code it with a M1 timer when I use the Daily Chart or should I use a higher Timer that is close to the D1 time. (86400 would be one day I guess)
Or Are you talking about something completely diffrent? There is no Handle like OnNewBar in MQL5...
Oh.. and why is the same Modelling on the Visualisation giving such a huge different result on SingleTest/Optimation? Isnt the only differnence the fact that one runs wit showing the testing and one without showing the test? So generelly both should do the same or do I get something wrong there?
Thanks again and have a great day!
No i mean you can code an EA that handles every incoming tick but you can also write an EA that only handles every new M1 bar so the last one will simply check the open price everytime a new bar arrives.
This has got nothing to do with the OnTimer() function but solely with the way it was coded.
For example if you use a trailingstop this could run OnTick() then it will monitor and adjust the stop every incoming tick.
But you can also use and compare the bar time in that case it will only adjust when a new bar opens.
If you look at the bar time and it changes then you will know a new bar has arrived.
The open price only mode is just to quickly test the logic.
Your right about the visualization issue it should be the same with and without so you might want to check the logs on that one.
Thanks again Marco. I still have to ask... so the Code bellow should give the same result in Visualisation and in SingleTest/Optimazion. If Not there must be an issue in the Code that I can try to find in the logs?!
Cause I get the same results when I test a shorter amount of time with the RealTicks/OHLC... but when I change to to OPO it differs...
Update: I found the Issue. The CustomIndicator I use to get my LotSize and SL/TP somethimes gave Invalid values. When I use no SL/TP and a fixed LotSize I get the same results in every Modelling... So I guess I have to calculate my Lotsize on my own...I dont know why the Visualisation did ignore this and still gave me the trades but at least I am a little smarter now ;)
Thanks again Marco for your help! Cause of you I watched in the Log and found that issue.
(I posted just parts of the code here... so dont expect it to run^^)
//--- Include standard libraries #include <Trade\AccountInfo.mqh> #include <Trade\PositionInfo.mqh> #include <Trade\SymbolInfo.mqh> #include <Trade\Trade.mqh> //--- Classes CAccountInfo AccountInfo; CPositionInfo PositionInfo; CSymbolInfo SymbolInfo; CTrade trade; //--- Number of symbols for each strategy #define Strategy_A 28 //------------------- External parameters of strategy A input string Data_for_Strategy_A="Strategy A -----------------------"; //---Symbole und Handelserlaubnis string SymbolArray[]={"EURUSD","GBPUSD","USDCHF" ,"USDJPY","USDCAD","AUDUSD","EURGBP","GBPJPY", "AUDJPY","CHFJPY","EURCAD","EURNZD","NZDCAD","NZDCHF","NZDJPY","EURJPY","EURCHF", "AUDCAD","AUDCHF","AUDNZD","CADCHF","CADJPY","EURAUD","GBPAUD","GBPCAD", "GBPCHF","GBPNZD","NZDUSD"}; input bool myIsTrade_A0 = true; // Permission for trading //--- TimeFrame input ENUM_TIMEFRAMES Period_A0 = PERIOD_D1; input group "TS und TP Varianten" input bool FirstTPCheck = true; // Ersten TP nehmen und Position halbieren input bool TSCheck = true; // TrailingStopp einbauen (sont wird nur SL und TP gesetzt) input double PriceMoveFactor =2; input group "1. Confi" input int inpFastLength_A0 = 6; // Fast length input int inpSlowLength_A0 = 18; // Slow length input group "Position Size Calculations" input int InpATRperiod=14; // ATR Periods input double InpRiskPC=2.0; // Risk Size % input double InpSLfactor=1.5; // Stop Loss as a factor of ATR input double InpTPfactor=1.0; // Take Profit as a factor of ATR input int InpFontSize=9; // Font size input color InpColor=clrMagenta; // Color input ENUM_BASE_CORNER InpBaseCorner=CORNER_RIGHT_UPPER; // Corner input double InpFixedATR=0; // Fixed ATR points input bool InpBack=false; // Background object input bool InpSelection=false; // Highlight to move input bool InpHidden=true; // Hidden in the object list input long InpZOrder=0; // Priority for mouse click //------------- Set variables of strategy A ----- //--- Arrays for external parameters string mySymbolPair[Strategy_A]; bool myIsTrade_A[Strategy_A]; //ENUM_TIMEFRAMES TimeFrame_A[Strategy_A]; //--- Indicator handle Array und Variablen für CI1 int FirstConfiDefinition[Strategy_A]; double myFirstConfiBufferOneArray[]; double myFirstConfiBufferTwoArray[]; //--- Indicator handle Array und Variablen für PoseSize int PoseSizeDefinition[Strategy_A]; double myPoseSizeVolumeArray[]; double myPoseSizeShortSLArray[]; double myPoseSizeShortTPArray[]; double myPoseSizeLongSLArray[]; double myPoseSizeLongTPArray[]; double Balance; double Equity; double VolumeOrder; double ShortSLOrder; double ShortTPOrder; double LongSLOrder; double LongTPOrder; //--- Positionenen Verarbeitung int mySignalBeforeArray[Strategy_A]; int myPosTotalBreak[Strategy_A]; ulong myDealTicketPosition [Strategy_A]; int myPositionsTotalOld [Strategy_A]; int TotalNumberOfDeals; ulong TicketNumberDeal; ulong DealReason; string MyDealSymbol; long MyDealType; //--- Set global variables for all strategies long Leverage; datetime old_Time=0; //---===================== The OnInit function ======================================================= int OnInit() { //--- Set event generation frequency EventSetTimer(86400); // 1 second 86400=D1 //--- Get the leverage for the account Leverage=AccountInfo.Leverage(); //--- Checks and actions associated with strategy A ------------- //--- Copy external variables to arrays for(int i=0; i<Strategy_A; i++) {mySymbolPair[i]=SymbolArray[i]; myIsTrade_A[i]=myIsTrade_A0; //TimeFrame_A[i]=Period_A0; } //--- Check for the symbol in the Market Watch for(int i=0; i<Strategy_A; i++) { if(myIsTrade_A[i]==false) continue; if(IsSymbolInMarketWatch(mySymbolPair[i])==false) { Print(mySymbolPair[i]," could not be found on the server!"); ExpertRemove(); } } //--- Check whether the symbol is used more than once if(Strategy_A>1) { for(int i=0; i<Strategy_A-1; i++) { if(myIsTrade_A[i]==false) continue; for(int j=i+1; j<Strategy_A; j++) { if(myIsTrade_A[j]==false) continue; if(mySymbolPair[i]==mySymbolPair[j]) { Print(mySymbolPair[i]," is used more than once!"); ExpertRemove(); } } } } //--- General actions for(int i=0; i<Strategy_A; i++) { if(myIsTrade_A[i]==false) continue; //--- Set indicator handles FirstConfiDefinition[i] =iCustom(mySymbolPair[i],Period_A0,"Downloads\\Confirmation Indi\\PTL (2)", inpFastLength_A0,inpSlowLength_A0); PoseSizeDefinition[i] = iCustom (mySymbolPair[i],Period_A0,"Downloads\\SL Calculator\\pos_size_Datawindow extende",InpATRperiod,InpRiskPC, InpSLfactor,InpTPfactor,InpFontSize,InpColor,InpBaseCorner,InpFixedATR,InpBack,InpSelection,InpHidden,InpZOrder); ChartIndicatorAdd(i,0,FirstConfiDefinition[i]); ChartIndicatorAdd(i,0,PoseSizeDefinition[i]); mySignalBeforeArray[i]=0; } return(0); } //-===================== The OnTimer function ====================================================== void OnTimer() { //--- Check if the terminal is connected to the trade server if(TerminalInfoInteger(TERMINAL_CONNECTED)==false) return; //--- Section A: Main loop of the FOR operator for strategy A ----------- for(int A=0; A<Strategy_A; A++) { datetime bar_Time=iTime(mySymbolPair[A],Period_A0,0); if(bar_Time>old_Time) { old_Time=bar_Time; //--------------------------------------------------Werte der Indikatoren berechnen------------------------------------------------ //--- 1. CI Werte ArraySetAsSeries(myFirstConfiBufferOneArray,true); CopyBuffer(FirstConfiDefinition[A],4,0,3,myFirstConfiBufferOneArray); double PTLCandleColorValue = NormalizeDouble(myFirstConfiBufferOneArray[1],1); double PTLCandleColorVergl = NormalizeDouble(myFirstConfiBufferOneArray[2],1); //--------------------------------------------------Ablauf der Positionen für TS,Exit------------------------------------------------ //--- prüft ob Positonen für das Symbol vorhanden sind -> wenn ja muss nichts neues berechnet werden if (PositionsTotal()>0) { int cntMyPos=PositionsTotal(); for(int ti=cntMyPos-1; ti>=0; ti--) { // skip if there is a position for the current symbol if(PositionGetSymbol(ti) == mySymbolPair[A] ) { myPosTotalBreak[A] = 1; break; } else { myPosTotalBreak[A] = 0; } } } else { myPosTotalBreak[A] = 0; } //--- Prüfen ob Bedingungen für eine Positiontseröffnug gegeben sind und wenn ja, dann Position eröffnen if (myPosTotalBreak[A]==0) { ArraySetAsSeries(myPoseSizeVolumeArray,true); ArraySetAsSeries(myPoseSizeShortSLArray,true); ArraySetAsSeries(myPoseSizeShortTPArray,true); ArraySetAsSeries(myPoseSizeLongSLArray,true); ArraySetAsSeries(myPoseSizeLongTPArray,true); CopyBuffer(PoseSizeDefinition[A],1,0,2,myPoseSizeVolumeArray); CopyBuffer(PoseSizeDefinition[A],2,0,2,myPoseSizeShortSLArray); CopyBuffer(PoseSizeDefinition[A],3,0,2,myPoseSizeShortTPArray); CopyBuffer(PoseSizeDefinition[A],4,0,2,myPoseSizeLongSLArray); CopyBuffer(PoseSizeDefinition[A],5,0,2,myPoseSizeLongTPArray); VolumeOrder = NormalizeDouble(myPoseSizeVolumeArray[1],2); ShortSLOrder = NormalizeDouble(myPoseSizeShortSLArray[1],_Digits); ShortTPOrder = NormalizeDouble(myPoseSizeShortTPArray[1],_Digits); LongSLOrder = NormalizeDouble(myPoseSizeLongSLArray[1],_Digits); LongTPOrder = NormalizeDouble(myPoseSizeLongTPArray[1],_Digits); SymbolInfo.Name(mySymbolPair[A]); SymbolInfo.RefreshRates(); double Ask_price=SymbolInfo.Ask(); double Bid_price=SymbolInfo.Bid(); //Abfrage ob Positionen eroeffnet werden koennen if(PTLCandleColorValue==0.0 &&(PTLCandleColorVergl==1.0 || PTLCandleColorVergl==-1.0) ) { Print(mySymbolPair[A]," : Kaufsignal LONG berechnet V1 ohne TS"); trade.PositionOpen(mySymbolPair[A],ORDER_TYPE_BUY,NormalizeDouble((VolumeOrder),2),Ask_price,LongSLOrder,LongTPOrder,NULL); mySignalBeforeArray[A]=1; myPosTotalBreak[A]=1; } if(PTLCandleColorValue==0.0 && (mySignalBeforeArray[A]==-1 ||mySignalBeforeArray[A]== 0) ) { Print(mySymbolPair[A]," : Kaufsignal LONG berechnet V2 ohne TS"); trade.PositionOpen(mySymbolPair[A],ORDER_TYPE_BUY,NormalizeDouble((VolumeOrder),2),Ask_price,LongSLOrder,LongTPOrder,NULL); mySignalBeforeArray[A]=1; myPosTotalBreak[A]=1; } if (PTLCandleColorValue == 1.0 && (PTLCandleColorVergl == 0.0 || PTLCandleColorVergl==-1.0) ) { Balance=AccountInfoDouble(ACCOUNT_BALANCE); Equity=AccountInfoDouble(ACCOUNT_EQUITY); Print(mySymbolPair[A]," : Kaufsignal SHORT berechnet V1 ohne TS"); trade.PositionOpen(mySymbolPair[A],ORDER_TYPE_SELL,NormalizeDouble((VolumeOrder),2),Bid_price,ShortSLOrder,ShortTPOrder,NULL); mySignalBeforeArray[A]=-1; myPosTotalBreak[A]=1; } if (PTLCandleColorValue==1.0 &&(mySignalBeforeArray[A]==1 ||mySignalBeforeArray[A]== 0) ) { Print(mySymbolPair[A]," : Kaufsignal SHORT berechnet V2 ohne TS"); trade.PositionOpen(mySymbolPair[A],ORDER_TYPE_SELL,NormalizeDouble((VolumeOrder),2),Bid_price,ShortSLOrder,ShortTPOrder,NULL); mySignalBeforeArray[A]=-1; myPosTotalBreak[A]=1; } } } } } //-===================== The OnDeinit function ============================ void OnDeinit(const int reason) { //--- Termination of event generation EventKillTimer(); //--- Delete indicator handles for(int i=0; i<Strategy_A; i++) { IndicatorRelease(FirstConfiDefinition[i]); IndicatorRelease(PoseSizeDefinition[i]); } } //-===================== Function set ============================ //--- The IsSymbolInMarketWatch() function bool IsSymbolInMarketWatch(string f_Symbol) { for(int s=0; s<SymbolsTotal(false); s++) { if(f_Symbol==SymbolName(s,false)) return(true); } return(false); } //+-----------------------------------------+ //| END OF PROGRAM | //+-----------------------------------------+
That code appears to run OnTimer() which is not OnTick() and not on open prices only.
Theoretically it can open positions without an open price and without any tick.
Open prices means the open price of every canle so that is not OnTick() and not OnTimer() but at every arrival of a new bar.
You could compare that with 1 tick a minute on a M1 time frame and 60 ticks (because 60 new bars thus 60 * a new open price) an Hour.
If you want the same open price only mode but in on tick you would have to filter out all other ticks an keep just the first one that opens a new candle.
You can do that by comparing the bar times.
datetime time_m1;
if(time_m1 != iTime(Symbol(),PERIOD_M1,0)) { // do something.... Alert("New bar"); time = iTime(Symbol(),PERIOD_CURRENT,0) }You can also do a combination of both so tat you can still observe and adjust open positions on every tick while only opening positions on a new bar and etc.
- www.mql5.com
Hi Marco,
thanks for your respeonse again! I could fix my EA so that i brings me the same results on Visu and on Single/Opti. Thanks for your help there. What you are writing above is realy interesting but I am a little confused.
I allways thought that I have to implement something like OnTimer or OnTick that my EA actually does something.
Is it possible to let him search for a new bar/for a different time without having it in OnTick/OnTimer or something else?
someting like:
void OnInit() { // do something.... } // can I call a Function just on global? like this? if(time_m1 != iTime(Symbol(),PERIOD_M1,0)) { do something....
Otherwise I guess you mean that I can use the OnTick Function as the basic Handle and in the OnTick Function I can call a if Function like above where the EA is only doing something when the nw bar occurs.
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hi all,
I am using an EA that is using Values from indicators of the last closed candle. So I expected that I can backtest it with using the "Open Pricy Only" Modelling because this is way faster. Specialy in the Optimazion. But the results made by this method are very different to the OHLC or the "every Tick "mode...
So I was wondering if this is typical for the Modelling (OPO not that accurate) or if I did something wrong with my code.
So my Questions:
1. Is it possible to get results as accurate as they are for OHLC/everyTick with the OPO modelling? If yes what has to be done?
2. If the answer for 1. is No: Since I only need the calculations of the last candle. how is it possible to speed up the Backtest/Optimazion when I have to use OHLC/everyTick for accurate results?
Thanks in advance for your help!
Thomas