IC Markets

My perspective on scalping – Forex for scaling capital, Stocks for steady cash flow

Discuss 1-minute to 15-minute price action setups, fading intraday momentum, key support/resistance zones, and proven short-term trading methodologies.
PTScalper
Site Admin
Posts: 1114
Joined: Mon Jul 20, 2026 1:28 pm

My perspective on scalping – Forex for scaling capital, Stocks for steady cash flow

Post by PTScalper »

Hi everyone,

I'd like to open a discussion here about a topic that has recently defined my approach to the markets: the difference in dynamics between Forex and Stock scalping.

After spending some time in the markets, I’ve divided my trading into two separate worlds. Each has a completely different goal and requires a different psychological approach. Here is my thought process:

📈 Forex Scalping = A Tool for Aggressive Capital Scaling
I don't see Forex as a place for "safe savings," but rather as an ideal environment for rapidly building and scaling overall capital.

Why it works: Thanks to leverage and massive liquidity (and a 24/5 market), you can build a solid account even from a smaller starting base.

The key to success: The alpha and omega here is absolutely uncompromising Money Management. Forex on lower timeframes can be treacherous and full of algorithmic noise. Without strict MM (fixed risk per trade, no widening stop-losses), leverage will eat you alive. But with it, I believe it's an unrivaled engine for growth.

🏢 Stock Scalping = Steady Growth and Monthly Income Without Leverage
While Forex is my "turbo," stocks play the role of a reliable cash generator. It's a vehicle for gradual, much more stable growth and a decent monthly income.

Why it works: I trade stocks with larger capital and strictly without leverage (1:1). Stock markets often have cleaner price action, respect trends better, and lack those crazy Forex spikes that just hunt for liquidity.

The key to success: Here, I'm not fighting for skyrocketing returns. I take a larger sum of money and "carve out" smaller, but highly probable moves from the market. Psychologically, it's a massive difference—no leverage means peace of mind. There is no risk of a margin call, and the equity curve is much smoother.

The bottom line:
I use Forex as an aggressive tool for capital growth through strict MM, while stocks are my zone for safely extracting steady monthly profits from a larger pool of money.

How about you guys? Do you view it similarly, or do you run aggressive scalping strategies on stocks too? I'd love to hear your experiences and insights. Happy trading! 🟢
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 1114
Joined: Mon Jul 20, 2026 1:28 pm

Re: My perspective on scalping – Forex for scaling capital, Stocks for steady cash flow

Post by PTScalper »

Just to add another layer to this strategy, I want to touch on the concept of exponential growth purely from profits.

When you combine strict Money Management with a high volume of scalping trades, you unlock the ability to let the math do the heavy lifting without putting your core capital on the line.

Here is how I look at it:

Protecting the Base: The initial capital deposit is just the engine starter. Once you generate that first solid profit buffer—whether from the Forex side or by funneling the steady cash flow from the Stock side—your risk profile changes entirely.

Compounding the Buffer: Instead of constantly risking your own money for aggressive growth, you start scaling your lot sizes exponentially based only on the accumulated profits.

The Hockey Stick Effect: Because scalping provides a massive number of trade executions over a short period, the compounding effect kicks in much faster than it ever could in swing trading. If you hit a drawdown, it only eats into the market’s money (your profit buffer), keeping your psychological baseline intact. But when you catch a statistical winning streak, the account equity goes parabolic.

Essentially, you are weaponizing the profits to scale exponentially, while treating your original deposit as untouchable.

Do you guys prefer to withdraw your profits at the end of every week/month to stay flat, or do you leave the profits in the account to compound and push for that exponential curve?
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 1114
Joined: Mon Jul 20, 2026 1:28 pm

Re: My perspective on scalping – Forex for scaling capital, Stocks for steady cash flow

Post by PTScalper »

Here is the chart visualizing the exact compounding concept i described for your.

This model simulates 500 scalping trades starting with a baseline capital of $1,000.

The Blue Line (Linear Growth): Represents taking a fixed profit on every trade (e.g., banking a flat $10 without adjusting your lot size). The growth is steady but slow.

The Green Line (Exponential Growth): Represents what happens when you use your profit buffer to compound (e.g., scaling your position size to always capture 1% of the current account balance).

As you can see, in the beginning, both lines look almost identical. However, right around the 200-trade mark—which a high-frequency scalper can hit relatively quickly—the math takes over and the "hockey stick" effect launches the equity curve parabolic.
Attachments
Code_Generated_Image.png
Code_Generated_Image.png (168.58 KiB) Viewed 18 times
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 1114
Joined: Mon Jul 20, 2026 1:28 pm

Re: My perspective on scalping – Forex for scaling capital, Stocks for steady cash flow

Post by PTScalper »

Here is a clean, modular Pine Script (v5) template that implements both Linear and Exponential position sizing. I have included a dropdown in the settings so you can easily toggle between the two modes during backtesting to see the exact difference on the equity curve.

I kept the entry logic to a basic moving average crossover so you can easily strip it out and plug in your own price action or scalping conditions.

💻 Pine Script (v5): Linear vs. Exponential Sizing

Code: Select all

//@version=5
strategy("Linear vs Exponential MM", overlay=true, initial_capital=1000, default_qty_type=strategy.cash)

// =========================================================================
// 1. INPUTS & SETTINGS
// =========================================================================
grp_mm = "Money Management Settings"
mm_type = input.string("Exponential", title="Sizing Model", options=["Linear", "Exponential"], group=grp_mm)

// Linear Settings
fixed_risk_usd = input.float(10.0, title="Linear: Fixed Risk (USD)", group=grp_mm, tooltip="The exact dollar amount risked per trade, regardless of account balance.")

// Exponential Settings
risk_percent = input.float(1.0, title="Exponential: Risk % per Trade", step=0.1, group=grp_mm, tooltip="Percentage of current equity to risk.") / 100

// Trade Settings
sl_pips = input.float(10.0, title="Stop Loss Distance (Pips/Ticks)", group=grp_mm)

// =========================================================================
// 2. POSITION SIZING LOGIC
// =========================================================================
// Calculate the monetary risk per single unit/share/lot based on the SL distance
sl_risk_per_unit = sl_pips * syminfo.mintick * syminfo.pointvalue

var float risk_amount = 0.0
var float position_size = 0.0

if sl_risk_per_unit > 0
    if mm_type == "Linear"
        // LINEAR: Always risk the same base amount.
        risk_amount := fixed_risk_usd
    else if mm_type == "Exponential"
        // EXPONENTIAL: Risk dynamically scales with the current equity.
        risk_amount := strategy.equity * risk_percent

    // Calculate final contract/lot quantity
    position_size := risk_amount / sl_risk_per_unit
else
    position_size := 0.0

// =========================================================================
// 3. DUMMY ENTRY LOGIC (Replace with your scalping logic)
// =========================================================================
fast_ma = ta.ema(close, 9)
slow_ma = ta.ema(close, 21)

long_cond = ta.crossover(fast_ma, slow_ma)
short_cond = ta.crossunder(fast_ma, slow_ma)

// =========================================================================
// 4. EXECUTION
// =========================================================================
if long_cond
    strategy.entry("Long", strategy.long, qty=position_size)
    strategy.exit("Exit Long", "Long", loss=sl_pips)

if short_cond
    strategy.entry("Short", strategy.short, qty=position_size)
    strategy.exit("Exit Short", "Short", loss=sl_pips)
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 1114
Joined: Mon Jul 20, 2026 1:28 pm

Re: My perspective on scalping – Forex for scaling capital, Stocks for steady cash flow

Post by PTScalper »

The Core Differences Explained
When you plug this into a high-frequency scalping environment, the math diverges drastically. Here is exactly how the mechanics differ beneath the surface:

