- 26994:No slaves here, learn to code or pay someone. I have posted my MM routine many times
I have an OsMA+2MA Cross bot. I want to put "proportional MM" in it, but
Works with static lots, works with profit after optimization on any (except M1) time frame.//+------------------------------------------------------------------+ //| Lot size computation. | //+------------------------------------------------------------------+ void OnInitLotSize(){ at.risk.equity = 0; at.risk.chart = 0; } double LotSize(double risk){ /*double at.risk.new; // Export to init/start //double TEF.value, // Import from ComputeTEF // at.risk.equity // Import from ModifyStops //double at.risk.chart; // Import from ModifyStops //int op.code; // OP_BUY/OP_SELL // Import from SetDIR */ /* This function computes the lot size for a trade. * Explicit inputs are SL relative to bid/ask (E.G. SL=30*points,) * Implicit inputs are the MM mode, the MM multiplier, count currently * filled orders by all EA's vs this EA/pair/period count and history. * Implicit inputs are all used to reduce available balance the maximum * dollar risk allowed. StopLoss determines the maximum dollar risk possible * per lot. Lots=maxRisk/maxRiskPerLot **************************************************************************/ /*++++ Compute lot size based on account balance and MM mode*/{ double ab = AccountBalance() - at.risk.equity; switch(MM.F0M1G2){ case MMMODE_FIXED: double minRisk = MM.PerTrade, maxRisk = MM.MaxRisk; break; case MMMODE_MODERATE: // See https://www.mql5.com/en/articles/1526 Fallacies, Part 1: Money // Management is Secondary and Not Very Important. maxRisk = MathSqrt(MM.MaxRisk * ab); minRisk = MathSqrt(MM.PerTrade * ab); break; case MMMODE_GEOMETRICAL: minRisk = MM.PerTrade * ab; maxRisk = MM.MaxRisk * ab; break; } ComputeTEF(); double minLot = MarketInfo(Symbol(), MODE_MINLOT), lotStep = MarketInfo(Symbol(), MODE_LOTSTEP), perLotPerPoint = PointValuePerLot(), maxLossPerLot = (risk+Slippage.Pips*pips2dbl) * perLotPerPoint, size = minRisk / maxLossPerLot; // Must still round to lotStep. /*---- Compute lot size based on account balance and MM mode*/} /* The broker doesn't care about the at.risk/account balance. They care * about margin. Margin used=lots used*marginPerLot and that must be less * than free margin available. Using the lesser of size vs * AccountFreeMargin / MODE_MARGINREQUIRED should have been sufficient, but * the tester was generating error 134 even when marginFree should have been * OK. So I also use AccountFreeMarginCheck < 0 which agrees with the * tester. Reported at https://forum.mql4.com/35056 * * Second problem, after opening the new order, if free margin then drops to * zero we get a margin call. In the tester, the test stops with: "EA: * stopped because of Stop Out" So I make sure that the free margin * after is larger then the equity risk so I never get a margin call. */ string status = "SL>AE"; // Assume size < minLot while (true){ // Adjust for broker, test for margin, combine with TEF... size = MathFloor(MathMax(0,size)/lotStep)*lotStep; at.risk.new = size * maxLossPerLot; // Export for Comment if (size < minLot){ at.risk.new = 0; EA.status = status; return(0); } if (at.risk.new+at.risk.chart > maxRisk){ size = (maxRisk-at.risk.chart)/maxLossPerLot; status = "MaxRisk"; continue; } // Multiple open trades double AFMC = AccountFreeMarginCheck(Symbol(), op.code, size), eRisk = at.risk.equity + risk*size*perLotPerPoint; /* at.risk.equity += Direction( OrderType() ) * * (OrderClosePrice()-OrderStopLoss())*perPoint; * Summed for all open orders. */ if (AFMC*0.99 <= eRisk){ size *= 0.95; status = "Free Margin"; continue; } // Prevent margin call if new trade goes against us. break; } if (TEF.Enable01>0){ size = MathFloor(size*MathMin(1, TEF.value)/lotStep)*lotStep; if (oo.count == 0 && size < minLot) size = minLot; // Not below min at.risk.new = size * maxLossPerLot; // Export for Comment if (size < minLot){ at.risk.new=0; EA.status = "TEF = "+TEF.value; return(0); } } return(size); // We're good to go. } // LotSize double PointValuePerLot() { // Value in account currency of a Point of Symbol. /* In tester I had a sale: open=1.35883 close=1.35736 (0.00147) * gain$=97.32/6.62 lots/147 points=$0.10/point or $1.00/pip. * IBFX demo/mini EURUSD TICKVALUE=0.1 MAXLOT=50 LOTSIZE=10,000 * IBFX demo/standard EURUSD TICKVALUE=1.0 MAXLOT=50 LOTSIZE=100,000 * $1.00/point or $10.00/pip. * * https://forum.mql4.com/33975 CB: MODE_TICKSIZE will usually return the * same value as MODE_POINT (or Point for the current symbol), however, an * example of where to use MODE_TICKSIZE would be as part of a ratio with * MODE_TICKVALUE when performing money management calculations which need * to take account of the pair and the account currency. The reason I use * this ratio is that although TV and TS may constantly be returned as * something like 7.00 and 0.00001 respectively, I've seen this * (intermittently) change to 14.00 and 0.00002 respectively (just example * tick values to illustrate). */ return( MarketInfo(Symbol(), MODE_TICKVALUE) / MarketInfo(Symbol(), MODE_TICKSIZE) ); // Not Point. }
Thanks. I'll try this code.
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
Hello to all.
I have an OsMA+2MA Cross bot. I want to put "proportional MM" in it, but
Works with static lots, works with profit after optimization on any (except M1) time frame.
Also, the EX4 file is here. You can test it...
I promise, the bot will be posted here later.
The Code:
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
double OsMA1, OsMA2;
double MAfast3, MAslow4;
double Lots; - OKAY. TEH LOTS.
double Slippage;
int cnt, ticket, total;
//----
if (Bars<100)
{
Print("bars less than 100");
return(0);
}
//----
// Lots = 0.1; -
Lots = AccountEquity()/Close[0]/1000*PercentsOfMoney/100; - <------------- <------------- <------------- HERE
OsMA1=iOsMA(0,0,fast_ema_period,slow_ema_period,signal_period,applied_price,shift_1);
OsMA2=iOsMA(0,0,fast_ema_period,slow_ema_period,signal_period,applied_price,shift_2);
MAfast3=iMA(NULL,0,M_A_Period_Fast,0,MODE_SMA,PRICE_CLOSE,1);
MAslow4=iMA(NULL,0,M_A_Period_Slow,0,MODE_SMA,PRICE_CLOSE,1);
total=OrdersTotal();
if(total<1)
{
// no opened orders identified
if(AccountFreeMargin()<(1000*Lots))
{
Print("We have no money. Free Margin = ", AccountFreeMargin());
return(0);
}
// check for long position (BUY) possibility
if(OsMA1>0&& MAfast3>MAslow4)
{
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,Ask-StopLoss*Point,0,"AveRage",994,0,Blue); //Zero BEFORE "AveRage" is for TakeProfit (not setted)
if(ticket>0)
//"994"
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice());
}
else Print("orderSend failed with error #", GetLastError());
return(0);
}
// check for short position (SELL) possibility
if(OsMA1<0 && MAfast3<MAslow4)
{
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,Bid+StopLoss*Point,0,"AveRage",994,0,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice());
}
else Print("orderSend failed with error #", GetLastError());
return(0);
}
return(0);
} // exit market correctly...
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()<=OP_SELL && // check for opened position
OrderSymbol()==Symbol()) // check for symbol
{
if(OrderType()==OP_BUY) // long position is opened
{
// should it be closed?
if(OsMA1<0 && MAfast3<MAslow4)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close position
return(0); // exit
}
}
else // go to short position
{
// should it be closed?
if(OsMA1>0 && MAfast3>MAslow4)
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close position
return(0); // exit
}
}
}
}
return(0);
}