stevehopwoodforex.com
https://www.stevehopwoodforex.com/phpBB3/
Print view

Trading one dollar per pip lot size function
https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?t=6419
Page 1 of 1
Author:  szfxtrader [ Tue Jan 28, 2025 11:29 pm ]
Post subject:  Trading one dollar per pip lot size function

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!
Author:  szfxtrader [ Thu Jan 30, 2025 12:09 am ]
Post subject:  Re: Trading one dollar per pip lot size function

Any help?
Author:  alexi [ Wed Feb 05, 2025 5:00 am ]
Post subject:  Re: Trading one dollar per pip lot size function

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;
}

Author:  szfxtrader [ Wed Feb 05, 2025 11:19 am ]
Post subject:  Re: Trading one dollar per pip lot size function

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
Author:  szfxtrader [ Wed Feb 05, 2025 11:21 am ]
Post subject:  Re: Trading one dollar per pip lot size function

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.
Author:  szfxtrader [ Wed Feb 05, 2025 12:09 pm ]
Post subject:  Re: Trading one dollar per pip lot size function

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;
}
All times are UTC Page 1 of 1