1. Linear Money Management (Fixed Position Size)
Linear MM ignores your ongoing success or failure. If you decide to risk $10 per trade (or trade exactly 1 mini-lot), you will always trade that size, whether your account balance is $1,000 or $10,000.

The Math: Equity grows in a straight line ($10, $20, $30, $40...).

The Advantage: It is incredibly safe. It isolates your psychological baseline because the dollar amount on the line never changes. If the market conditions change and you hit a severe drawdown, the capital bleeds very slowly.

The Disadvantage: It is mathematically inefficient for scaling. You are effectively leaving money on the table by not utilizing the newly acquired capital (your profits) to generate more returns.

2. Exponential Money Management (Compounding/Fixed Fractional)

Exponential MM dynamically links your position size to your real-time account equity. If you risk 1%, a $1,000 account means a $10 risk. Once that account grows to $2,000, you are automatically risking $20.

The Math: Equity grows on a curve ($10, $10.10, $10.20, $10.30...), eventually going parabolic (the "hockey stick" effect).

The Advantage: It weaponizes your profits. By risking a percentage of the current balance, the algorithm automatically scales up your lot sizes during winning streaks without putting your original deposit at a higher proportional risk. This is the absolute fastest way to scale a smaller account.

The Disadvantage: It works in reverse, too (Asymmetrical Drawdown). If you hit a losing streak, your position sizes shrink. While this mathematically prevents you from easily blowing the account, it also means it takes much longer to climb out of a deep drawdown, because you are now trading smaller sizes with the depleted capital.

In summary: Linear is great for generating a predictable, steady cash flow (like extracting monthly income from a larger stock portfolio). Exponential is the engine for hyper-growth, relying strictly on tight, rule-based algorithmic executions to snowball the capital.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 1114
Joined: Mon Jul 20, 2026 1:28 pm

Re: My perspective on scalping – Forex for scaling capital, Stocks for steady cash flow

Post by PTScalper »

Here is a professional-grade Pine Script (v5) implementation.

To elevate this from a basic template to a robust algorithmic script suitable for high-volume scalping, I have integrated several advanced features. The most important addition is the Asymmetric Profit Compounding model, which perfectly mirrors the philosophy from your forum post: protecting the initial deposit while exponentially scaling only the generated profits.

I also added dynamic volatility (ATR) tracking for stop-losses, trading session filters, and a real-time dashboard to monitor system health.

💻 Pine Script (v5): Advanced Scalping MM Engine

Code: Select all

//@version=5
strategy("Pro MM Engine: Asymmetric Scalping", overlay=true, initial_capital=10000, default_qty_type=strategy.cash, commission_type=strategy.commission.cash_per_contract, commission_value=3.0, margin_long=100, margin_short=100)

// =========================================================================
// 1. ADVANCED INPUTS & CONFIGURATION
// =========================================================================
grp_time = "Session Filters"
trade_session = input.session("0800-1700", title="Trading Session (e.g., London/NY)", group=grp_time)
use_session = input.bool(true, title="Restrict to Session?", group=grp_time)

grp_mm = "Advanced Money Management"
mm_type = input.string("Profit Compounding (Pro)", title="Position Sizing Model", options=["Linear", "Standard Exponential", "Profit Compounding (Pro)"], group=grp_mm)

// Core Risk Parameters
base_risk_pct = input.float(1.0, title="Base Risk % (Initial Capital)", step=0.1, group=grp_mm) / 100
compound_multi = input.float(2.0, title="Profit Compound Multiplier", step=0.1, group=grp_mm, tooltip="How aggressively to compound profits (e.g., 2.0 = risk 2% of accrued profits).")
max_risk_cap = input.float(5.0, title="Hard Risk Cap % per Trade", step=0.1, group=grp_mm) / 100

grp_vol = "Volatility & Exits (ATR)"
atr_len = input.int(14, title="ATR Length", group=grp_vol)
sl_mult = input.float(1.5, title="Stop Loss (ATR Multiplier)", step=0.1, group=grp_vol)
rr_ratio = input.float(2.0, title="Risk:Reward Ratio", step=0.1, group=grp_vol)

