Trading the Breaking

Trading the Breaking

Share this post

Trading the Breaking
Trading the Breaking
[WITH CODE] RiskOps: Improving MAE/MFE
Alpha Lab

[WITH CODE] RiskOps: Improving MAE/MFE

A methodical approach to trading with peaks, valleys, and robust models

𝚀𝚞𝚊𝚗𝚝 𝙱𝚎𝚌𝚔𝚖𝚊𝚗's avatar
𝚀𝚞𝚊𝚗𝚝 𝙱𝚎𝚌𝚔𝚖𝚊𝚗
Feb 15, 2025
∙ Paid
13

Share this post

Trading the Breaking
Trading the Breaking
[WITH CODE] RiskOps: Improving MAE/MFE
2
Share

Table of contents:

  1. Introduction.

  2. The problem with MAE/MFE.

  3. An alternative to finding the optimal target value.

    1. Step 1 - Identify peaks and bottoms.

    2. Step 2: Calculate differences.

    3. Step 3 - RANSAC

  4. The exit strategy based on partial exists.


Introduction

Once upon a time, in the enchanted land of Data Science, there existed two popular wizards: Maximum Adverse Excursion and Maximum Favorable Excursion. These magical tools helped traders and engineers measure the extreme ups and downs of their trades. Think of them as the superhero gadgets of financial risk management—capable of measuring how far a price could fall—or rise—during a trade. But alas, like picky eaters who only relish a specific flavor, MAE and MFE insist that all data must be normal, resembling a perfect bell curve.

Imagine you’re measuring the heights of children in a class, and suddenly one kid shows up on stilts! The bell curve gets all confused, and our MAE/MFE tools cry, this isn’t normal! Abort mission! And so, our adventure begins: How do we deal with data that is more like a squashed cupcake or a rollercoaster ride than a neat, bell-shaped curve?

The problem with MAE/MFE

MAE and MFE have long been the darlings of traders who assume that price movements follow a bell-shaped normal distribution. In mathematical terms, when we say a variable X is normally distributed, we mean its probability density function is given by

\(f(x) = \frac{1}{\sqrt{2\pi\sigma^2}} \exp \left( -\frac{(x - \mu)^2}{2\sigma^2} \right) \)

where μ is the mean and σ is the standard deviation. This formula looks elegant and symmetric, much like a well-baked cake.

However, market data is messy. Prices can be influenced by countless unpredictable factors, leading to distributions that are skewed and heavy-tailed. Under these conditions, MAE and MFE—tools that rely on the assumption of normality— give misleading signals.

Let’s examine the MAE. For a trade, we define:

\(\text{MAE} = \max \{ P_{\text{peak}} - P_{\text{trough}} \}, \)

where Ppeak is a local maximum—a peak—and Ptrought​ is the subsequent local minimum—a valley.

Under the assumption of normality, we expect the differences Ppeak−Ptrought to be symmetrically distributed about a central value. But when the data is non-normal, extreme values—outliers—may distort this picture, making MAE and MFE unreliable.

Thus, we require an approach that does not rely on the data being normal—a method that can handle irregularities with the grace of a superhero dodging meteors.

An alternative to finding the optimal target value

To tackle the problem of non-normal data, we propose an approach that is both intuitive and mathematically robust. Our method consists of three key steps:

Step 1 - Identify peaks and bottoms:

Imagine you’re hiking in the mountains: the peaks represent the highest points, and the valleys are the lowest dips. In our mathematical frame, peaks correspond to local maxima and valleys to local minima.

A peak is identified when the derivative—the slope—of the function changes sign from positive to negative. Mathematically, if f(x) is our function, then a point x=x0​ is a local maximum or peak if:

\(f'(x_0) = 0 \quad \text{and} \quad f''(x_0) < 0. \)

Similarly, a valley is found when:

\(f'(x_0) = 0 \quad \text{and} \quad f''(x_0) > 0. \)

This is like saying: If the hill stops rising and starts falling, you’re at a peak! And if it stops falling and starts rising, you’re at a valley! Pretty neat, right?

Let’s see how we can implement this idea. Consider the following code fragment, keeping in mind that it is only used to label or to use as a basis as an approximation for this type of methods, never to give input or output signals:

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import find_peaks

# Simulate stock price data
np.random.seed(42)
time = np.arange(50)  # Time steps
stock_price = np.cumsum(np.random.randn(50)) + 100  # Random walk around 100

# Find peaks (local maxima)
peaks, _ = find_peaks(stock_price)

# Find bottoms (local minima)
bottoms, _ = find_peaks(-stock_price)

# Plot the stock price with peaks and bottoms
plt.figure(figsize=(10, 5))
plt.plot(time, stock_price, label="Stock Price", linestyle="-", marker="o", markersize=4)
plt.scatter(time[peaks], stock_price[peaks], color="red", label="Peaks", zorder=3)
plt.scatter(time[bottoms], stock_price[bottoms], color="blue", label="Bottoms", zorder=3)
plt.xlabel("Time")
plt.ylabel("Stock Price")
plt.title("Simulated Stock Price with Peaks and Bottoms")
plt.legend()
plt.grid()

# Show the chart
plt.show()

The find_peaks function locates positions in the data array where a peak occurs. To find valleys, we simply invert the data—multiply by -1—and then find the peaks of this inverted series.

This post is for paid subscribers

Already a paid subscriber? Sign in
© 2025 Quant Beckman
Privacy ∙ Terms ∙ Collection notice
Start writingGet the app
Substack is the home for great culture

Share