I made universal position size calculating method based on risk

 

Hi, I couldn't find any satisfying solution, so I created my own, maybe it will be useful for someone, will be glad for any feedback.

Tested with online calculator on multiple pairs, and looks like it works.


class PositionSizeCalculator 
{
    public:

    double Calculate(double risk, double stopLossPips, string tradeDirection)
    {
        string tradingPair = Symbol();
        string tradingCurrency = AccountCurrency();
        double accountSize = AccountEquity(); //Don't know if AccountBalance or AccountEquity is better in this case
        double amountRisked = accountSize * (risk/100);
        double valuePerPip = amountRisked / stopLossPips;
        double lots = 0;

        if(tradingCurrency == GetCounterCurrency(tradingPair) || IsTesting())
        {
            lots = valuePerPip / 10;
            return (_Digits == 3) ? lots / 100 : lots;
        }
        else if(tradingCurrency == GetBaseCurrency(tradingPair))
        {
            double tradingPairPrice = (tradeDirection == "LONG") ? Bid : Ask;

            lots = valuePerPip * tradingPairPrice / 10;            
            return (_Digits == 3) ? lots / 100 : lots;
        }
        else
        {
            //We need to check price of currency pair so we can convert our value per pip
            string convertedPair = tradingCurrency + GetCounterCurrency(tradingPair);

            double convertedPairPrice = (tradeDirection == "LONG") ? MarketInfo(convertedPair, MODE_BID) : MarketInfo(convertedPair, MODE_ASK);
            
            //If currency pair like this don't exist, we check invert currencies and try again
            if(convertedPairPrice == 0)
            {
                convertedPair = InvertPair(convertedPair);
                convertedPairPrice = (tradeDirection == "LONG") ? MarketInfo(convertedPair, MODE_BID) : MarketInfo(convertedPair, MODE_ASK);

                lots = valuePerPip / convertedPairPrice / 10;
                //No need to secure from JPY pairs, because there is never JPY as a base currency
                return lots;
            }

            lots = valuePerPip * convertedPairPrice / 10;
            return (MarketInfo(convertedPair, MODE_DIGITS) == 3) ? lots / 100 : lots;
        }        

        return 0;
    }


    private:

    //+------------------------------------------------------------------+
    //| Helpers
    //+------------------------------------------------------------------+

    string GetBaseCurrency(string tradingPair)
    {
        return StringSubstr(tradingPair, 0, 3);
    }

    string GetCounterCurrency(string tradingPair)
    {
        return StringSubstr(tradingPair, 3, 3);
    }

    string InvertPair(string tradingPair)
    {
        return GetCounterCurrency(tradingPair) + GetBaseCurrency(tradingPair);
    }

}; 
 

Hi that will not work on brokers with pre or postfix.

Please see:

string base       = SymbolInfoString(tradingPair,SYMBOL_CURRENCY_BASE);
string counter    = SymbolInfoString(tradingPair,SYMBOL_CURRENCY_PROFIT);
 

Hi, thank you for your response.

I had to change a code a little bit, because SymbolInfoString doesn't work on symbols, that not exist. It sounds obvious, but I tried to figure out what's wrong for quite long :D

So, InvertPair method was removed and replaced with working solution. Thanks!


class PositionSizeCalculator 
{
    public:

    double Calculate(double risk, double stopLossPips, string tradeDirection)
    {
        string tradingPair = Symbol();
        string tradingCurrency = AccountCurrency();
        double accountSize = AccountEquity(); //Don't know if AccountBalance or AccountEquity is better in this case
        double amountRisked = accountSize * (risk/100);
        double valuePerPip = amountRisked / stopLossPips;
        double lots = 0;

        if(tradingCurrency == GetCounterCurrency(tradingPair) || IsTesting())
        {
            lots = valuePerPip / 10;
            return (_Digits == 3) ? lots / 100 : lots;
        }
        else if(tradingCurrency == GetBaseCurrency(tradingPair))
        {
            double tradingPairPrice = (tradeDirection == "LONG") ? Bid : Ask;

            lots = valuePerPip * tradingPairPrice / 10;            
            return (_Digits == 3) ? lots / 100 : lots;
        }
        else
        {
            //We need to check price of currency pair so we can convert our value per piri
            string convertedPair = tradingCurrency + GetCounterCurrency(tradingPair);

            double convertedPairPrice = (tradeDirection == "LONG") ? MarketInfo(convertedPair, MODE_BID) : MarketInfo(convertedPair, MODE_ASK);
            
            //If currency pair like this don't exist, we invert currencies and try again
            if(convertedPairPrice == 0)
            {
                convertedPair = GetCounterCurrency(tradingPair) + tradingCurrency;       
                convertedPairPrice = (tradeDirection == "LONG") ? MarketInfo(convertedPair, MODE_BID) : MarketInfo(convertedPair, MODE_ASK);
               
                lots = valuePerPip / convertedPairPrice / 10;
                //No need to secure from JPY pairs, because there is never JPY as a base currency
                return lots;
            }

            lots = valuePerPip * convertedPairPrice / 10;
            return (MarketInfo(convertedPair, MODE_DIGITS) == 3) ? lots / 100 : lots;
        }        

        return 0;
    }


    private:

    //+------------------------------------------------------------------+
    //| Helpers
    //+------------------------------------------------------------------+

    string GetBaseCurrency(string tradingPair)
    {
        return SymbolInfoString(tradingPair, SYMBOL_CURRENCY_BASE);
    }

    string GetCounterCurrency(string tradingPair)
    {
        return SymbolInfoString(tradingPair, SYMBOL_CURRENCY_PROFIT);
    }

}; 


 

Kacper Górzyński #:

Hi, thank you for your response.

I had to change a code a little bit, because SymbolInfoString doesn't work on symbols, that not exist. It sounds obvious, but I tried to figure out what's wrong for quite long :D

So, InvertPair method was removed and replaced with working solution. Thanks!




hi, do you have compiled version of this script? sorry because i dont know how to do that. thx

Reason: