Trading one dollar per pip lot size function

Post Reply
szfxtrader
Trader
Posts: 377
Joined: Sun Feb 10, 2013 9:36 am

Trading one dollar per pip lot size function

Post by szfxtrader »

Code: Select all

input double DollarPerPip = 1;

double LotSize(string sym) {
   // Retrieve minimum, maximum, and step size for lot calculation
   double minLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MIN);
   double maxLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MAX);
   double lotStep = SymbolInfoDouble(sym, SYMBOL_VOLUME_STEP);

   // Ensure SymbolInfoDouble() calls succeeded
   if (minLot <= 0 || maxLot <= 0 || lotStep <= 0) {
      Print("Error retrieving lot size information for symbol: ", sym);
      return 0;
   }
   
   // Retrieve symbol properties
   double tickSize = SymbolInfoDouble(sym, SYMBOL_TRADE_TICK_SIZE);    // Minimum price movement
   double tickValue = SymbolInfoDouble(sym, SYMBOL_TRADE_TICK_VALUE); // Value of the tick size
   double contractSize = SymbolInfoDouble(sym, SYMBOL_TRADE_CONTRACT_SIZE); // Contract size

   // Validate retrieved values
   if (tickSize <= 0 || tickValue <= 0 || contractSize <= 0) {
      Print("Error retrieving symbol properties for: ", sym);
      return 0;
   }

   // Ensure DollarPerPip is valid
   if (DollarPerPip <= 0) {
      Print("Invalid DollarPerPip value: ", DollarPerPip);
      return 0;
   }

   // Calculate pip value for 1 lot
   double pipValue = (tickValue / tickSize);

   // Calculate the required lot size to achieve DollarPerPip
   double lot = DollarPerPip / pipValue;

   // Normalize lot size to the nearest step size
   lot = NormalizeDouble(MathFloor(lot / lotStep) * lotStep, (int) SymbolInfoInteger(sym, SYMBOL_DIGITS));
   Print("Normalized lot size: ", lot);
   
   // Ensure the lot size is within the allowable range
   if (lot < minLot) lot = minLot;
   if (lot > maxLot) lot = maxLot;

   return lot;
}
I am trying to trade one dollar per pip on any symbol. I've tried the function with EURUSD, and it is returning a wrong lot size(0.01). Please help me fix the function, thank you very much!
szfxtrader
Trader
Posts: 377
Joined: Sun Feb 10, 2013 9:36 am

Re: Trading one dollar per pip lot size function

Post by szfxtrader »

Any help?
alexi
Posts: 1
Joined: Sat Jan 28, 2023 5:51 am

Re: Trading one dollar per pip lot size function

Post by alexi »

Try this:

Code: Select all

input double DollarPerPip = 1;  // Risk amount in USD per pip

double LotSize(string sym) {
    // Retrieve lot size constraints
    double minLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MIN);
    double maxLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MAX);
    double lotStep = SymbolInfoDouble(sym, SYMBOL_VOLUME_STEP);
    
    // Validate lot constraints
    if(minLot <= 0 || maxLot <= 0 || lotStep <= 0) {
        Print("Error: Invalid lot size constraints for ", sym);
        return 0;
    }

    // Get contract size (standard = 100000)
    double contractSize = SymbolInfoDouble(sym, SYMBOL_TRADE_CONTRACT_SIZE);
    if(contractSize <= 0) {
        Print("Error: Invalid contract size for ", sym);
        return 0;
    }

    // Determine pip definition (0.01 for JPY pairs)
    bool isJPY = StringFind(sym, "JPY") != -1;
    double pipDefinition = isJPY ? 0.01 : 0.0001;

    // Extract quote currency (3rd-5th characters, e.g., "USD" from "EURUSD")
    string quoteCurrency = StringSubstr(sym, 3, 3);
    
    // Get quote currency to USD rate
    string quoteSymbol = quoteCurrency + "USD";
    double quoteToUSDRate = SymbolInfoDouble(quoteSymbol, SYMBOL_BID);
    
    // Handle inverse pairs if direct rate unavailable (e.g., CHF, SGD)
    if(quoteToUSDRate <= 0) {
        string inverseSymbol = "USD" + quoteCurrency;
        double inverseRate = SymbolInfoDouble(inverseSymbol, SYMBOL_BID);
        if(inverseRate > 0) {
            quoteToUSDRate = 1.0 / inverseRate;
        } else {
            Print("Error: Failed to get exchange rate for ", quoteCurrency);
            return 0;
        }
    }

    // Calculate pip value in USD for 1 standard lot
    double pipValue = contractSize * pipDefinition * quoteToUSDRate;
    if(pipValue <= 0) {
        Print("Error: Invalid pip value calculation for ", sym);
        return 0;
    }

    // Calculate required lot size
    double lot = DollarPerPip / pipValue;
    
    // Normalize to broker's lot step size
    lot = MathFloor(lot / lotStep) * lotStep;
    
    // Apply broker constraints
    lot = MathMin(MathMax(lot, minLot), maxLot);

    // Debugging information
    Print("Symbol: ", sym, 
          " | Pip Value: ", pipValue, 
          " | Raw Lot: ", DollarPerPip / pipValue, 
          " | Final Lot: ", lot);

    return lot;
}

Last edited by alexi on Wed Feb 05, 2025 5:39 am, edited 1 time in total.
szfxtrader
Trader
Posts: 377
Joined: Sun Feb 10, 2013 9:36 am

Re: Trading one dollar per pip lot size function

Post by szfxtrader »

SteveHopwood wrote: Sat Feb 01, 2025 9:41 pm In all the time that this forum has existed, nobody has come up with a solution to this in code.

