In the logic of the Grid Martingale EA, the setting of the grid width and the martingale multiplier, which determines how much to increase the lot size, are the basic settings.
While the Martingale method typically uses a multiplier of 2, the Grid Martingale EA often employs a multiplier of 1.5.
In addition, there is a method called the “Cocomo” method, which involves a more complex calculation rather than simply multiplying the previous lot size by a constant.
This article will introduce how to expand the lot size setting function of the Grid Martingale EA, including the introduction of the Cocomo method.
Base Model of the EA
Here, we refer to the EA created in the following article as the “base model,” and we will be adding additional functionality to it.
This article explains how to create a very basic grid martingale EA from scratch, so if you haven’t seen it yet, please take a look.
Setting Input Parameters
In the base model, we had set the following input parameters.
input double first_lot = 0.01; // Initial lot size input
double nanpin_range = 200; // Grid range input
double profit_target = 1.00; // Profit target input
int magic_number = 10001; // Magic number static
int ticket_number; // Ticket number
double slippage = 10; // Slippage
We will add an additional input parameter for lot size patterns here.
input int lot_type = 1;// Lot size pattern (1: martingale 1.5x, 2: martingale 2x, 3: Cocomo method)
Lot Size Pattern (lot_type)
We have set a variable to switch between lot size settings for grid orders.
Here, we have set up three patterns to choose from:
- Martingale 1.5x
- Martingale 2x
- Cocomo method
Loop Processing
With the necessary additional processing completed beforehand, we will now move on to adding functionality within the loop processing.
void OnTick()
void OnTick()
{
From here on out, the following content will be added within the void OnTick() function.
Variable Definitions
In the base model, the following variables were defined:
int cnt;
int current_buy_position; // latest buy position
int current_sell_position; // latest sell position
int buy_position; // buy position count
int sell_position; // sell position count
double buy_profit; // unrealized profit/loss on buy positions
double sell_profit; // unrealized profit/loss on sell positions
We will add the following 5 definitions here:
double current_buy_lot; // lot size of the latest buy position
double current_sell_lot; // lot size of the latest sell position
double pre_buy_lot; // lot size of the previous buy position
double pre_sell_lot; // lot size of the previous sell position
double nanpin_lot; // lot size of the averaging down order
current_buy_lot、current_sell_lot
current_buy_lot is a variable that records the lot size of the latest buy position. For example, if there are three buy positions, it represents the lot size of the third buy position. current_sell_lot is the same.
pre_buy_lot、pre_sell_lot
pre_buy_lot is a variable that records the lot size of the second latest buy position. For example, if there are three buy positions, it represents the lot size of the second buy position. pre_sell_lot is the same.
nanpin_lot
To handle different cases when placing averaging down orders, we will prepare a variable called nanpin_lot.
Position Check
We will add a function to check the lot size of each position.
Before the addition
In the base model, the following code was used:
buy_position=0;// initialize buy position count
sell_position=0;// initialize sell position count
current_buy_position=-1;// initialize latest buy position
current_sell_position=-1;// initialize latest sell position
for(cnt=0;cnt<OrdersTotal();cnt++)// check positions
{
if(OrderSelect(cnt,SELECT_BY_POS)==false)continue;
if(OrderMagicNumber()!=magic_number)continue;
if(OrderType()==OP_BUY)
{
current_buy_position=cnt;
buy_position+=1;
buy_profit=buy_profit+OrderProfit();
};
if(OrderType()==OP_SELL)
{
current_sell_position=cnt;
sell_position+=1;
sell_profit=sell_profit+OrderProfit();
};
}
After the addition
We will make the following changes. (“//added” indicates the added lines.)
buy_position=0;//initialize buy position count
sell_position=0;//initialize sell position count
current_buy_position=-1;//initialize latest buy position
current_sell_position=-1;//initialize latest sell position
current_buy_lot=0;//initialize lot size of the latest buy position //added
current_sell_lot=0;//initialize lot size of the latest sell position //added
pre_buy_lot=0;//initialize lot size of the previous buy position //added
pre_sell_lot=0;//initialize lot size of the previous sell position //added
for(cnt=0;cnt<OrdersTotal();cnt++)//check positions
{
if(OrderSelect(cnt,SELECT_BY_POS)==false)continue;
if(OrderMagicNumber()!=magic_number)continue;
if(OrderType()==OP_BUY)
{
current_buy_position=cnt;
buy_position+=1;
buy_profit=buy_profit+OrderProfit();
pre_buy_lot=current_buy_lot; //added
current_buy_lot=OrderLots(); //added
};
if(OrderType()==OP_SELL)
{
current_sell_position=cnt;
sell_position+=1;
sell_profit=sell_profit+OrderProfit();
pre_sell_lot=current_sell_lot; //added
current_sell_lot=OrderLots(); //added
};
}
To explain the added lines, we are checking each position one by one, and if it is a buy position:
- We record the lot size of the previous buy position in pre_buy_lot before overwriting it with the lot size of the latest buy position in current_buy_lot.
- We record the lot size of the latest buy position in current_buy_lot before overwriting the previous value.
This process is done for each buy position. The recorded values of pre_buy_lot and current_buy_lot will remain after checking all buy positions.
Additional Entry (Martingale) Orders
Next, we will add a function for averaging down orders.
Before the addition
In the base model, the following code was used:
if(buy_position>0) //If holding one or more buy positions
{
OrderSelect(current_buy_position,SELECT_BY_POS); //Select the latest buy position
if(Ask<(OrderOpenPrice()-nanpin_range*Point)) //Check if the current price has reached the Martingale range
{
ticket_number=OrderSend(
Symbol(), //Currency pair
OP_BUY, //Buy:OP_BUY, Sell:OP_SELL
round(OrderLots()*1.5*100)/100, //Lot size
Ask, //Order price
slippage, //Slippage
0, //Stop-loss
0, //Take-profit
"nanpin_buy", //Order comment
magic_number, //Magic number
0, //Order expiration time
Blue //Arrow color
);
}
}
if(sell_position>0) //If holding one or more sell positions
{
OrderSelect(current_sell_position,SELECT_BY_POS); //Select the latest sell position
if(Bid>(OrderOpenPrice()+nanpin_range*Point)) //Check if the current price has reached the Martingale range
{
ticket_number=OrderSend(
Symbol(), //Currency pair
OP_SELL, //Buy:OP_BUY, Sell:OP_SELL
round(OrderLots()*1.5*100)/100, //Lot size
Bid, //Order price
slippage, //Slippage
0, //Stop-loss
0, //Take-profit
"nanpin_sell", //Order comment
magic_number, //Magic number
0, //Order expiration time
Red //Arrow color
);
}
}
Lot size selection
Regarding the lot size, we directly wrote it in the OrderSend function as follows:
round(OrderLots()*1.5*100)/100, //Lot size
We will now use the nanpin_lot variable that we added in the variable definitions to set the lot size as follows:
//Lot size selection
if(lot_type==1){nanpin_lot = round(OrderLots()*1.5*100)/100;} //Martingale multiplier: 1.5x
if(lot_type==2){nanpin_lot = round(OrderLots()*2*100)/100;} //Martingale multiplier: 2x
if(lot_type==3){nanpin_lot = pre_buy_lot+current_buy_lot;} //Cocomo method
Then, we simply replace the lot size part in the OrderSend function with nanpin_lot.
Regarding the Martingale multiplier of 2x, there is no need for further explanation, so I will briefly explain the Cocomo method.
This method determines the next lot size by adding the latest lot size to the previous lot size.
For example, if you have one buy position with a lot size of 0.01, pre_buy_lot would be 0.00 and current_buy_lot would be 0.01, so nanpin_lot would be 0.01.
The logic for the Cocomo method is as follows:
- If pre_buy_lot is 0.01 and current_buy_lot is 0.01, then nanpin_lot is 0.02.
- If pre_buy_lot is 0.01 and current_buy_lot is 0.02, then nanpin_lot is 0.03.
- If pre_buy_lot is 0.02 and current_buy_lot is 0.03, then nanpin_lot is 0.05.
And so on.
After the addition
The updated code with the added features is as follows:
if(buy_position>0) //If holding one or more buy positions
{
OrderSelect(current_buy_position,SELECT_BY_POS); //Select the latest buy position
if(Ask<(OrderOpenPrice()-nanpin_range*Point)) //Check if the current price has reached the Martingale range
{
//Lot size selection
if(lot_type==1){nanpin_lot = round(OrderLots()*1.5*100)/100;} //Martingale multiplier: 1.5x
if(lot_type==2){nanpin_lot = round(OrderLots()*2*100)/100;} //Martingale multiplier: 2x
if(lot_type==3){nanpin_lot = pre_buy_lot+current_buy_lot;} //Cocomo method
ticket_number=OrderSend(
Symbol(), //Currency pair
OP_BUY, //Buy:OP_BUY, Sell:OP_SELL
nanpin_lot, //Lot size
Ask, //Order price
slippage, //Slippage
0, //Stop-loss
0, //Take-profit
"nanpin_buy", //Order comment
magic_number, //Magic number
0, //Order expiration time
Blue //Arrow color
);
}
}
if(sell_position>0) //If holding one or more sell positions
{
OrderSelect(current_sell_position,SELECT_BY_POS); //Select the latest sell position
if(Bid>(OrderOpenPrice()+nanpin_range*Point)) //Check if the current price has reached the Martingale range
{
//Lot size selection
if(lot_type==1){nanpin_lot = round(OrderLots()*1.5*100)/100;} //Martingale multiplier: 1.5x
if(lot_type==2){nanpin_lot = round(OrderLots()*2*100)/100;} //Martingale multiplier: 2x
if(lot_type==3){nanpin_lot = pre_sell_lot+current_sell_lot;} //Cocomo method
ticket_number=OrderSend(
Symbol(), //Currency pair
OP_SELL, //Buy:OP_BUY, Sell:OP_SELL
nanpin_lot, //Lot size
Bid, //Order price
slippage, //Slippage
0, //Stop-loss
0, //Take-profit
"nanpin_sell", //Order comment
magic_number, //Magic number
0, //Order expiration time
Red //Arrow color
);
}
}
Conclusion
That concludes the addition of the functionality to modify the lot size for the martingale strategy.
Other Articles on Creating EAs
Adding Trading Time Limits and Forced Closure Functionality
Adding the ability to change take profit patterns
Creating an FX Automated Trading Tool (Bot) in Python
Here, we will introduce how to create an FX automated trading tool (bot) using Python.






Comments