// =========================================================================
// 2. TIME & SESSION LOGIC
// =========================================================================
in_session = not use_session or not na(time(timeframe.period, trade_session))

// =========================================================================
// 3. DYNAMIC VOLATILITY & RISK PER UNIT
// =========================================================================
// Use ATR to adjust SL distance dynamically based on current market noise
atr_val = ta.atr(atr_len)
dynamic_sl_points = atr_val * sl_mult
dynamic_tp_points = dynamic_sl_points * rr_ratio

// Calculate monetary risk per contract/lot (Point Value * SL distance)
sl_risk_per_unit = dynamic_sl_points * syminfo.pointvalue

// =========================================================================
// 4. PRO POSITION SIZING ENGINE
// =========================================================================
var float initial_balance = strategy.initial_capital
float current_equity = strategy.equity
float total_profit = math.max(0, current_equity - initial_balance) // Only count positive PnL

float risk_amount = 0.0

if mm_type == "Linear"
    // Strictly bases risk on the initial capital, ignoring all growth or drawdown
    risk_amount := initial_balance * base_risk_pct

else if mm_type == "Standard Exponential"
    // Standard compounding: Risks a flat % of the real-time equity
    risk_amount := current_equity * base_risk_pct

else if mm_type == "Profit Compounding (Pro)"
    // Asymmetric Compounding: Protects base capital, aggressive on profits
    float base_risk_amount = initial_balance * base_risk_pct
    float profit_risk_amount = total_profit * (base_risk_pct * compound_multi)
    risk_amount := base_risk_amount + profit_risk_amount

// Apply Hard Risk Cap to prevent over-leveraging during extreme spikes
float max_allowed_risk = current_equity * max_risk_cap
risk_amount := math.min(risk_amount, max_allowed_risk)

// Final Contract Sizing Calculation
float position_size = sl_risk_per_unit > 0 ? (risk_amount / sl_risk_per_unit) : 0.0

// =========================================================================
// 5. ENTRY LOGIC (Momentum / Scalping Placeholder)
// =========================================================================
// Fast momentum crossover for scalping demonstration
fast_ema = ta.ema(close, 5)
slow_ema = ta.ema(close, 13)
trend_sma = ta.sma(close, 50) // Baseline trend filter

long_cond = in_session and close > trend_sma and ta.crossover(fast_ema, slow_ema)
short_cond = in_session and close < trend_sma and ta.crossunder(fast_ema, slow_ema)

// =========================================================================
// 6. TRADE EXECUTION
// =========================================================================
if long_cond and strategy.position_size == 0
    strategy.entry("Long", strategy.long, qty=position_size)
    strategy.exit("Exit Long", "Long", loss=dynamic_sl_points / syminfo.mintick, profit=dynamic_tp_points / syminfo.mintick)

if short_cond and strategy.position_size == 0
    strategy.entry("Short", strategy.short, qty=position_size)
    strategy.exit("Exit Short", "Short", loss=dynamic_sl_points / syminfo.mintick, profit=dynamic_tp_points / syminfo.mintick)

// Close all positions at the end of the session to prevent overnight slippage
if use_session and not in_session and in_session[1]
    strategy.close_all(comment="Session Close")

// =========================================================================
// 7. REAL-TIME DASHBOARD (UI)
// =========================================================================
var table dash = table.new(position.bottom_right, 2, 4, border_width=1, border_color=color.new(color.gray, 50))

