Lot Size Management

 

Hi, sorry to bother you all again, but I was wondering if anyone can point me in the right direction. The problem I am having is turning the formula on the attached file into code for my EA. I am trying to add code that will automatically change the lot size as my equity grows in increments of 500 pips, e.g. if I start with £1000 at 0.01 % risk (10p a pip) and when it reaches £1050, I automatically want the lot size to change to 0.019% risk (20p a pip), £1150 0.26% and so on. Please msg me if you do not understand the spreadsheet and I will endevour to explain it to you. I would like to keep all of the variables (in pink) if at all possible.

Thank You in advance for your time and help

MW

 
//+------------------------------------------------------------------+
//| 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
//          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;
    }
    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.
}
Reason: