Edgoro
Major forex pairs · Free calculator

USDCHF lot size calculator

On USD/CHF one pip is 0.0001 on 100,000 USD, so a pip is worth CHF 10 per lot, which is $12.50 at a rate of 0.80. Risking $100 with a 20-pip stop gives 0.40 lots.

Risk per trade
Position size (rounded down to 0.01 lot)
0.40 lots
Risk amount$100.00
Exact size0.4000 lots
Mini lots (0.10)4.00
Micro lots (0.01)40.0
Units40,000 USD
Value of 1 pip per lot$12.50

USD account. 1 lot = 100,000 USD; 1 pip = 0.0001. Converted to USD at the USD/CHF rate. Spread and commission not included.

The calculator opens on the worked example below: a USD account, 1% of $10,000, USD/CHF at an example rate of 0.8. Trading involves substantial risk of loss and is not suitable for every investor. Edgoro is a software tool, not a broker or financial adviser: nothing it produces is investment advice, and past or backtested performance does not guarantee future results.

What 1 pip is on USDCHF

USD/CHF is quoted in Swiss francs per dollar, so the profit of a position is counted in francs: 100,000 × 0.0001 = CHF 10 per pip per lot. A USD account converts it at the pair's own rate: CHF 10 ÷ 0.80 = $12.50.

Because the franc has traded above the dollar (USD/CHF below 1.00), a pip of USD/CHF is worth more than $10 there, and its dollar value rises as USD/CHF falls. The quote has 5 digits, so 1 pip = 10 points and MT5's tick of 0.00001 is worth CHF 1 per lot.

USDCHF pip value per lot

Value of one pip (0.0001 in price): 0.0001 × 100,000 = CHF 10 ÷ 0.8 = $12.50 per 1.00 lot, at an example USD/CHF rate of 0.8.

Position1 pip20 pips (0.0020)
1.00 lot$12.50$250.00
0.10 lot$1.25$25.00
0.01 lot$0.13$2.50

Worked example: 1% of $10,000

  1. Risk: 1% × $10,000 = $100.00.
  2. Stop: 20 pips = 0.0020 in price.
  3. Value of 1 pip per 1.00 lot: $12.50.
  4. Lot size = $100.00 ÷ (20 × $12.50) = 0.4000, rounded down to the 0.01 step: 0.40 lots.

The same 20 pips cost more on USD/CHF than on EUR/USD while the pair trades below 1.00, so the position is smaller for the same $100.

Same stop with USD/CHF at 0.90: $100.00 ÷ (20 × $11.11) = 0.45 lots.

Contract size and tick value in MT5

In MetaTrader 5, right-click USDCHF in Market Watch and choose Specification: it shows Contract size, Digits, Profit currency and the volume limits. Tick size and tick value are what MQL5 reads with SYMBOL_TRADE_TICK_SIZE and SYMBOL_TRADE_TICK_VALUE; the script below prints them for your account.

Contract size100,000 USD
Digits5 (e.g. 1.16253) at most brokers
Tick size (SYMBOL_TRADE_TICK_SIZE)0.00001
1 pip0.0001 = 10 ticks (10 MT5 points)
Profit currencyCHF
Tick value, 1.00 lot (SYMBOL_TRADE_TICK_VALUE)CHF 1.00, about $1.25 in a USD account at USD/CHF 0.8
Volume stepShown in Specification; 0.01 at most retail brokers

MQL5: lot size from a money risk

A script that sends no order: it reads the contract size, tick size, tick value and volume limits your broker sets for USDCHF, then prints the lot size that risks 1% of the balance at the stop. The stop is a price distance (0.0020), so the result is the same on 2-, 3- or 5-digit quotes. Save it as MQL5/Scripts/LotSize_USDCHF.mq5 and compile it in MetaEditor (F7): 0 errors, 0 warnings.

MQL5
//+------------------------------------------------------------------+
//| LotSize_USDCHF.mq5                                             |
//| Lot size that risks a % of the balance at a given stop distance|
//+------------------------------------------------------------------+
#property script_show_inputs

input string InpSymbol       = "USDCHF"; // Symbol, exactly as in Market Watch
input double InpRiskPercent  = 1.0;      // Risk per trade, % of balance
input double InpStopDistance = 0.0020;   // Stop-loss distance in price (0.0020 = 20 pips)

// Lots that lose about riskMoney at the stop, rounded down to the volume step.
// Returns 0 when even the minimum volume would risk more than riskMoney.
double LotsForRisk(const string symbol, const double riskMoney, const double stopDistance)
  {
   double tickSize  = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
   double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE); // 1.00 lot, one tick, account currency
   double step      = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   double minLot    = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
   double maxLot    = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
   if(tickSize <= 0.0 || tickValue <= 0.0 || step <= 0.0 || stopDistance <= 0.0)
      return 0.0;
   double lossPerLot = stopDistance / tickSize * tickValue;            // money lost by 1.00 lot at the stop
   double lots       = MathFloor(riskMoney / lossPerLot / step + 1e-9) * step;
   if(lots < minLot)
      return 0.0;
   int volumeDigits = (int)MathMax(0.0, MathCeil(-MathLog10(step) - 1e-9));
   return NormalizeDouble(MathMin(lots, maxLot), volumeDigits);
  }