if barstate.islast
    table.cell(dash, 0, 0, "MM Mode:", text_color=color.white, bgcolor=color.new(color.black, 20))
    table.cell(dash, 1, 0, mm_type, text_color=color.yellow, bgcolor=color.new(color.black, 20))
    
    table.cell(dash, 0, 1, "Account Equity:", text_color=color.white, bgcolor=color.new(color.black, 20))
    table.cell(dash, 1, 1, str.tostring(current_equity, "#.##"), text_color=current_equity >= initial_balance ? color.green : color.red, bgcolor=color.new(color.black, 20))
    
    table.cell(dash, 0, 2, "Current Risk ($):", text_color=color.white, bgcolor=color.new(color.black, 20))
    table.cell(dash, 1, 2, str.tostring(risk_amount, "#.##"), text_color=color.white, bgcolor=color.new(color.black, 20))

    table.cell(dash, 0, 3, "Lot / Qty Size:", text_color=color.white, bgcolor=color.new(color.black, 20))
    table.cell(dash, 1, 3, str.tostring(position_size, "#.####"), text_color=color.white, bgcolor=color.new(color.black, 20))
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 1114
Joined: Mon Jul 20, 2026 1:28 pm

Re: My perspective on scalping – Forex for scaling capital, Stocks for steady cash flow

Post by PTScalper »

⚙️ Why this is the "Pro" Version

Profit Compounding (Asymmetric Risk): This script mathematically isolates your baseline capital from your generated profits. If your account is at $10,000, you trade a conservative base risk. If you grow it to $12,000, the script applies an aggressive multiplier only to the $2,000 profit buffer. This gives you the hockey-stick growth curve on winning streaks while acting as an algorithmic circuit breaker if you hit a drawdown.

Dynamic Volatility (ATR) Integration: A fixed 10-pip stop loss is a death sentence in algorithmic scalping because market volatility changes by the hour. The script calculates real-time ATR to widen the stop during fast markets and tighten it during slow chop, adjusting the lot size dynamically to keep the dollar risk exactly the same.

Hard Risk Caps: To protect the account against algorithmic black-swan events (like a sudden spread widening that creates a massive lot size calculation), there is a hard ceiling (e.g., maximum 5% risk per trade) that overrides all other math.

Session Flattening: High-volume scalpers know that holding through illiquid rollovers triggers massive slippage. The script includes logic to forcibly flatten all open positions the moment the designated trading session (e.g., London/NY overlap) ends.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 1114
Joined: Mon Jul 20, 2026 1:28 pm

Re: My perspective on scalping – Forex for scaling capital, Stocks for steady cash flow

Post by PTScalper »

Here are the complete implementations for both MetaTrader 5 (MQL5) and MetaTrader 4 (MQL4).

Both versions translate the Asymmetric Profit Compounding model directly into production-ready code, complete with dynamic ATR volatility scaling, lot-step rounding, broker constraint clamping, and a hard equity risk cap.

1. MetaTrader 5 (MQL5)

MT5 uses object-oriented trade requests via the standard library (Trade\Trade.mqh) and handles dynamic tick-size normalization natively.

Code: Select all

//+------------------------------------------------------------------+
//|                                  ProMM_AsymmetricScalping.mq5    |
//|                                  Copyright 2026                  |
//+------------------------------------------------------------------+
#property copyright "Pro MM Engine"
#property link      ""
#property version   "1.00"
#property strict

#include <Trade\Trade.mqh>
CTrade trade;

enum ENUM_MM_TYPE
{
   MM_LINEAR            = 0, // Linear (Fixed % of Initial Deposit)
   MM_EXPONENTIAL       = 1, // Standard Exponential (% of Real-time Equity)
   MM_PROFIT_COMPOUND   = 2  // Asymmetric Compounding (Accelerate on Profits)
};

//--- Inputs
input group "=== Money Management ==="
input ENUM_MM_TYPE InpMMType             = MM_PROFIT_COMPOUND; // MM Sizing Model
input double       InpBaseRiskPct        = 1.0;                 // Base Risk %
input double       InpProfitMultiplier   = 2.0;                 // Profit Compound Multiplier
input double       InpHardCapPct         = 5.0;                 // Hard Equity Risk Cap %
input double       InpManualInitDeposit  = 0.0;                 // Initial Deposit (0 = Auto-detect)

