![Testing and optimization of binary options strategies in MetaTrader 5](https://c.mql5.com/2/0/binary-strategy-tester_600x314.jpg)
Testing and optimization of binary options strategies in MetaTrader 5
Introduction
Recently, I became interested in binary options. After surfing the Internet and looking at brokers, it turned out that almost everyone uses their platforms for trading. These platforms do not have the ability to test strategies and have, at best, a meager set of standard indicators. After reviewing a large number of different strategies for binary options, I started wondering how to check these strategies and their optimization. As always, our beloved MetaTrader 5 came to my rescue. As always, I will try to share my experiments with you as simply as possible presenting the material without complex equations and code. But first, a little theory and arguments on whether it is worth delving into binary options or not.
Theory
Binary option is a digital contract, the subject of which is the forecast of an asset price direction in a selected period of time. The task is to correctly determine one of the two possible scenarios for the development of the market situation: whether the asset will rise or fall. Today, we have a wide selection of online options for currencies, securities and commodities. Practically anything (including a weather forecast) can be an asset. Trading does not require huge investments and deep financial and economic knowledge in the field of market exchange processes.
Types of binary options
High/Low is the simplest type of binary options as traders only have to determine, in which direction the price will go. In a bullish trend, it is advisable to buy High (Call). While Down (Put) is purchased if a downward movement of the asset is expected. The profit of High/Low options varies from 10% to 80% of the bet.
One touch represents an agreement, in which it is required to determine the achievement of the desired price level. The location of quotes during a closure does not matter. The touching of a given level is sufficient. The profitability of "One touch" is higher than usual and may reach 95%, since in most cases it is very difficult to predict them, but you can lose all 100%.
Range determines a price corridor, inside which the value of the asset will be located at the time of expiration. It is also difficult to understand and predict. Profitability is up to 95%.
Below I will test and optimize strategies for High/Low options as the most popular in my opinion.
Advantages and disadvantages
The advantages are as follows:
- Simplicity - you fix the amount of potential losses or profits avoiding the need to make complex calculations of stop loss and take profit levels, which is especially useful if you are a beginner.
- Simple registration on the website of the options broker - no need for a package of documents.
- The widest variety of resources - company stocks, stock indices, oil, gold, cryptocurrencies with the initial capital starting from $100 or even less. Trading on stock or futures markets requires greater amount of the initial deposit.
Disadvantages:
- High risks and negative expectation. It takes two wins to make up for one loss. Profitable efficiency up to 80%. A loss-making operation will cost more than a winning one.
- The "Casino" mode brings losses in the long run. Some try to apply tricks from the casino when trading or averaging methods such as Martingale, which violates the rules of proper trading and ultimately leads to a deposit destruction.
- Large commissions.
Currency pair. Optimization and forward test range. Settings
Below are all optimization and test parameters:
- Forex;
- EURUSD;
- M5, M15, M30, H1;
- Expiration time 5, 15, 30 minutes and 1 hour.
- Optimization range 1 year. 2021.01.28 - 2022.01.28.
- Forward test range is 1 year. 2022.01.28 - 2023.01.28;
- Initial deposit 10,000;
- Rate 10;
- Interest rate 80%.
Technical aspects
We need inputs for testing and optimization:
- StartDepo - starting deposit;
- OptionRate - rate;
- ExpirationTime - expiration time;
- ProfitPercent - profitability percentage;
- TimeFrame - indicator timeframe;
- Optimization - optimization switch;
- OptimizationFileName – file name for storing optimization results.
input string N0 = "------------Open settings----------------"; input double StartDepo = 10000; input int OptionRate = 10; input string N1 = "------------Close settings---------------"; input int ExpirationTime = 1; //ExpirationTime 1=5 min, 2=15 min, 3=30 min, 4=60 min input double ProfitPercent = 80; input string N2 = "------------Optimization settings--------"; input int TimeFrame = 1; //TimeFrame 1=5 min, 2=15 min, 3=30 min, 4=60 min input bool Optimization = false; input string OptimizationFileName = "Optimization.csv"; input string N3 = "------------Other settings---------------"; input int Slippage = 10; input int Magic = 111111; input string EAComment = "2Ma+RSI+Stochastic Oscillator";
We will also need variables to store and track changes in the deposit and in the number of profitable and unprofitable option purchases:
- XStartDepo - for storing the current deposit;
- Profit - for storing the number of profitable option purchases;
- Loss - for storing the number of unprofitable options;
double XStartDepo = StartDepo; int Profit=0; int Loss=0;
To track the position opening time and close the position after the expiration time in MetaTrader 5, we will use the function that returns the position opening time.
//+------------------------------------------------------------------+ //| Get open time in positions | //+------------------------------------------------------------------+ datetime GetTime(string symb="0", int type=-1, int mg=-1,int index=0) { datetime p[]; int c=-1, pr=0; if(symb=="0") { symb=Symbol();} for(int i=PositionsTotal()-1;i>=0;i--){ if(position.SelectByIndex(i)) { if(position.PositionType()==POSITION_TYPE_BUY || position.PositionType()==POSITION_TYPE_SELL) { if((position.Symbol()==symb||symb=="")&&(type<0||position.PositionType()==type)&&(mg<0||position.Magic()==mg)) { c++; ArrayResize(p, c+1); p[c]=position.Time(); pr=c>=index?index:c; }}}} return(c==-1?0:p[pr]); }
To track the profitability of a position and to make a decision whether we won a bet or not, we will use a function that returns the profit of an open position at the current time. Commissions and swaps are not considered.
//+------------------------------------------------------------------+ //| Get profit in positions | //+------------------------------------------------------------------+ double GetProfit(string symb="0", int type=-1, int mg=-1,int index=0) { double p[]; int c=-1, pr=0; if(symb=="0") { symb=Symbol();} for(int i=PositionsTotal()-1;i>=0;i--){ if(position.SelectByIndex(i)) { if(position.PositionType()==POSITION_TYPE_BUY || position.PositionType()==POSITION_TYPE_SELL) { if((position.Symbol()==symb||symb=="")&&(type<0||position.PositionType()==type)&&(mg<0||position.Magic()==mg)) { c++; ArrayResize(p, c+1); p[c]=position.Profit(); pr=c>=index?index:c; }}}} return(c==-1?0:p[pr]); }
Apply several triggers in order to handle only a new incoming signal. In other words, permission to enter occurs only with a new signal. Repeated entries on the same signal are ignored:
- TrigerSell - buy Put option;
- TrigerBuy - buy Call option;
int TrigerSell=0; int TrigerBuy=0;
Exiting a position, adding and subtracting funds from the initial deposit, as well as calculating the profitable and unprofitable purchases of options is carried out by tracking the current time relative to the opening of the position and the expiration time.
//Sell (Put) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
For optimization, use variables to determine the desired timeframe and expiration time. The optimization mode is enabled by the Optimization variable. The essence of optimization comes down to the use of files like CSV. After testing is completed in OnDeinit, write all the necessary variables to the file.When optimizing, Expert Advisors create a CSV file with the result at "C:\Users\Your username\AppData\Roaming\MetaQuotes\Terminal\Common\Files".
- Final deposit;
- Number of profitable trades;
- Number of losing trades;
- Timeframe;
- Expiration time.
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if (Optimization==true){ if (FileIsExist(OptimizationFileName)==false){ filehandle = FileOpen(OptimizationFileName,FILE_WRITE|FILE_READ|FILE_CSV|FILE_COMMON|FILE_ANSI, ";"); if(filehandle!=INVALID_HANDLE) { FileSeek(filehandle, 0, SEEK_END); FileWrite(filehandle,DoubleToString(XStartDepo),IntegerToString(Profit),IntegerToString(Loss),IntegerToString(XTimeFrame),IntegerToString(XExpirationTime)); FileClose(filehandle); } } } }
You can watch testing in visualization mode. Let's display the current result using Comment() for simplicity.
Strategies
2Ma+RSI+Stochastic Oscillator strategy
The strategy is offered by one well-known broker as a scalping strategy for binary options. Suggested timeframe is 5 minutes. Expiration time is 5 minutes.
Indicators:
- A pair of exponential moving averages with periods of 5 and 10;
- RSI, default settings;
- Stochastic Oscillator with the setting values of 14, 3, 3.
The "up" signal (or buying a Call option) when a number of conditions are met:
- The red moving average has crossed the blue moving average upwards;
- RSI is above 50;
- The fast Stochastic line crossed the slow (dotted) line upwards.
- The red MA crossed the blue one downwards;
- RSI is located below 50;
- The fast line of the Stochastic oscillator crosses the slow one downwards.
//Sell (Put) if((ind_In1S1[1]>ind_In2S1[1]) && (ind_In1S1[2]>ind_In2S1[2])){TrigerSell=1;} if ((TrigerSell==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (ind_In1S1[1]<ind_In2S1[1]) && (ind_In1S1[0]<ind_In2S1[0]) && (ind_In4S1[1]<50) && (ind_In4S1[0]<50) && (ind_In3S1_1[1]<ind_In3S1_2[1])){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerSell=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if((ind_In1S1[1]<ind_In2S1[1]) && (ind_In1S1[2]<ind_In2S1[2])){TrigerBuy=1;} if ((TrigerBuy==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (ind_In1S1[1]>ind_In2S1[1]) && (ind_In1S1[0]>ind_In2S1[0]) && (ind_In4S1[1]>50) && (ind_In4S1[0]>50) && (ind_In3S1_1[1]>ind_In3S1_2[1])){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerBuy=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
The test yields the following results:
- Final deposit 1964;
- Profitable trades 1273;
- Losing trades 1822.
After optimization, we get the result. As we can see, we did not get an increase to our deposit on any timeframe and expiration time.
Maverick strategy
This is an interesting and simple option strategy named Maverick. It is based on two technical analysis indicators. It is said to determine the trade entry and exit points quite accurately. Trading is offered on a timeframe of 1-5 minutes. In order to receive more signals, we can open several charts with different assets at the same time.
Indicators:
- Bollinger Bands 20 and StDev (standard deviation) 2;
- RSI indicator. RSI parameters – 4 with the borders of 80 and 20.
Growth forecast. Buying a Call option:
As soon as RSI indicator line enters the oversold area below 20, while the price line touches or goes beyond the Bollinger Bands, wait for the first bullish candle and enter an UPWARD trade.
Fall forecast. Buying a Put option:
After the RSI indicator line has entered the overbought area above 80, and the price line has gone beyond the upper limits of the Bollinger, wait for the first bearish candle and open a DOWNWARD trade.
I chose the closing of the previous candle inside the Bollinger indicator channel as a new signal trigger. The strategy code is displayed below.
//Sell (Put) if(iClose(symbolS1.Name(),XTimeFrame,1)<ind_In1S1_1[1]){TrigerSell=1;} if ((TrigerSell==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (iClose(symbolS1.Name(),XTimeFrame,2)>ind_In1S1_1[2]) && (ind_In2S1[2]>80) && (iClose(symbolS1.Name(),XTimeFrame,1)<iOpen(symbolS1.Name(),XTimeFrame,1))){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerSell=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if(iClose(symbolS1.Name(),XTimeFrame,1)>ind_In1S1_2[1]){TrigerBuy=1;} if ((TrigerBuy==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (iClose(symbolS1.Name(),XTimeFrame,2)<ind_In1S1_2[2]) && (ind_In2S1[2]<20) && (iClose(symbolS1.Name(),XTimeFrame,1)>iOpen(symbolS1.Name(),XTimeFrame,1))){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerBuy=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
Let's start the check. Let's conduct a test on M5. Get the result:
- Final deposit 3312;
- Profitable trades 1589;
- Losing trades 1940.
We have suffered a loss. Although the result is slightly better than in the previous strategy. Let's perform optimization in the hope of positive deposit values. Alas, the strategy does not work:
Vortex+TSI strategy
The strategy for binary options is called Vortex due to the use of the indicator of the same name. In fact, the strategy involves two indicators - the main one and the second one as a filter. The suggested timeframe is 1-5 minutes.
Indicators:
- Vortex 14;
- True Strength Indicator (TSI) 25, 13, 5, Exponential.
For buying a Call option:
- Wait for the simultaneous intersection of the lines of both indicators, when the blue lines are at the top, and the red ones go down;
- Vortex indicator lines should diverge.
For buying a Put option:
- Wait for the simultaneous intersection of the lines of both indicators, when the red lines are at the top, and the blue ones go down;
- Vortex indicator lines should diverge.
//Sell (Put) if(ind_In1S1_1[1]>ind_In1S1_2[1]){TrigerSell=1;} if ((TrigerSell==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (ind_In1S1_1[0]<ind_In1S1_2[0]) && (ind_In1S1_1[1]<ind_In1S1_2[1]) && (ind_In2S1_1[0]<ind_In2S1_2[0]) && (ind_In2S1_1[1]<ind_In2S1_2[1]) && (ind_In2S1_1[0]<ind_In2S1_1[1]) && (ind_In2S1_2[0]>ind_In2S1_2[1]) && (ind_In2S1_1[1]<ind_In2S1_1[2]) && (ind_In2S1_2[1]>ind_In2S1_2[2])){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerSell=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if(ind_In1S1_1[1]<ind_In1S1_2[1]){TrigerBuy=1;} if ((TrigerBuy==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (ind_In1S1_1[0]>ind_In1S1_2[0]) && (ind_In1S1_1[1]>ind_In1S1_2[1]) && (ind_In2S1_1[0]>ind_In2S1_2[0]) && (ind_In2S1_1[1]>ind_In2S1_2[1]) && (ind_In2S1_1[0]>ind_In2S1_1[1]) && (ind_In2S1_2[0]<ind_In2S1_2[1]) && (ind_In2S1_1[1]>ind_In2S1_1[2]) && (ind_In2S1_2[1]<ind_In2S1_2[2])){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerBuy=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
It is time to start testing our indicator strategy. Let's conduct a test on M5. Get the result:
- Final deposit -3118;
- Profitable trades 1914;
- Losing trades 2843.
The number of losing trades is greater. The final deposit went negative. Perhaps optimization will help.
The optimization results speak for themselves:
After testing about 10 more different strategies without the desired result, I decided to develop my own strategy. Based on the experience gained, I decided to try a different approach. The strategy is named New.
New strategy
I will use oversold and overbought situations as the central part of the strategy. I have also decided to add averaging. Although I am against such a decision, it is still interesting to check out the results.
Indicators:
Envelopes 14, 0, 0,1 Simple method is applied to Close.
"Upward" signal or buying a Call option:
- The Ask price is less than the lower line of the Envelopes indicator;
- The distance in points from the bottom line of the Envelopes indicator to the Ask price is greater than the Distance value.
"Downward" signal or buying a Put option:
- The Bid price is higher than the upper line of the Envelopes indicator;
- The distance in points from the Bid price to the Envelopes indicator line is greater than the Distance value.
No trigger is used in the strategy. A new entry signal is constantly monitored if the conditions are met and there is no open trade. Below is the strategy code without using averaging:
//Sell (Put) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (BidS1>(ind_In1S1_1[0]+(Distance*PointS1)))){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (AskS1<(ind_In1S1_2[0]-(Distance*PointS1)))){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
Let's test on M5. Distance=150. The test result without using averaging is in the screenshot below:
Losing trades 804.
There are more profitable entries than unprofitable ones, but we have lost part of the deposit. This is the negative expectation. With this approach, the maximum series of losing entries in a row was two, which I think will play into our hands when averaging.The result of optimization without using averaging is in the screenshot below. It was decided to include only profitable situations in the report for convenience and clarity:
Let's add averaging. I decided to limit the number of averaging entries. To do this, I introduced a new parameter Averaging, which is 4 by default. The averaging strategy code is provided below:
//Sell (Put) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (BidS1>(ind_In1S1_1[0]+(Distance*PointS1)))){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); Print(((XOptionRate*LossIn)*LossIn)); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+(((XOptionRate*LossIn)*ProfitPercent)/100); Profit++; LossIn=1; } else{ XStartDepo=XStartDepo-(XOptionRate*LossIn); Loss++; LossIn++; if(LossIn>Averaging){LossIn=1;} } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (AskS1<(ind_In1S1_2[0]-(Distance*PointS1)))){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); Print(((XOptionRate*LossIn)*LossIn)); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+(((XOptionRate*LossIn)*ProfitPercent)/100); Profit++; LossIn=1; } else{ XStartDepo=XStartDepo-(XOptionRate*LossIn); Loss++; LossIn++; if(LossIn>Averaging){LossIn=1;} } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
Test results with averaging. Finally, success:
Optimization results with averaging:
The results of a more interesting option with multiplying the rate after losing trades. The code is provided below:
//Sell (Put) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (BidS1>(ind_In1S1_1[0]+(Distance*PointS1)))){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); Print(((XOptionRate*LossIn)*LossIn)); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((((XOptionRate*LossIn)*LossIn)*ProfitPercent)/100); Profit++; LossIn=1; } else{ XStartDepo=XStartDepo-((XOptionRate*LossIn)*LossIn); Loss++; LossIn++; if(LossIn>Averaging){LossIn=1;} } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (AskS1<(ind_In1S1_2[0]-(Distance*PointS1)))){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); Print(((XOptionRate*LossIn)*LossIn)); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((((XOptionRate*LossIn)*LossIn)*ProfitPercent)/100); Profit++; LossIn=1; } else{ XStartDepo=XStartDepo-((XOptionRate*LossIn)*LossIn); Loss++; LossIn++; if(LossIn>Averaging){LossIn=1;} } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
Results of optimizing an interesting variant:
Conclusion
What conclusions can be drawn from all the work done? 99% of all indicator strategies practically do not work. By changing the approach a little, it is possible to develop a good profitable strategy. It is necessary to check everything before entering the market. As always, MetaTrader 5 will help us with this.By the way, there are already options with 100% profitability, which gives additional food for thought. You can download all considered strategies in the form of Expert Advisors in the attached archive.
Translated from Russian by MetaQuotes Ltd.
Original article: https://www.mql5.com/ru/articles/12103
![Neural networks made easy (Part 34): Fully Parameterized Quantile Function](https://c.mql5.com/2/50/Neural_Networks_Made_Easy_quantile-parameterized_avatar.png)
![Learn how to design a trading system by Fibonacci](https://c.mql5.com/2/52/learnhow_trading_system_fibonacci_avatar.png)
![Data Science and Machine Learning(Part 14): Finding Your Way in the Markets with Kohonen Maps](https://c.mql5.com/2/52/data_science_ml_kohonen_maps_avatar.png)
![Data Science and Machine Learning (Part 13): Improve your financial market analysis with Principal Component Analysis (PCA)](https://c.mql5.com/2/52/pca_avatar.png)
![MQL5 - Language of trade strategies built-in the MetaTrader 5 client terminal](https://c.mql5.com/i/registerlandings/logo-2.png)
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Thanks for your feedback. I don't use the mobile version of MT5. I can't tell you anything.
Meanwhile, how about the columns and the figures on each of them... Please do you mind adding headings to each column so we can follow? I don't know what the data on each column represents: which column represents balance, profit, loss, etc...? Please. I'm super grateful.
Table headers.
Final deposit, Number of profitable trades, Number of losing trades, Timeframe, Expiration time, Distance
>>> What conclusions can be drawn from all the work done? 99% of all indicator strategies practically do not work.
Reversing the entry to the position will not help. )
Table headers.
Final deposit, Number of profitable trades, Number of losing trades, Timeframe, Expiration time, Distance