void OnStart()
  {
   if(!SymbolSelect(InpSymbol, true))
     {
      PrintFormat("%s not found: use the exact name from Market Watch (some brokers add a suffix)", InpSymbol);
      return;
     }
   int    digits   = (int)SymbolInfoInteger(InpSymbol, SYMBOL_DIGITS);
   double point    = SymbolInfoDouble(InpSymbol, SYMBOL_POINT);
   double contract = SymbolInfoDouble(InpSymbol, SYMBOL_TRADE_CONTRACT_SIZE);
   double tickSize = SymbolInfoDouble(InpSymbol, SYMBOL_TRADE_TICK_SIZE);
   double tickVal  = SymbolInfoDouble(InpSymbol, SYMBOL_TRADE_TICK_VALUE);
   string currency = AccountInfoString(ACCOUNT_CURRENCY);
   double risk     = AccountInfoDouble(ACCOUNT_BALANCE) * InpRiskPercent / 100.0;
   double lots     = LotsForRisk(InpSymbol, risk, InpStopDistance);

   PrintFormat("%s: contract size %g, %d digits, tick size %s, tick value %g %s per lot",
               InpSymbol, contract, digits, DoubleToString(tickSize, digits), tickVal, currency);
   PrintFormat("Stop %s = %.0f points. Risk %.2f %s",
               DoubleToString(InpStopDistance, digits), InpStopDistance / point, risk, currency);
   if(lots > 0.0)
      PrintFormat("Lot size: %g", lots);
   else
      Print("Even the minimum volume risks more than that: widen the risk or tighten the stop");
  }

The key line is stopDistance / tickSize * tickValue: the money one lot loses at the stop, already converted to your account currency by the terminal. Dividing the risk by it and flooring to SYMBOL_VOLUME_STEP gives the volume to pass to CTrade::Buy() or CTrade::Sell().

Pine Script v6 equivalent

The same sizing on a TradingView chart, from syminfo.pointvalue (money per 1.0 of price per unit) and syminfo.mintick (the chart's tick). Checked by Edgoro Pine Check; paste it into TradingView's Pine Editor to add it to a chart.

Pine Script v6
//@version=6
indicator("USDCHF lot size for a money risk", overlay = true)

riskMoney    = input.float(100.0, "Risk per trade (account currency)", minval = 0.01)
accountCcy   = input.string("USD", "Account currency")
stopDistance = input.float(0.0020, "Stop-loss distance (price)", minval = 0.0)
contractSize = input.float(100000.0, "Units per 1.00 lot at your broker", minval = 0.0)

// One unit of the symbol gains or loses syminfo.pointvalue (in syminfo.currency) per 1.0 of price
fx          = request.currency_rate(syminfo.currency, accountCcy)
lossPerUnit = stopDistance * syminfo.pointvalue * fx
units       = lossPerUnit > 0 ? riskMoney / lossPerUnit : na
lots        = contractSize > 0 ? math.floor(units / contractSize * 100) / 100 : na

var table info = table.new(position.top_right, 2, 3, bgcolor = color.new(color.gray, 80))
if barstate.islast
    table.cell(info, 0, 0, "Stop")
    table.cell(info, 1, 0, str.tostring(stopDistance / syminfo.mintick, "#") + " ticks of " + str.tostring(syminfo.mintick))
    table.cell(info, 0, 1, "Units")
    table.cell(info, 1, 1, str.tostring(units, "#.####"))
    table.cell(info, 0, 2, "Lots (rounded down)")
    table.cell(info, 1, 2, str.tostring(lots, "#.##"))

On a TradingView forex chart, syminfo.pointvalue is 1: units is an amount of USD, and 100,000 of them make a lot. request.currency_rate() converts the CHF result into your account currency.

Common mistakes on USDCHF

  • Assuming $10 per pip. At 0.80 a pip is $12.50: a 0.50-lot position sized with $10 pips loses $125 at a 20-pip stop, not $100.
  • Franc gaps. On 15 January 2015 the Swiss National Bank dropped the 1.20 floor it had held under EUR/CHF since 2011, and franc pairs moved hundreds of pips in minutes. Stops filled far from their price: a stop limits the planned loss, not the worst case.
  • Converting with the wrong pair. USD/CHF converts at its own rate (divide by it). EUR/CHF and GBP/CHF convert francs at USD/CHF too, not at EUR/USD or GBP/USD.

Lot size sets how much a trade loses if the stop is hit at its price. It doesn't make a trade a good one, and gaps or slippage can make the loss larger. Trading involves substantial risk of loss and is not suitable for every investor. Edgoro is a software tool, not a broker or financial adviser: nothing it produces is investment advice, and past or backtested performance does not guarantee future results.

All 34 symbols

Tools and code for the same job

Want the sizing inside an Expert Advisor?

Describe your USDCHF strategy in plain English and Edgoro's MT5 EA generator writes the MQL5 Expert Advisor, with risk-based lot sizing like the script above, and compiles it in MetaEditor before you get it. Test it on a demo account: a clean build isn't proof that a strategy works.