Contents
Essence of the Trading Strategy
The main idea is as follows:
- Asset Selection: The trader selects a financial instrument for trading (e.g., stocks, currencies).
- Coin Flip: A random selection of trade direction (“buy” or “sell”).
- Position Opening: After choosing the side, a trade is opened for a predefined volume.
- Risk Management: Stop-loss and take-profit levels are set to limit losses and fix profits respectively.
Thus, all trading activity boils down to a random selection of price movement direction, which greatly simplifies decision-making.
Advantages and Disadvantages of the Strategy
Advantages of the tactic:
- No need to conduct complex technical or fundamental market analysis.
- No need for constant market analysis — this reduces stress levels.
- The strategy is easily automated and can be used in automated trading systems.
Disadvantages:
- Success probability is only 50%, significantly lower than most professional strategies.
- Ignoring important economic indicators and technical indicators increases loss risks.
- To minimize risks, substantial trading capital is recommended to withstand potential losses.
For successful strategy implementation, consider the following:
- Optimal position size is no more than 1% of total trading capital.
- Strict adherence to stop-loss and take-profit levels.
- Asset diversification: Using different financial instruments reduces overall portfolio risk.
Beginner traders should first test the ‘Heads or Tails’ strategy on demo accounts to assess its potential and develop their own position management approaches.
Expert Advisor Code
1. Overall File Structure
The expert file starts with a header (comment) indicating:
- File name (VR Heads or Tails.mq5);
- Author information and release year;
- Developer’s website.
Followed by #property directives setting expert metadata: copyrights, version, and required links.
2. Library Includes and Variable Declarations
For trading operations, standard MQL5 libraries are included:
#include <Trade\Trade.mqh>nCTrade trade; // Instance for trade managementnn#include <Trade\PositionInfo.mqh>nCPositionInfo posit; // Instance for position information
- CTrade — class for sending trade orders (buys, sells);
- CPositionInfo — class for getting data on open positions.
Then, input parameters of the expert are declared (configurable by user in MT5 interface):
input double iStartLots = 0.01; // Initial lotninput int iTakeProfit = 450; // Take-profit (in points)ninput int iStopLoss = 390; // Stop-loss (in points)ninput int iMagicNumber = 227; // Unique trade identifierninput int iSlippage = 30; // Maximum allowable slippage
- iStartLots — volume of the first trade;
- iTakeProfit and iStopLoss — profit and loss levels;
- iMagicNumber — number to identify robot trades (to avoid confusion with manual ones);
- iSlippage — allowable price deviation on order execution.
3. OnInit() Function — Robot Initialization
This function executes once on expert launch. Its task is to set trading parameters:
int OnInit() {n trade.SetExpertMagicNumber(iMagicNumber); // Set MagicNumbern trade.SetDeviationInPoints(iSlippage); // Set slippagen trade.SetTypeFillingBySymbol(_Symbol); // Execution type by symboln trade.SetMarginMode(); // Margin mode (hedging)n MathSrand(GetTickCount()); // Initialize random number generatorn return(INIT_SUCCEEDED); // Report successful launchn}
Key actions:
- SetExpertMagicNumber() — assigns unique identifier to trades.
- SetDeviationInPoints() — sets maximum allowable slippage.
- SetTypeFillingBySymbol() — configures order execution type (e.g., “market”).
- SetMarginMode() — activates hedging mode (separate positions per instrument).
- MathSrand() — initializes random number generator (used later for random trade direction selection).
4. OnTick() Function — New Quote Processing
This function is called on every new tick (price change). Let’s break it down.
4.1. Getting Market and Position Data
int total = ::PositionsTotal(); // Number of open positionsndouble Bid = ::SymbolInfoDouble(_Symbol, SYMBOL_BID); // BID pricendouble Ask = ::SymbolInfoDouble(_Symbol, SYMBOL_ASK); // ASK price
- PositionsTotal() — returns number of open positions;
- SymbolInfoDouble() — gets current BID (sell) and ASK (buy) prices.
If prices are invalid (≤ 0), the function exits:
if(Bid <= 0 || Ask <= 0)n return;
4.2. Analysis of Open Positions
The loop iterates through all positions and counts long (BUY) and short (SELL) trades:
for(int i = 0; i < total; i++) {n if(posit.SelectByIndex(i)) {n if(posit.Symbol() == _Symbol && posit.Magic() == iMagicNumber) {n if(posit.PositionType() == POSITION_TYPE_BUY) b++;n if(posit.PositionType() == POSITION_TYPE_SELL) s++;n }n }n}
- SelectByIndex() — selects position by index;
- Symbol() and Magic() — check if position belongs to current instrument and robot;
- PositionType() — determines position type (BUY/SELL).
4.3. Opening a New Trade
If no positions (b + s == 0), the robot randomly selects trade direction:
if((b + s) == 0) {n if(MathRand() % 2 == 0) { // Random choice: 0 — BUY, 1 — SELLn trade.Buy(iStartLots, _Symbol, Ask, Ask - iStopLoss * _Point, Ask + iTakeProfit * _Point, "");n } else {n trade.Sell(iStartLots, _Symbol, Bid, Bid + iStopLoss * _Point, Bid - iTakeProfit * _Point, "");n }n}
- MathRand() % 2 — generates random number (0 or 1);
- trade.Buy() — opens long position with specified TP and SL;
- trade.Sell() — opens short position.
Trade Function Parameters:<