W

WquGuru·QuantLearn

BreakoutIntermediate

London Breakout

Session-based breakout trading strategy

Historical Backtest Results

Backtesting results showing London Breakout strategy performance on major FX pairs during different market conditions.

London Breakout Trading Positions

London Breakout Trading Positions

Intraday positions showing entry points triggered by pre-London range breakouts during actual London trading hours.

Pre-London Range and Thresholds

Pre-London Range and Thresholds

Daily pre-London high/low ranges with calculated upper and lower breakout thresholds including volatility adjustments.

Strategy Performance Analysis

Strategy Performance Analysis

Performance metrics including win rate, average trade duration, and comparison with buy-and-hold across different currency pairs.

Cross-Market Information Arbitrage

London Breakout capitalizes on information flow between global FX markets across different time zones.

The strategy targets the crucial hour before London market opens (GMT 7:00-7:59), capturing overnight market sentiment.

Tokyo FX market (GMT 0:00-8:59) and London market (GMT 8:00+) are two of the world's largest FX trading centers.

The pre-London hour incorporates information from all overnight global activities, creating potential trading opportunities.

Unlike equity markets with fixed opening hours, FX markets are decentralized and operate 24/7, enabling cross-timezone arbitrage.

Price movements during this window often predict London session direction, providing early entry opportunities.

The strategy assumes that significant overnight developments will manifest as range breakouts when London traders arrive.

Mathematical Foundation

1
Upper Threshold

Upper=H7:007:59+k×σUpper = H_{7:00-7:59} + k \times \sigma

Upper breakout level based on pre-London hour high plus volatility buffer, where k is typically 0.5-1.0.

2
Lower Threshold

Lower=L7:007:59k×σLower = L_{7:00-7:59} - k \times \sigma

Lower breakout level based on pre-London hour low minus volatility buffer.

3
Volatility Estimate

σ=1n1i=1n(RiRˉ)2\sigma = \sqrt{\frac{1}{n-1} \sum_{i=1}^{n} (R_i - \bar{R})^2}

Historical volatility calculated from recent returns to determine appropriate threshold buffer.

4
Position Size

Size=Risk%EntryStopLoss×AccountValueSize = \frac{Risk\%}{|Entry - StopLoss|} \times AccountValue

Position sizing based on account risk percentage and distance to stop loss level.

Core Algorithm Implementation

The London Breakout algorithm identifies key time windows and establishes dynamic thresholds for breakout detection.

Time Zone Management

python
def london_breakout_setup(df, pre_london_start='07:00', pre_london_end='07:59'):
    """Setup London Breakout time zones and key levels"""
    df = df.copy()
    df.index = pd.to_datetime(df.index)
    
    # Filter for pre-London hour (GMT 7:00-7:59)
    df['hour'] = df.index.hour
    df['minute'] = df.index.minute
    df['time_str'] = df.index.strftime('%H:%M')
    
    # Identify pre-London session
    pre_london_mask = (
        (df['hour'] == 7) & 
        (df['minute'] >= 0) & 
        (df['minute'] <= 59)
    )
    
    df['pre_london'] = pre_london_mask
    
    return df

Establishes time zone framework and identifies the crucial pre-London trading hour (GMT 7:00-7:59).

Threshold Calculation

python
def calculate_breakout_levels(df, volatility_multiplier=0.8):
    """Calculate dynamic upper and lower breakout thresholds"""
    df = df.copy()
    
    # Calculate daily pre-London high/low
    daily_stats = df.groupby(df.index.date).agg({
        'High': lambda x: x[df.loc[x.index, 'pre_london']].max() if any(df.loc[x.index, 'pre_london']) else np.nan,
        'Low': lambda x: x[df.loc[x.index, 'pre_london']].min() if any(df.loc[x.index, 'pre_london']) else np.nan,
        'Close': 'last'
    }).dropna()
    
    # Calculate recent volatility
    daily_stats['returns'] = daily_stats['Close'].pct_change()
    daily_stats['volatility'] = daily_stats['returns'].rolling(window=20).std()
    
    # Merge back to main dataframe
    df = df.join(daily_stats[['volatility']], rsuffix='_daily')
    
    # Calculate thresholds
    df['upper_threshold'] = df.groupby(df.index.date)['High'].transform(
        lambda x: x[df.loc[x.index, 'pre_london']].max() if any(df.loc[x.index, 'pre_london']) else np.nan
    ) + volatility_multiplier * df['volatility']
    
    df['lower_threshold'] = df.groupby(df.index.date)['Low'].transform(
        lambda x: x[df.loc[x.index, 'pre_london']].min() if any(df.loc[x.index, 'pre_london']) else np.nan
    ) - volatility_multiplier * df['volatility']
    
    return df

Calculates dynamic upper and lower thresholds based on pre-London range plus volatility adjustments.

Signal Generation and Risk Management