input group "=== Volatility & Exits ==="
input int          InpATRPeriod          = 14;                  // ATR Period
input double       InpATRMulSL           = 1.5;                 // SL (ATR Multiplier)
input double       InpRRRatio            = 2.0;                 // Risk:Reward Ratio

input group "=== Execution Settings ==="
input ulong        InpMagicNumber        = 987654;              // Magic Number
input ulong        InpSlippage           = 10;                  // Slippage (Points)

//--- Global Variables
double g_initial_capital = 0.0;
int    g_atr_handle      = INVALID_HANDLE;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   trade.SetExpertMagicNumber(InpMagicNumber);
   trade.SetDeviationInPoints(InpSlippage);

   // Determine starting baseline capital
   if(InpManualInitDeposit > 0.0)
      g_initial_capital = InpManualInitDeposit;
   else
      g_initial_capital = AccountInfoDouble(ACCOUNT_BALANCE);

   // Initialize ATR Indicator Handle
   g_atr_handle = iATR(_Symbol, _Period, InpATRPeriod);
   if(g_atr_handle == INVALID_HANDLE)
   {
      Print("Error creating ATR handle.");
      return(INIT_FAILED);
   }

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   if(g_atr_handle != INVALID_HANDLE)
      IndicatorRelease(g_atr_handle);
}

//+------------------------------------------------------------------+
//| Lot Normalization & Clamping Engine                              |
//+------------------------------------------------------------------+
double NormalizeVolume(double volume)
{
   double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
   double min  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double max  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);

   if(step <= 0.0) return 0.0;

   // Round down to closest valid broker step
   double normalized = MathFloor(volume / step) * step;

   if(normalized < min) return 0.0; // Risk capacity below minimum lot
   if(normalized > max) normalized = max;

   int precision = 0;
   if(step == 0.1) precision = 1;
   else if(step == 0.01) precision = 2;
   else if(step == 0.001) precision = 3;

   return NormalizeDouble(normalized, precision);
}

//+------------------------------------------------------------------+
//| Dynamic Position Size Calculator                                 |
//+------------------------------------------------------------------+
double CalculateLots(double sl_distance_points)
{
   if(sl_distance_points <= 0.0) return 0.0;

   double equity  = AccountInfoDouble(ACCOUNT_EQUITY);
   double profits = MathMax(0.0, equity - g_initial_capital);
   double target_risk = 0.0;

   // 1. Calculate target risk capital ($)
   switch(InpMMType)
   {
      case MM_LINEAR:
         target_risk = g_initial_capital * (InpBaseRiskPct / 100.0);
         break;

      case MM_EXPONENTIAL:
         target_risk = equity * (InpBaseRiskPct / 100.0);
         break;

      case MM_PROFIT_COMPOUND:
      {
         double base_risk   = g_initial_capital * (InpBaseRiskPct / 100.0);
         double profit_risk = profits * ((InpBaseRiskPct * InpProfitMultiplier) / 100.0);
         target_risk = base_risk + profit_risk;
         break;
      }
   }

   // 2. Apply Hard Equity Risk Cap
   double max_risk_allowed = equity * (InpHardCapPct / 100.0);
   if(target_risk > max_risk_allowed)
      target_risk = max_risk_allowed;

   // 3. Calculate monetary loss per single lot
   double tick_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
   double tick_size  = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);

   if(tick_size <= 0.0 || tick_value <= 0.0) return 0.0;

   double point_value        = tick_value * (_Point / tick_size);
   double loss_per_unit_lot  = sl_distance_points * point_value;

   if(loss_per_unit_lot <= 0.0) return 0.0;

   return NormalizeVolume(target_risk / loss_per_unit_lot);
}