Maybe it is possible but nobody has offered one.

Good luck in trying to find yours.

:xm: :rocket:
Mission impossible : D
szfxtrader
Trader
Posts: 377
Joined: Sun Feb 10, 2013 9:36 am

Re: Trading one dollar per pip lot size function

Post by szfxtrader »

alexi wrote: Wed Feb 05, 2025 5:00 am Try this:

Code: Select all

input double DollarPerPip = 1;  // Risk amount in USD per pip

double LotSize(string sym) {
    // Retrieve lot size constraints
    double minLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MIN);
    double maxLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MAX);
    double lotStep = SymbolInfoDouble(sym, SYMBOL_VOLUME_STEP);
    
    // Validate lot constraints
    if(minLot <= 0 || maxLot <= 0 || lotStep <= 0) {
        Print("Error: Invalid lot size constraints for ", sym);
        return 0;
    }

    // Get contract size (standard = 100000)
    double contractSize = SymbolInfoDouble(sym, SYMBOL_TRADE_CONTRACT_SIZE);
    if(contractSize <= 0) {
        Print("Error: Invalid contract size for ", sym);
        return 0;
    }

    // Determine pip definition (0.01 for JPY pairs)
    bool isJPY = StringFind(sym, "JPY") != -1;
    double pipDefinition = isJPY ? 0.01 : 0.0001;

    // Extract quote currency (3rd-5th characters, e.g., "USD" from "EURUSD")
    string quoteCurrency = StringSubstr(sym, 3, 3);
    
    // Get quote currency to USD rate
    string quoteSymbol = quoteCurrency + "USD";
    double quoteToUSDRate = SymbolInfoDouble(quoteSymbol, SYMBOL_BID);
    
    // Handle inverse pairs if direct rate unavailable (e.g., CHF, SGD)
    if(quoteToUSDRate <= 0) {
        string inverseSymbol = "USD" + quoteCurrency;
        double inverseRate = SymbolInfoDouble(inverseSymbol, SYMBOL_BID);
        if(inverseRate > 0) {
            quoteToUSDRate = 1.0 / inverseRate;
        } else {
            Print("Error: Failed to get exchange rate for ", quoteCurrency);
            return 0;
        }
    }

    // Calculate pip value in USD for 1 standard lot
    double pipValue = contractSize * pipDefinition * quoteToUSDRate;
    if(pipValue <= 0) {
        Print("Error: Invalid pip value calculation for ", sym);
        return 0;
    }

    // Calculate required lot size
    double lot = DollarPerPip / pipValue;
    
    // Normalize to broker's lot step size
    lot = MathFloor(lot / lotStep) * lotStep;
    
    // Apply broker constraints
    lot = MathMin(MathMax(lot, minLot), maxLot);

    // Debugging information
    Print("Symbol: ", sym, 
          " | Pip Value: ", pipValue, 
          " | Raw Lot: ", DollarPerPip / pipValue, 
          " | Final Lot: ", lot);

    return lot;
}

Thank you very much, from 36 symbols, it is not working just for AUDUSD, EURUSD, GBPUSD and NZDUSD, but an AI has fix it, please check the next post.
You do not have the required permissions to view the files attached to this post.
szfxtrader
Trader
Posts: 377
Joined: Sun Feb 10, 2013 9:36 am

Re: Trading one dollar per pip lot size function

Post by szfxtrader »

Code: Select all

input double DollarPerPip = 1;

double LotSize(string sym) {
   // Retrieve lot and contract constraints
   double minLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MIN);
   double maxLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MAX);
   double lotStep = SymbolInfoDouble(sym, SYMBOL_VOLUME_STEP);
   double contractSize = SymbolInfoDouble(sym, SYMBOL_TRADE_CONTRACT_SIZE);

   // Validate lot and contract constraints
   if (minLot <= 0 || maxLot <= 0 || lotStep <= 0 || contractSize <= 0) {
      Alert("Invalid lot or contract for ", sym);
      return 0;
   }

   // Determine pip definition
   double pipValue = (StringFind(sym, "JPY") != -1) ? 0.01 : 0.0001;

   // Get Quote Currency and conversion rate to USD (Improved)
   string quoteCurrency = StringSubstr(sym, 3, 3);
   double quoteToUSDRate = 1.0;

   if (quoteCurrency != "USD") {
      string conversionSymbol = (quoteCurrency + "USD"); // Try direct conversion first
      if (!SymbolSelect(conversionSymbol, true)) {
         conversionSymbol = ("USD" + quoteCurrency); // Then try inverse
         if (!SymbolSelect(conversionSymbol, true)) {
            Alert("Could not find USD conversion symbol for ", sym);
            return 0;
         } else {
            quoteToUSDRate = 1.0 / SymbolInfoDouble(conversionSymbol, SYMBOL_BID);
         }
      } else {
         quoteToUSDRate = SymbolInfoDouble(conversionSymbol, SYMBOL_BID);
      }
   }

   if (quoteToUSDRate <= 0) {
      Alert("Failed to get exchange rate for ", sym);
      return 0;
   }

   // Calculate pip value in USD for 1 standard lot (using pipValue calculated above)
   pipValue *= contractSize * quoteToUSDRate;

   if (pipValue <= 0) {
      Alert("Invalid pip value calculation for ", sym);
      return 0;
   }

   // Calculate lot size and normalize (using DollarPerPip from parameter)
   double lot = NormalizeDouble(MathRound((DollarPerPip / pipValue) / lotStep) * lotStep, 2);

   // Apply broker constraints
   lot = MathMin(MathMax(lot, minLot), maxLot);

   return lot;
}
Post Reply

Return to “MQ5 Nuggets for the Dauntless”