python
def london_breakout_signals(df, max_volatility_threshold=0.02):
    """Generate trading signals with built-in risk management"""
    df = df.copy()
    df['signal'] = 0
    df['position'] = 0
    df['stop_loss'] = np.nan
    df['take_profit'] = np.nan
    
    # London trading hours (GMT 8:00-16:00)
    london_hours = (df['hour'] >= 8) & (df['hour'] <= 16)
    
    current_position = 0
    entry_price = 0
    
    for i in range(len(df)):
        if not london_hours.iloc[i]:
            continue
            
        price = df['Close'].iloc[i]
        upper = df['upper_threshold'].iloc[i]
        lower = df['lower_threshold'].iloc[i]
        vol = df['volatility'].iloc[i]
        
        # Avoid trading in extreme volatility
        if pd.notna(vol) and vol > max_volatility_threshold:
            continue
            
        # Long breakout signal
        if current_position == 0 and price > upper and pd.notna(upper):
            df.loc[df.index[i], 'signal'] = 1
            current_position = 1
            entry_price = price
            df.loc[df.index[i], 'stop_loss'] = lower
            df.loc[df.index[i], 'take_profit'] = price + 2 * (price - lower)
            
        # Short breakout signal
        elif current_position == 0 and price < lower and pd.notna(lower):
            df.loc[df.index[i], 'signal'] = -1
            current_position = -1
            entry_price = price
            df.loc[df.index[i], 'stop_loss'] = upper
            df.loc[df.index[i], 'take_profit'] = price - 2 * (upper - price)
            
        # Exit conditions
        elif current_position != 0:
            stop_loss = df['stop_loss'].iloc[i-1] if i > 0 else np.nan
            take_profit = df['take_profit'].iloc[i-1] if i > 0 else np.nan
            
            if (current_position == 1 and price <= stop_loss) or                (current_position == -1 and price >= stop_loss) or                (current_position == 1 and price >= take_profit) or                (current_position == -1 and price <= take_profit):
                df.loc[df.index[i], 'signal'] = -current_position
                current_position = 0
                
        df.loc[df.index[i], 'position'] = current_position
        
    return df

Comprehensive signal generation with volatility filters, stop-loss, and take-profit mechanisms for risk management.

Implementation Steps

  1. 1Identify FX pairs with high liquidity during London session (EUR/USD, GBP/USD, USD/CHF)
  2. 2Monitor price action during GMT 7:00-7:59 (pre-London crucial hour)
  3. 3Record high and low prices during this one-hour window
  4. 4Calculate volatility-adjusted upper and lower thresholds
  5. 5Wait for London market opening at GMT 8:00
  6. 6Execute long position if price breaks above upper threshold with sufficient volume
  7. 7Execute short position if price breaks below lower threshold
  8. 8Set stop-loss at opposite threshold level
  9. 9Set take-profit at 2:1 risk-reward ratio
  10. 10Close all positions by end of London session or at predetermined time limits

Key Metrics

Pre-London range as percentage of daily average true range
Breakout success rate during different volatility regimes
Average holding period and time to target/stop-loss
Profit factor (gross profit / gross loss)
Maximum consecutive losing trades
Correlation with major economic announcements
Performance by day of week and month

Risk Considerations

Overnight gaps can invalidate pre-calculated thresholds, especially during major news events
False breakouts are common during low-volume periods or market holidays
Central bank interventions can cause sudden reversals against breakout direction
Economic data releases during London session can override technical signals
Slippage and spread widening during volatile periods can erode profits significantly
Strategy requires precise timing and may not work well with retail broker execution speeds
Currency correlations can cause simultaneous breakouts across multiple pairs, concentrating risk

Practice Implementation

Prerequisites

Mathematical Background

  • • Linear regression and OLS estimation
  • • Time series analysis (stationarity, unit roots)
  • • Hypothesis testing and p-values
  • • Basic econometrics (error correction models)

Technical Skills

  • • Python programming (pandas, numpy)
  • • Statistical libraries (statsmodels)
  • • Data visualization (matplotlib)
  • • Financial data handling (yfinance)

Complete Implementation

Access the full Python implementation from the original quantitative trading repository:

bash
# Complete pair trading implementation
git clone https://github.com/je-suis-tm/quant-trading.git
cd quant-trading
python "Pair trading backtest.py"
# Modify tickers and parameters for your own analysis

Learning Checkpoints

1

Understand Cointegration

Can you explain why two assets might be cointegrated and what breaks this relationship?

2

Interpret Statistical Tests

Practice reading ADF test results and understanding when to accept/reject cointegration.

3

Signal Generation

Implement Z-score calculations and understand threshold selection (±1σ vs ±2σ).

4

Risk Management

Understand position sizing, monitoring regime changes, and exit strategies.

Recommended Learning Path

Immediate Actions

  • Download and run the Python script
  • Test with different asset pairs
  • Experiment with threshold parameters

Advanced Studies

  • Learn Johansen cointegration test
  • Study Vector Error Correction Models
  • Explore multiple asset pair trading

Important Disclaimer

This strategy involves significant risk. Historical cointegration relationships can break permanently. Always use proper risk management, position sizing, and never risk more than you can afford to lose. Paper trade extensively before using real capital.

Quick Navigation