//+------------------------------------------------------------------+
//| Execution Wrapper                                                |
//+------------------------------------------------------------------+
void ExecuteTrade(ENUM_ORDER_TYPE order_type)
{
   // Query current ATR
   double atr[1];
   if(CopyBuffer(g_atr_handle, 0, 1, 1, atr) <= 0) return;

   double sl_distance = atr[0] * InpATRMulSL;
   double sl_points   = sl_distance / _Point;
   double tp_distance = sl_distance * InpRRRatio;

   double volume = CalculateLots(sl_points);
   if(volume <= 0.0)
   {
      Print("Calculated volume is insufficient for minimum lot requirements.");
      return;
   }

   double price = (order_type == ORDER_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) 
                                                 : SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double sl    = (order_type == ORDER_TYPE_BUY) ? (price - sl_distance) 
                                                 : (price + sl_distance);
   double tp    = (order_type == ORDER_TYPE_BUY) ? (price + tp_distance) 
                                                 : (price - tp_distance);

   trade.PositionOpen(_Symbol, order_type, volume, price, sl, tp, "Pro MM Execution");
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // Place your entry signal logic here
   // Example: if(SignalBuy && PositionsTotal() == 0) ExecuteTrade(ORDER_TYPE_BUY);
}
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 1114
Joined: Mon Jul 20, 2026 1:28 pm

Re: My perspective on scalping – Forex for scaling capital, Stocks for steady cash flow

Post by PTScalper »

2. MetaTrader 4 (MQL4)

MT4 uses procedural execution calls (OrderSend) and relies on MarketInfo() to evaluate tick metrics and step sizes.

Code: Select all

//+------------------------------------------------------------------+
//|                                  ProMM_AsymmetricScalping.mq4    |
//|                                  Copyright 2026                  |
//+------------------------------------------------------------------+
#property copyright "Pro MM Engine"
#property link      ""
#property version   "1.00"
#property strict

enum ENUM_MM_TYPE
{
   MM_LINEAR            = 0, // Linear (Fixed % of Initial Deposit)
   MM_EXPONENTIAL       = 1, // Standard Exponential (% of Real-time Equity)
   MM_PROFIT_COMPOUND   = 2  // Asymmetric Compounding (Accelerate on Profits)
};

//--- Inputs
extern string       _s0                   = "=== Money Management ===";
extern ENUM_MM_TYPE InpMMType             = MM_PROFIT_COMPOUND; 
extern double       InpBaseRiskPct        = 1.0;                 
extern double       InpProfitMultiplier   = 2.0;                 
extern double       InpHardCapPct         = 5.0;                 
extern double       InpManualInitDeposit  = 0.0; // 0 = Auto-detect

extern string       _s1                   = "=== Volatility & Exits ===";
extern int          InpATRPeriod          = 14;                  
extern double       InpATRMulSL           = 1.5;                 
extern double       InpRRRatio            = 2.0;                 

extern string       _s2                   = "=== Execution Settings ===";
extern int          InpMagicNumber        = 987654;              
extern int          InpSlippage           = 3;                   

//--- Global Variables
double g_initial_capital = 0.0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   if(InpManualInitDeposit > 0.0)
      g_initial_capital = InpManualInitDeposit;
   else
      g_initial_capital = AccountBalance();

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Lot Normalization & Clamping Engine                              |
//+------------------------------------------------------------------+
double NormalizeVolume(double volume)
{
   double step = MarketInfo(Symbol(), MODE_LOTSTEP);
   double min  = MarketInfo(Symbol(), MODE_MINLOT);
   double max  = MarketInfo(Symbol(), MODE_MAXLOT);

   if(step <= 0.0) return 0.0;

   // Truncate to nearest valid broker step
   double normalized = MathFloor(volume / step) * step;

   if(normalized < min) return 0.0; 
   if(normalized > max) normalized = max;

   int precision = 2;
   if(step == 0.1) precision = 1;
   else if(step == 0.01) precision = 2;
   else if(step == 0.001) precision = 3;

   return NormalizeDouble(normalized, precision);
}

//+------------------------------------------------------------------+
//| Dynamic Position Size Calculator                                 |
//+------------------------------------------------------------------+
double CalculateLots(double sl_distance_points)
{
   if(sl_distance_points <= 0.0) return 0.0;

   double equity  = AccountEquity();
   double profits = MathMax(0.0, equity - g_initial_capital);
   double target_risk = 0.0;

   // 1. Calculate target risk capital ($)
   switch(InpMMType)
   {
      case MM_LINEAR:
         target_risk = g_initial_capital * (InpBaseRiskPct / 100.0);
         break;

      case MM_EXPONENTIAL:
         target_risk = equity * (InpBaseRiskPct / 100.0);
         break;

      case MM_PROFIT_COMPOUND:
      {
         double base_risk   = g_initial_capital * (InpBaseRiskPct / 100.0);
         double profit_risk = profits * ((InpBaseRiskPct * InpProfitMultiplier) / 100.0);
         target_risk = base_risk + profit_risk;
         break;
      }
   }

   // 2. Apply Hard Equity Risk Cap
   double max_risk_allowed = equity * (InpHardCapPct / 100.0);
   if(target_risk > max_risk_allowed)
      target_risk = max_risk_allowed;

   // 3. Calculate monetary loss per single lot
   double tick_value = MarketInfo(Symbol(), MODE_TICKVALUE);
   double tick_size  = MarketInfo(Symbol(), MODE_TICKSIZE);

   if(tick_size <= 0.0 || tick_value <= 0.0) return 0.0;

   double point_value       = tick_value * (Point / tick_size);
   double loss_per_unit_lot = sl_distance_points * point_value;

   if(loss_per_unit_lot <= 0.0) return 0.0;

   return NormalizeVolume(target_risk / loss_per_unit_lot);
}

//+------------------------------------------------------------------+
//| Execution Wrapper                                                |
//+------------------------------------------------------------------+
void ExecuteTrade(int cmd)
{
   double atr_val     = iATR(Symbol(), 0, InpATRPeriod, 1);
   double sl_distance = atr_val * InpATRMulSL;
   double sl_points   = sl_distance / Point;
   double tp_distance = sl_distance * InpRRRatio;

   double volume = CalculateLots(sl_points);
   if(volume <= 0.0)
   {
      Print("Calculated volume is below minimum lot capacity.");
      return;
   }

   double price = (cmd == OP_BUY) ? Ask : Bid;
   double sl    = (cmd == OP_BUY) ? (price - sl_distance) : (price + sl_distance);
   double tp    = (cmd == OP_BUY) ? (price + tp_distance) : (price - tp_distance);

   color trade_color = (cmd == OP_BUY) ? clrGreen : clrRed;
   int ticket = OrderSend(Symbol(), cmd, volume, price, InpSlippage, sl, tp, "Pro MM Scalp", InpMagicNumber, 0, trade_color);

   if(ticket < 0)
      Print("OrderSend failed with error: ", GetLastError());
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // Place your entry signal logic here
   // Example: if(SignalBuy && OrdersTotal() == 0) ExecuteTrade(OP_BUY);
}
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 1114
Joined: Mon Jul 20, 2026 1:28 pm

Re: My perspective on scalping – Forex for scaling capital, Stocks for steady cash flow

Post by PTScalper »

Key Architectural Safeguards in Both Implementations

Broker Step Truncation (MathFloor):
Standard mathematical rounding can round a volume of 1.055 up to 1.06. If your broker's lot step is strictly 0.05, an order of 1.06 triggers an ERR_INVALID_STOPS or TRADE_RETCODE_INVALID_VOLUME error. The NormalizeVolume() function truncates downward to preserve strict risk bounds and match broker step quantization.

Tick Size vs. Point Discrepancies: Instruments like CFDs or metals frequently exhibit non-1.0 ratios between point size and minimum tick step.

The Profit Circuit Breaker: In both scripts, profits = MathMax(0.0, equity - g_initial_capital) prevents the algorithm from penalizing you with negative lot sizes during drawdowns. If the account drops below your initial starting capital, the script automatically drops back to base-risk calculations until the baseline is recovered.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Post Reply