<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Momentum &#8211; The Financial Hacker</title>
	<atom:link href="https://financial-hacker.com/tag/trend/feed/" rel="self" type="application/rss+xml" />
	<link>https://financial-hacker.com</link>
	<description>A new view on algorithmic trading</description>
	<lastBuildDate>Sun, 13 Apr 2025 06:24:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://financial-hacker.com/wp-content/uploads/2017/07/cropped-mask-32x32.jpg</url>
	<title>Momentum &#8211; The Financial Hacker</title>
	<link>https://financial-hacker.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Trading the Channel</title>
		<link>https://financial-hacker.com/trading-the-channel/</link>
					<comments>https://financial-hacker.com/trading-the-channel/#comments</comments>
		
		<dc:creator><![CDATA[Petra Volkova]]></dc:creator>
		<pubDate>Wed, 09 Apr 2025 12:14:55 +0000</pubDate>
				<category><![CDATA[Indicators]]></category>
		<category><![CDATA[Petra on Programming]]></category>
		<category><![CDATA[System Development]]></category>
		<category><![CDATA[Channels]]></category>
		<category><![CDATA[Kaufman]]></category>
		<category><![CDATA[Momentum]]></category>
		<category><![CDATA[Regression]]></category>
		<guid isPermaLink="false">https://financial-hacker.com/?p=4834</guid>

					<description><![CDATA[One of the simplest form of trend trading opens positions when the price crosses its moving average, and closes or reverses them when the price crosses back. In the latest TASC issue, Perry Kaufman suggested an alternative. He is using a linear regression line with an upper and lower band for trend trading. Such a &#8230; <a href="https://financial-hacker.com/trading-the-channel/" class="more-link">Continue reading<span class="screen-reader-text"> "Trading the Channel"</span></a>]]></description>
										<content:encoded><![CDATA[<p><em>One of the simplest form of trend trading opens positions when the price crosses its moving average, and closes or reverses them when the price crosses back. In the latest TASC issue, <strong>Perry Kaufman</strong> suggested an alternative. He is using a linear regression line with an upper and lower band for trend trading. Such a band indicator can be used to trigger long or short positions when the price crosses the upper or lower band, or when it gets close.</em><span id="more-4834"></span></p>
<p>Let’s first code the bands. They are simply a regression line moved up or down so that it crosses through the highest and lowest price peaks and valleys. Here’s the piece of code in C:</p>
<pre class="prettyprint">var Slope = LinearRegSlope(seriesC(),N);
var Intercept = LinearRegIntercept(seriesC(),N);
var LinVal, HighDev = 0, LowDev = 0;
for(i=N; i&gt;0; i--) {
  LinVal = Intercept + Slope*(N-i);
  HighDev = max(HighDev,priceC(i)-LinVal);
  LowDev = min(LowDev,priceC(i)-LinVal);
}</pre>
<p><strong>N</strong> is the number of bars for which the regression line is calculated. The line has the formula <strong>y = b + m*x</strong>, where <strong>b</strong> is the intercept and <strong>m</strong> the slope. The code generates both for the previous <strong>N</strong> bars, then calculates in the loop the maximum and minimum deviations (<strong>HighDev</strong>, <strong>LowDev</strong>). The regression value (<strong>LinVal</strong>) is calculated from the intercept and slope with the above formula. Since the bar offset <strong>i</strong> runs backwards from the current bar, the bar number that’s multiplied with the slope runs from <strong>N</strong> down to <strong>0</strong>. Here’s the code applied to a SPY chart from 2025:</p>
<p><strong><img fetchpriority="high" decoding="async" width="701" height="405" class="wp-image-4835" src="https://financial-hacker.com/wp-content/uploads/2025/04/ein-bild-das-diagramm-text-reihe-screenshot-en.png" srcset="https://financial-hacker.com/wp-content/uploads/2025/04/ein-bild-das-diagramm-text-reihe-screenshot-en.png 701w, https://financial-hacker.com/wp-content/uploads/2025/04/ein-bild-das-diagramm-text-reihe-screenshot-en-300x173.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></strong></p>
<p>The candles can exceed the upper and lower bands because only the close price is used for the bands. It would probably improve the system, at least in theory, when we used the high and low prices instead.</p>
<p>Kaufman suggests several methods of trading with these bands; we’re here using the ‘Inside Channel’ method since it is, according to Kaufman, the most profitable. We open a long position when the price comes within a zone around the lower band, and close the position (or open a short position) when the price comes within a zone around the upper band. Here’s the complete trading system in C for Zorro, using the above code to calculate the bands.</p>
<pre class="prettyprint">void run()
{
  BarPeriod = 1440;
  StartDate = 20100101;
  LookBack = 150;
  assetList("AssetsIB");
  asset("SPY");
  if(is(LOOKBACK)) return;

  int i, N = 40;
  var Factor = 0.2;
  var Slope = LinearRegSlope(seriesC(),N);
  var Intercept = LinearRegIntercept(seriesC(),N);
  var LinVal, HighDev = 0, LowDev = 0;
  for(i=N; i&gt;0; i--) {
    LinVal = Intercept + Slope*(N-i);
    HighDev = max(HighDev,priceC(i)-LinVal);
    LowDev = min(LowDev,priceC(i)-LinVal);
  }
  var Zone = Factor*(HighDev+LowDev);
  if(!NumOpenLong &amp;&amp; priceC(0) &lt; LinVal+LowDev+Zone)
    enterLong();
  if(!NumOpenShort &amp;&amp; priceC(0) &gt; LinVal+HighDev-Zone)
    exitLong();
}</pre>
<p>We’ve selected the <strong>AssetsIB</strong> asset list, which contains the margins, commissions and other parameters from an US broker (IBKR). So the backtest simulates trading with IBKR. The resulting equity curve with the default parameters, <strong>N = 40</strong> and <strong>Zone Factor = 20%</strong>, already shows promise with a 2.8 profit factor:</p>
<p><img decoding="async" width="701" height="405" class="wp-image-4836" src="https://financial-hacker.com/wp-content/uploads/2025/04/word-image-4834-2.png" srcset="https://financial-hacker.com/wp-content/uploads/2025/04/word-image-4834-2.png 701w, https://financial-hacker.com/wp-content/uploads/2025/04/word-image-4834-2-300x173.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></p>
<p>However, Kaufman mentioned that he tested <strong>N</strong> values from 20 to 150, and zone factors from 5% to 50%. We’ll do the same by optimizing these parameters. Of course a backtest with the best optimization result would be meaningless due to bias (see <a href="https://zorro-project.com/backtest.php">https://zorro-project.com/backtest.php</a>). Therefore we’re using <strong>walk forward optimization</strong> for an out-of-sample backtest. Since anything with Zorro is done in code, we’ll insert 4 lines of C code for the optimization:</p>
<pre class="prettyprint">set(PARAMETERS); // optimize parameters
NumWFOCycles = 5;
N = optimize(40,20,150,10);
Factor = optimize(0.2,0.05,0.5,0.05);</pre>
<p>We also changed the trading from only long positions to long and short by replacing <strong>exitLong</strong> with <strong>enterShort</strong> By default, entering a short position automatically exits the long one, and vice versa. So the system is always in the market with 1 share, either long or short. The walk forward optimization takes about 3 seconds. This is the resulting equity curve:</p>
<p><img decoding="async" width="701" height="405" class="wp-image-4837" src="https://financial-hacker.com/wp-content/uploads/2025/04/word-image-4834-3.png" srcset="https://financial-hacker.com/wp-content/uploads/2025/04/word-image-4834-3.png 701w, https://financial-hacker.com/wp-content/uploads/2025/04/word-image-4834-3-300x173.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></p>
<p>The profit factor rose to 7, with a 76% win rate &#8211; not bad for such a simple system. The code can be downloaded from the 2025 script repository on <a href="https://financial-hacker.com">https://financial-hacker.com</a>. </p>
]]></content:encoded>
					
					<wfw:commentRss>https://financial-hacker.com/trading-the-channel/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
		<item>
		<title>The Gap Momentum System</title>
		<link>https://financial-hacker.com/the-gap-momentum-system/</link>
					<comments>https://financial-hacker.com/the-gap-momentum-system/#comments</comments>
		
		<dc:creator><![CDATA[Petra Volkova]]></dc:creator>
		<pubDate>Fri, 15 Mar 2024 11:49:36 +0000</pubDate>
				<category><![CDATA[Indicators]]></category>
		<category><![CDATA[Petra on Programming]]></category>
		<category><![CDATA[Momentum]]></category>
		<guid isPermaLink="false">https://financial-hacker.com/?p=4701</guid>

					<description><![CDATA[Perry Kaufman, known for his technical indicators bible, presented in TASC 1/24 a trading strategy based on upwards and downwards gaps. For his system, he invented the Gap Momentum Indicator (GAPM). Here I&#8217;m publishing the C version of his indicator, and a simple trading system based on it. The indicator is a straighforward conversion of &#8230; <a href="https://financial-hacker.com/the-gap-momentum-system/" class="more-link">Continue reading<span class="screen-reader-text"> "The Gap Momentum System"</span></a>]]></description>
										<content:encoded><![CDATA[<p><em>Perry Kaufman, known for his technical indicators bible, presented in TASC 1/24 a trading strategy based on upwards and downwards gaps. For his system, he invented the Gap Momentum Indicator (GAPM). Here I&#8217;m publishing the C version of his indicator, and a simple trading system based on it.</em><span id="more-4701"></span></p>
<p>The indicator is a straighforward conversion of Kaufman&#8217;s EasyLanguage code to C:</p>
<pre class="prettyprint">var GAPM(int Period, int SignalPeriod)
{
    var UpGaps = 0, DnGaps = 0;
    int ix;
    for(ix = 0; ix &lt; Period; ix++) {
        var Gap = priceO(ix) - priceC(ix+1);
        if(Gap &gt; 0) UpGaps += Gap;
        else if(Gap &lt; 0) DnGaps -= Gap;
    }
    var GapRatio = ifelse(DnGaps == 0,1,100*UpGaps/DnGaps);
    return SMA(series(GapRatio),SignalPeriod);
}</pre>
<p>The system trades QQQ, a NASDAQ ETF. The historical data for the backtest is loaded from Yahoo. It enters a long position when upward gaps are on the rise, and closes the position otherwise. The code in C for the Zorro platform:</p>
<pre class="prettyprint">function run()
{
    StartDate = 2011;
    EndDate = 2023;
    BarPeriod = 1440;
    Fill = 3;    // trade on next open
    var Investment = 100000;
    assetAdd("QQQ","YAHOO:*");
    asset("QQQ");
    vars Signals = series(GAPM(40,20));
    if(!NumOpenLong &amp;&amp; rising(Signals))
        enterLong(Investment/priceC());
    if(NumOpenLong &amp;&amp; falling(Signals))
        exitLong();
}</pre>
<p>The resulting equity curve:</p>
<p><img decoding="async" src="https://financial-hacker.com/wp-content/uploads/2024/03/031524_1142_TheGapMomen1.png" alt="" /></p>
<p>The result is not sensational, but the system achieved a solid 12% return on investment, well above buy-and-hold, with 56% winning trades. The GAPM indicator and the trading system can be downloaded from the 2023 script repository.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://financial-hacker.com/the-gap-momentum-system/feed/</wfw:commentRss>
			<slash:comments>11</slash:comments>
		
		
			</item>
		<item>
		<title>Build Better Strategies! Part 2: Model-Based Systems</title>
		<link>https://financial-hacker.com/build-better-strategies-part-2-model-based-systems/</link>
					<comments>https://financial-hacker.com/build-better-strategies-part-2-model-based-systems/#comments</comments>
		
		<dc:creator><![CDATA[jcl]]></dc:creator>
		<pubDate>Fri, 25 Dec 2015 12:34:08 +0000</pubDate>
				<category><![CDATA[Indicators]]></category>
		<category><![CDATA[System Development]]></category>
		<category><![CDATA[Arbitrage]]></category>
		<category><![CDATA[Bandpass filter]]></category>
		<category><![CDATA[Brexit]]></category>
		<category><![CDATA[CHF]]></category>
		<category><![CDATA[Currency strength]]></category>
		<category><![CDATA[Curve patterns]]></category>
		<category><![CDATA[Cycles]]></category>
		<category><![CDATA[Earnings]]></category>
		<category><![CDATA[Ehlers]]></category>
		<category><![CDATA[Fisher transformation]]></category>
		<category><![CDATA[Frechet algorithm]]></category>
		<category><![CDATA[Gap]]></category>
		<category><![CDATA[Heteroskedasticity]]></category>
		<category><![CDATA[Hurst exponent]]></category>
		<category><![CDATA[Market Meanness Index]]></category>
		<category><![CDATA[Mean Reversion]]></category>
		<category><![CDATA[Momentum]]></category>
		<category><![CDATA[Price shock]]></category>
		<category><![CDATA[Seasonality]]></category>
		<category><![CDATA[Spectral filter]]></category>
		<category><![CDATA[Support and resistance]]></category>
		<guid isPermaLink="false">http://www.financial-hacker.com/?p=318</guid>

					<description><![CDATA[Trading systems come in two flavors: model-based and data-mining. This article deals with model based strategies. Even when the basic algorithms are not complex, properly developing them has its difficulties and pitfalls (otherwise anyone would be doing it). A significant market inefficiency gives a system only a relatively small edge. Any little mistake can turn &#8230; <a href="https://financial-hacker.com/build-better-strategies-part-2-model-based-systems/" class="more-link">Continue reading<span class="screen-reader-text"> "Build Better Strategies! Part 2: Model-Based Systems"</span></a>]]></description>
										<content:encoded><![CDATA[<p>Trading systems come in two flavors: <strong>model-based</strong> and <strong>data-mining</strong>. This article deals with model based strategies. Even when the basic algorithms are not complex, properly developing them has its difficulties and pitfalls (otherwise anyone would be doing it). A significant market inefficiency gives a system only a <strong>relatively small edge</strong>. Any little mistake can turn a winning strategy into a losing one. And you will not necessarily notice this in the backtest. <span id="more-318"></span></p>
<p>Developing a model-based strategy begins with the <strong>market inefficiency</strong> that you want to exploit. The inefficiency produces a <strong>price anomaly</strong> or <strong>price pattern</strong> that you can describe with a qualitative or quantitative <strong>model</strong>. Such a model predicts the current price <em><strong>y<sub>t</sub></strong></em> from the previous price <em><strong>y<sub>t-1</sub></strong></em> plus some function <em><strong>f</strong></em> of a limited number of previous prices plus some noise term <strong>ε</strong>:</p>
<p style="text-align: center;">[pmath size=16]y_t ~=~ y_{t-1} + f(y_{t-1},~&#8230;, ~y_{t-n}) + epsilon[/pmath]</p>
<p>The time distance between the prices <em><strong>y<sub>t</sub></strong></em> is the <strong>time frame</strong> of the model; the number <em><strong>n</strong></em> of prices used in the function <em><strong>f</strong></em> is the <strong>lookback period</strong> of the model. The higher the predictive <em><strong>f</strong></em> term in relation to the nonpredictive <strong>ε</strong> term, the better is the strategy. Some traders claim that their favorite method does not predict, but &#8216;reacts on the market&#8217; or achieves a positive return by some other means. On a certain trader forum you can even encounter a math professor who re-invented the grid trading system, and praised it as non-predictive and even able to trade a random walk curve. But systems that do not predict <em><strong>y<sub>t</sub></strong></em> in some way must rely on luck; they only can redistribute risk, for instance exchange a high risk of a small loss for a low risk of a high loss. The profit expectancy stays negative. As far as I know, the professor is still trying to sell his grid trader, still advertising it as non-predictive, and still regularly blowing his demo account with it. </p>
<p>Trading by throwing a coin loses the transaction costs. But trading by applying the wrong model &#8211; for instance, trend following to a mean reverting price series &#8211; can cause much higher losses. The average trader indeed loses more than by random trading (about 13 pips per trade according to FXCM statistics). So it&#8217;s not sufficient to have a model; you must also prove that it is valid for the market you trade, at the time you trade, and with the used time frame and lookback period.</p>
<p>Not all price anomalies can be exploited. Limiting stock prices to 1/16 fractions of a dollar is clearly an inefficiency, but it&#8217;s probably difficult to use it for prediction or make money from it. The working model-based strategies that I know, either from theory or because we&#8217;ve been contracted to code some of them, can be classified in several categories. The most frequent are:</p>
<h3>1. Trend </h3>
<p>Momentum in the price curve is probably the most significant and most exploited anomaly. No need to elaborate here, as trend following was the topic of a whole <a href="http://www.financial-hacker.com/trend-delusion-or-reality/">article series</a> on this blog. There are many methods of trend following, the classic being a <strong>moving average crossover</strong>. This &#8216;hello world&#8217; of strategies (<a href="http://www.financial-hacker.com/hackers-tools-zorro-and-r/">here</a> the scripts in R and in C) routinely fails, as it does not distinguish between real momentum and random peaks or valleys in the price curve.</p>
<p>The problem: momentum does not exist in all markets all the time. Any asset can have long non-trending periods. And contrary to popular belief this is not necessarily a &#8216;sidewards market&#8217;. A random walk curve can go up and down and still has zero momentum. Therefore, some good filter that detects the real market regime is essential for trend following systems. Here&#8217;s a minimal Zorro strategy that uses a lowpass filter for detecting trend reversal, and the <a href="http://www.financial-hacker.com/the-market-meanness-index/">MMI</a> indicator for determining when we&#8217;re entering trend regime:</p>
<pre class="prettyprint">function run()
{
  vars Price = series(price());
  vars Trend = series(LowPass(Price,500));
	
  vars MMI_Raw = series(MMI(Price,300));
  vars MMI_Smooth = series(LowPass(MMI_Raw,500));
	
  if(falling(MMI_Smooth)) {
    if(valley(Trend))
      reverseLong(1);
    else if(peak(Trend))
      reverseShort(1);
  }
}</pre>
<p>The profit curve of this strategy:</p>
<figure id="attachment_1224" aria-describedby="caption-attachment-1224" style="width: 879px" class="wp-caption alignnone"><a href="http://www.financial-hacker.com/wp-content/uploads/2015/12/momentum.png"><img loading="lazy" decoding="async" class="wp-image-1224 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/12/momentum.png" alt="" width="879" height="321" srcset="https://financial-hacker.com/wp-content/uploads/2015/12/momentum.png 879w, https://financial-hacker.com/wp-content/uploads/2015/12/momentum-300x110.png 300w, https://financial-hacker.com/wp-content/uploads/2015/12/momentum-768x280.png 768w" sizes="auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a><figcaption id="caption-attachment-1224" class="wp-caption-text">Momentum strategy profit curve</figcaption></figure>
<p>(For the sake of simplicity all strategy snippets on this page are barebone systems with no exit mechanism other than reversal, and no stops, trailing, parameter training, money management, or other gimmicks. Of course the backtests mean in no way that those are profitable systems. The P&amp;L curves are all from EUR/USD, an asset good for demonstrations since it seems to contain a little bit of every possible inefficiency). </p>
<h3><strong>2. Mean reversion</strong></h3>
<p>A mean reverting market believes in a &#8216;real value&#8217; or &#8216;fair price&#8217; of an asset. Traders buy when the actual price is cheaper than it ought to be in their opinion, and sell when it is more expensive. This causes the price curve to revert back to the mean more often than in a random walk. Random data are mean reverting 75% of the time (proof <a href="http://www.financial-hacker.com/the-market-meanness-index/">here</a>), so anything above 75% is caused by a market inefficiency. A model:</p>
<p>[pmath size=16]y_t ~=~ y_{t-1} ~-~ 1/{1+lambda}(y_{t-1}- hat{y}) ~+~ epsilon[/pmath]</p>
<p>[pmath size=16]y_t[/pmath] = price at bar <em><strong>t<br />
 </strong></em>[pmath size=16]hat{y}[/pmath] = fair price<br />
 [pmath size=16]lambda[/pmath] = half-life factor<br />
 [pmath size=16]epsilon[/pmath] = some random noise term</p>
<p>The higher the half-life factor, the weaker is the mean reversion. The half-life of mean reversion in price series ist normally in the range of  50-200 bars. You can calculate <em><strong>λ</strong></em> by linear regression between <em><strong>y<sub>t-1</sub></strong></em> and <em><strong>(y<sub>t-1</sub>-y<sub>t</sub>)</strong></em>. The price series need not be stationary for experiencing mean reversion, since the fair price is allowed to drift. It just must drift less as in a random walk. Mean reversion is usually exploited by removing the trend from the price curve and normalizing the result. This produces an oscillating signal that can trigger trades when it approaches a top or bottom. Here&#8217;s the script of a simple mean reversion system:</p>
<pre class="prettyprint">function run()
{
  vars Price = series(price());
  vars Filtered = series(HighPass(Price,30));
  vars Signal = series(FisherN(Filtered,500));
  var Threshold = 1.0;

  if(Hurst(Price,500) &lt; 0.5) { // do we have mean reversion?
    if(crossUnder(Signal,-Threshold))
      reverseLong(1); 
    else if(crossOver(Signal,Threshold))
      reverseShort(1);
  }
} </pre>
<p>The highpass filter dampens all cycles above 30 bars and thus removes the trend from the price curve. The result is normalized by the <strong>Fisher transformation </strong>which produces a Gaussian distribution of the data. This allows us to determine fixed thresholds at <strong>1</strong> and <strong>-1</strong> for separating the tails from the resulting bell curve. If the price enters a tail in any direction, a trade is triggered in anticipation that it will soon return into the bell&#8217;s belly. For detecting mean reverting regime, the script uses the <strong>Hurst Exponent</strong>. The exponent is 0.5 for a random walk. Above 0.5 begins momentum regime and below 0.5 mean reversion regime.</p>
<figure id="attachment_1226" aria-describedby="caption-attachment-1226" style="width: 879px" class="wp-caption alignnone"><a href="http://www.financial-hacker.com/wp-content/uploads/2015/12/meanreversion.png"><img loading="lazy" decoding="async" class="wp-image-1226 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/12/meanreversion.png" alt="" width="879" height="301" srcset="https://financial-hacker.com/wp-content/uploads/2015/12/meanreversion.png 879w, https://financial-hacker.com/wp-content/uploads/2015/12/meanreversion-300x103.png 300w, https://financial-hacker.com/wp-content/uploads/2015/12/meanreversion-768x263.png 768w" sizes="auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a><figcaption id="caption-attachment-1226" class="wp-caption-text">Mean reversion profit curve</figcaption></figure>
<h3>3. Statistical Arbitrage</h3>
<p>Strategies can exploit the similarity between two or more assets.  This allows to hedge the first asset by a reverse position in the second asset, and this way derive profit from mean reversion of their price difference:</p>
<p>[pmath size=16]y ~=~ h_1 y_1 &#8211; h_2 y_2[/pmath]</p>
<p>where <em><strong>y<sub>1</sub></strong></em> and <em><strong>y<sub>2</sub></strong></em> are the prices of the two assets and the multiplication factors <em><strong>h<sub>1</sub></strong></em> and <em><strong>h<sub>2</sub></strong></em> their <strong>hedge ratios</strong>. The hedge ratios are calculated in a way that the mean of the difference <em><strong>y</strong></em> is zero or a constant value. The simplest method for calculating the hedge ratios is linear regression between <em><strong>y<sub>1</sub></strong></em> and <em><strong>y<sub>2</sub></strong></em>. A mean reversion strategy as above can then be applied to <em><strong>y.</strong></em>  </p>
<p>The assets need not be of the same type; a typical arbitrage system can be based on the price difference between an index ETF and its major stock. When <em><strong>y</strong></em> is not <strong>stationary</strong> &#8211; meaning that its mean tends to wander off slowly &#8211; the hedge ratios must be adapted in real time for compensating. <a href="https://mktstk.wordpress.com/2015/08/18/the-kalman-filter-and-pairs-trading/" target="_blank" rel="noopener">Here</a> is a proposal using a <strong>Kalman Filter</strong> by a fellow blogger.</p>
<p>The simple arbitrage system from the <a href="http://manual.zorro-project.com/Lecture4.htm" target="_blank" rel="noopener">R tutorial</a>:<!--?prettify linenums=true?--></p>
<pre class="prettyprint">require(quantmod)

symbols &lt;- c("AAPL", "QQQ")
getSymbols(symbols)

#define training set
startT  &lt;- "2007-01-01"
endT    &lt;- "2009-01-01"
rangeT  &lt;- paste(startT,"::",endT,sep ="")
tAAPL   &lt;- AAPL[,6][rangeT]
tQQQ   &lt;- QQQ[,6][rangeT]
 
#compute price differences on in-sample data
pdtAAPL &lt;- diff(tAAPL)[-1]
pdtQQQ &lt;- diff(tQQQ)[-1]
 
#build the model
model  &lt;- lm(pdtAAPL ~ pdtQQQ - 1)
 
#extract the hedge ratio (h1 is assumed 1)
h2 &lt;- as.numeric(model$coefficients[1])

#spread price (in-sample)
spreadT &lt;- tAAPL - h2 * tQQQ
 
#compute statistics of the spread
meanT    &lt;- as.numeric(mean(spreadT,na.rm=TRUE))
sdT      &lt;- as.numeric(sd(spreadT,na.rm=TRUE))
upperThr &lt;- meanT + 1 * sdT
lowerThr &lt;- meanT - 1 * sdT
 
#run in-sample test
spreadL  &lt;- length(spreadT)
pricesB  &lt;- c(rep(NA,spreadL))
pricesS  &lt;- c(rep(NA,spreadL))
sp       &lt;- as.numeric(spreadT)
tradeQty &lt;- 100
totalP   &lt;- 0

for(i in 1:spreadL) {
     spTemp &lt;- sp[i]
     if(spTemp &lt; lowerThr) {
        if(totalP &lt;= 0){
           totalP     &lt;- totalP + tradeQty
           pricesB[i] &lt;- spTemp
        }
     } else if(spTemp &gt; upperThr) {
       if(totalP &gt;= 0){
          totalP &lt;- totalP - tradeQty
          pricesS[i] &lt;- spTemp
       }
    }
}
</pre>
<h3>4. Price constraints</h3>
<p>A price constraint is an artificial force that causes a constant price drift or establishes a price range, floor, or ceiling. The most famous example was the <a href="http://www.financial-hacker.com/build-better-strategies/" target="_blank" rel="noopener">EUR/CHF price cap</a> mentioned in the first part of this series. But even after removal of the cap, the EUR/CHF price has still a constraint, this time not enforced by the national bank, but by the current strong asymmetry in EUR and CHF buying power. An extreme example of a ranging price is the EUR/DKK pair (see below). All such constraints can be used in strategies to the trader&#8217;s advantage. </p>
<figure id="attachment_1983" aria-describedby="caption-attachment-1983" style="width: 979px" class="wp-caption alignnone"><a href="http://www.financial-hacker.com/wp-content/uploads/2015/12/PlotCurve_EURDKK.png"><img loading="lazy" decoding="async" class="wp-image-1983 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/12/PlotCurve_EURDKK.png" width="979" height="321" srcset="https://financial-hacker.com/wp-content/uploads/2015/12/PlotCurve_EURDKK.png 979w, https://financial-hacker.com/wp-content/uploads/2015/12/PlotCurve_EURDKK-300x98.png 300w, https://financial-hacker.com/wp-content/uploads/2015/12/PlotCurve_EURDKK-768x252.png 768w" sizes="auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a><figcaption id="caption-attachment-1983" class="wp-caption-text">EUR/DKK price range 2006-2016</figcaption></figure>
<h3>5. Cycles</h3>
<p>Non-seasonal cycles are caused by feedback from the price curve. When traders believe in a &#8216;fair price&#8217; of an asset, they often sell or buy a position when the price reaches a certain distance from that value, in hope of a reversal. Or they close winning positions when the favorite price movement begins to decelerate. Such effects can synchronize entries and exits among a large number of traders, and cause the price curve to oscillate with a period that is stable over several cycles. Often many such cycles are superposed on the curve, like this:</p>
<p>[pmath size=16]y_t ~=~ hat{y}  ~+~ sum{i}{}{a_i sin(2 pi t/C_i+D_i)} ~+~ epsilon[/pmath]</p>
<p>When you know the period <em><strong>C<sub>i</sub></strong></em> and the phase <em><strong>D<sub>i</sub></strong></em> of the dominant cycle, you can calculate the optimal trade entry and exit points as long as the cycle persists. Cycles in the price curve can be detected with spectral analysis functions &#8211; for instance, fast Fourier transformation (FFT) or simply a bank of narrow bandpass filters. Here is the frequency spectrum of the EUR/USD in October 2015:</p>
<figure id="attachment_1160" aria-describedby="caption-attachment-1160" style="width: 1599px" class="wp-caption alignnone"><a href="http://www.financial-hacker.com/wp-content/uploads/2015/11/spectrum.png"><img loading="lazy" decoding="async" class="wp-image-1160 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/11/spectrum.png" alt="" width="1599" height="321" srcset="https://financial-hacker.com/wp-content/uploads/2015/11/spectrum.png 1599w, https://financial-hacker.com/wp-content/uploads/2015/11/spectrum-300x60.png 300w, https://financial-hacker.com/wp-content/uploads/2015/11/spectrum-1024x206.png 1024w, https://financial-hacker.com/wp-content/uploads/2015/11/spectrum-1200x241.png 1200w" sizes="auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a><figcaption id="caption-attachment-1160" class="wp-caption-text">EUR/USD spectrum, cycle length in bars</figcaption></figure>
<p>Exploiting cycles is a little more tricky than trend following or mean reversion. You need not only the cycle length of the dominant cycle of the spectrum, but also its phase (for triggering trades at the right moment) and its amplitude (for determining if there is a cycle worth trading at all). This is a barebone script:</p>
<pre class="prettyprint">function run()
{
  vars Price = series(price());
  var Phase = DominantPhase(Price,10);
  vars Signal = series(sin(Phase+PI/4));
  vars Dominant = series(BandPass(Price,rDominantPeriod,1));
  ExitTime = 10*rDominantPeriod;
  var Threshold = 1*PIP;
	
  if(Amplitude(Dominant,100) &gt; Threshold) {
    if(valley(Signal))
      reverseLong(1); 
    else if(peak(Signal))
      reverseShort(1);
  }
}</pre>
<p>The <strong>DominantPhase</strong> function determines both the phase and the cycle length of the dominant peak in the spectrum; the latter is stored in the <strong>rDominantPeriod</strong> variable. The phase is converted to a sine curve that is shifted ahead by <em><strong>π/4</strong></em>. With this trick we&#8217;ll get a sine curve that runs ahead of the price curve. Thus we do real price prediction here, only question is if the price will follow our prediction. This is determined by applying a bandpass filter centered at the dominant cycle to the price curve, and measuring its amplitude (the <em><strong>a<sub>i</sub></strong></em> in the formula). If the amplitude is above a threshold,  we conclude that we have a strong enough cycle. The script then enters long on a valley of the run-ahead sine curve, and short on a peak. Since cycles are shortlived, the duration of a trade is limited by <strong>ExitTime</strong> to a maximum of 10 cycles. </p>
<p><a href="http://www.financial-hacker.com/wp-content/uploads/2015/12/cycles2.png"><img loading="lazy" decoding="async" class="alignnone wp-image-1252 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/12/cycles2.png" alt="" width="879" height="321" srcset="https://financial-hacker.com/wp-content/uploads/2015/12/cycles2.png 879w, https://financial-hacker.com/wp-content/uploads/2015/12/cycles2-300x110.png 300w, https://financial-hacker.com/wp-content/uploads/2015/12/cycles2-768x280.png 768w" sizes="auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>We can see from the P&amp;L curve that there were long periods in 2012 and 2014 with no strong cycles in the EUR/USD price curve. </p>
<h3>6. Clusters</h3>
<p>The same effect that causes prices to oscillate can also let them cluster at certain levels. Extreme clustering can even produce &#8220;supply&#8221; and &#8220;demand&#8221; lines (also known as &#8220;<strong>support and resistance</strong>&#8220;), the favorite subjects in trading seminars. Expert seminar lecturers can draw support and resistance lines on any chart, no matter if it&#8217;s pork belly prices or last year&#8217;s baseball scores. However the mere existence of those lines remains debatable: There are few strategies that really identify and exploit them, and even less that really produce profits. Still, clusters in price curves are real and can be easily identified in a histogram similar to the cycles spectogram.</p>
<h3>7. Curve patterns</h3>
<p>They arise from repetitive behavior of traders. Traders not only produce, but also believe in many curve patterns; most &#8211; such as the famous &#8216;head and shoulders&#8217; pattern that is said to predict trend reversal &#8211; are myths (at least I have not found any statistical evidence of it, and heard of no other any research that ever confirmed the existence of predictive heads and shoulders in price curves). But some patterns, for instance &#8220;cups&#8221; or &#8220;half-cups&#8221;, really exist and can indeed precede an upwards or downwards movement. Curve patterns &#8211; not to be confused with <strong>candle patterns</strong> &#8211; can be exploited by pattern-detecting methods such as the <a href="http://zorro-project.com/manual/en/detect.htm" target="_blank" rel="noopener">Fréchet algorithm</a>. </p>
<p>A special variant of a curve pattern is the <strong>Breakout</strong> &#8211; a sudden momentum after a long sidewards movement. Is can be caused, for instance, by trader&#8217;s tendency to place their stop losses as a short distance below or above the current plateau. Triggering the first stops then accelerates the price movement until more and more stops are triggered. Such an effect can be exploited by a system that detects a sidewards period and then lies in wait for the first move in any direction.</p>
<h3>8. Seasonality</h3>
<p>&#8220;Season&#8221; does not necessarily mean a season of a year. Supply and demand can also follow monthly, weekly, or daily patterns that can be detected and exploited by strategies. For instance, the S&amp;P500 index is said to often move upwards in the first days of a month, or to show an upwards trend in the early morning hours before the main trading session of the day. Since seasonal effects are easy to exploit, they are often shortlived, weak, and therefore hard to detect by just eyeballing price curves. But they can be found by plotting a <a href="http://zorro-project.com/manual/en/profile.htm" target="_blank" rel="noopener">day, week, or month profile</a> of average price curve differences.</p>
<h3>9. Gaps</h3>
<p>When market participants contemplate whether to enter or close a position, they seem to come to rather similar conclusions when they have time to think it over at night or during the weekend. This can cause the price to start at a different level when the market opens again. Overnight or weekend price gaps are often more predictable than price changes during trading hours. And of course they can be exploited in a strategy. On the Zorro forum was recently a discussion about the &#8220;<a href="http://www.opserver.de/ubb7/ubbthreads.php?ubb=showflat&amp;Number=452807&amp;page=1" target="_blank" rel="noopener">One Night Stand System</a>&#8220;, a simple currency weekend-gap trader with mysterious profits.</p>
<h3>10. Autoregression and heteroskedasticity</h3>
<p>The latter is a fancy word for: &#8220;Prices jitter a lot and the jittering varies over time&#8221;. The ARIMA and GARCH models are the first models that you encounter in financial math. They assume that future returns or future volatility can be determined with a linear combination of past returns or past volatility. Those models are often considered purely theoretical and of no practical use. Not true: You can use them for predicting tomorrow&#8217;s price just as any other model. You can examine a <strong>correlogram</strong> &#8211; a statistics of the correlation of the current return with the returns of the previous bars &#8211; for finding out if an ARIMA model fits to a certain price series. Here are two excellent articles by fellow bloggers for using those models in trading strategies:  <a href="https://www.quantstart.com/articles/ARIMA-GARCH-Trading-Strategy-on-the-SP500-Stock-Market-Index-Using-R" target="_blank" rel="noopener">ARIMA+GARCH Trading Strategy on the S&amp;P500</a> and <a href="http://robotwealth.com/fitting-time-series-models-to-the-forex-market-are-arimagarch-predictions-profitable" target="_blank" rel="noopener">Are ARIMA/GARCH Predictions Profitable?</a></p>
<h3>11. Price shocks</h3>
<p>Price shocks often happen on Monday or Friday morning when companies or organizations publish good or bad news that affect the market. Even without knowing the news, a strategy can detect the first price reactions and quickly jump onto the bandwagon. This is especially easy when a large shock is shaking the markets. Here&#8217;s a simple Forex portfolio strategy that evaluates the relative strengths of currencies for detecting price shocks:</p>
<pre class="prettyprint">function run()
{
  BarPeriod = 60;
  ccyReset();
  string Name;
  while(Name = (loop(Assets)))
  {
    if(assetType(Name) != FOREX) 
      continue; // Currency pairs only
    asset(Name);
    vars Prices = series(priceClose());
    ccySet(ROC(Prices,1)); // store price change as strength
  }
  
// get currency pairs with highest and lowest strength difference
  string Best = ccyMax(), Worst = ccyMin();
  var Threshold = 1.0; // The shock level

  static char OldBest[8], OldWorst[8];	// static for keeping contents between runs
  if(*OldBest &amp;&amp; !strstr(Best,OldBest)) { // new strongest asset?
    asset(OldBest);
    exitLong();
    if(ccyStrength(Best) &gt; Threshold) {
      asset(Best);
      enterLong();
    }
  } 
  if(*OldWorst &amp;&amp; !strstr(Worst,OldWorst)) { // new weakest asset?
    asset(OldWorst);
    exitShort();
    if(ccyStrength(Worst) &lt; -Threshold) {
      asset(Worst);
      enterShort();
    }
  }

// store previous strongest and weakest asset names  
  strcpy(OldBest,Best);
  strcpy(OldWorst,Worst);
}</pre>
<p>The equity curve of the currency strength system (you&#8217;ll need Zorro 1.48 or above):</p>
<figure id="attachment_2004" aria-describedby="caption-attachment-2004" style="width: 879px" class="wp-caption alignnone"><a href="http://www.financial-hacker.com/wp-content/uploads/2015/12/CurrencyStrength_EURCHF.png"><img loading="lazy" decoding="async" class="wp-image-2004 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/12/CurrencyStrength_EURCHF.png" width="879" height="341" srcset="https://financial-hacker.com/wp-content/uploads/2015/12/CurrencyStrength_EURCHF.png 879w, https://financial-hacker.com/wp-content/uploads/2015/12/CurrencyStrength_EURCHF-300x116.png 300w, https://financial-hacker.com/wp-content/uploads/2015/12/CurrencyStrength_EURCHF-768x298.png 768w" sizes="auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a><figcaption id="caption-attachment-2004" class="wp-caption-text">Price shock exploiting system</figcaption></figure>
<p>The blue equity curve above reflects profits from small and large jumps of currency prices. You can clearly identify the <strong>Brexit</strong> and the <strong>CHF price cap shock</strong>. Of course such strategies would work even better if the news could be early detected and interpreted in some way. Some data services provide news events with a binary valuation, like &#8220;good&#8221; or &#8220;bad&#8221;. Especially of interest are <strong>earnings reports</strong>, as provided by data services such as Zacks or Xignite. Depending on which surprises the earnings report contains, stock prices and implied volatilities can rise or drop sharply at the report day, and generate quick profits.</p>
<p>For learning what can happen when news are used in more creative ways, I recommend the excellent <a href="http://www.amazon.de/gp/product/0099553279/ref=as_li_tl?ie=UTF8&amp;camp=1638&amp;creative=6742&amp;creativeASIN=0099553279&amp;linkCode=as2&amp;tag=worterbuchdes-21&quot;&gt;The Fear Index&lt;/a&gt;&lt;img src=&quot;http://ir-de.amazon-adsystem.com/e/ir?t=worterbuchdes-21&amp;l=as2&amp;o=3&amp;a=0099553279&quot; width=&quot;1&quot; height=&quot;1&quot; border=&quot;0&quot; alt=&quot;&quot; style=&quot;border:none !important; margin:0px !important;" target="_blank" rel="noopener">Fear Index</a> by Robert Harris &#8211; a mandatory book in any financial hacker&#8217;s library.</p>
<hr />
<p>This was the second part of the <a href="http://www.financial-hacker.com/build-better-strategies/">Build Better Strategies</a> series. The third part will deal with the process to develop a model-based strategy, from inital research up to building the user interface. In case someone wants to experiment with the code snippets posted here, I&#8217;ve added them to the 2015 scripts repository. They are no real strategies, though. The missing elements &#8211; parameter optimization, exit algorithms, money management etc. &#8211; will be the topic of the next part of the series.</p>
<p style="text-align: right;"><strong>⇒ <a href="http://www.financial-hacker.com/build-better-strategies-part-3-the-development-process/">Build Better Strategies &#8211; Part 3</a></strong></p>
]]></content:encoded>
					
					<wfw:commentRss>https://financial-hacker.com/build-better-strategies-part-2-model-based-systems/feed/</wfw:commentRss>
			<slash:comments>46</slash:comments>
		
		
			</item>
		<item>
		<title>The Market Meanness Index</title>
		<link>https://financial-hacker.com/the-market-meanness-index/</link>
					<comments>https://financial-hacker.com/the-market-meanness-index/#comments</comments>
		
		<dc:creator><![CDATA[jcl]]></dc:creator>
		<pubDate>Mon, 21 Sep 2015 05:00:40 +0000</pubDate>
				<category><![CDATA[Indicators]]></category>
		<category><![CDATA[Ehlers]]></category>
		<category><![CDATA[Mandelbrot]]></category>
		<category><![CDATA[Market Meanness Index]]></category>
		<category><![CDATA[Mean Reversion]]></category>
		<category><![CDATA[Momentum]]></category>
		<guid isPermaLink="false">http://www.financial-hacker.com/?p=250</guid>

					<description><![CDATA[This indicator can improve &#8211; sometimes even double &#8211; the profit expectancy of trend following systems. The Market Meanness Index tells whether the market is currently moving in or out of a &#8220;trending&#8221; regime. It can this way prevent losses by false signals of trend indicators. It is a purely statistical algorithm and not based on volatility, &#8230; <a href="https://financial-hacker.com/the-market-meanness-index/" class="more-link">Continue reading<span class="screen-reader-text"> "The Market Meanness Index"</span></a>]]></description>
										<content:encoded><![CDATA[<p>This indicator can improve &#8211; sometimes even double &#8211; the profit expectancy of trend following systems. The <strong>Market Meanness Index</strong> tells whether the market is currently moving in or out of a &#8220;trending&#8221; regime. It can this way prevent losses by <strong>false signals</strong> of trend indicators. It is a purely statistical algorithm and not based on volatility, trends, or cycles of the price curve.<span id="more-250"></span></p>
<p>There are already several methods for differentiating trending and nontrending market regimes. Some of them are rumored to really work, at least occasionally. John Ehlers proposed the <strong>Hilbert Transform</strong> or a <strong>Cycle / Trend decomposition</strong>, Benoit Mandelbrot the <strong>Hurst Exponent</strong>. In comparison, the source code of the Market Meanness Index is relatively simple:</p>
<pre class="prettyprint">// Market Meanness Index
double MMI(double *Data,int Length)
{
  double m = Median(Data,Length);
  int i, nh=0, nl=0;
  for(i=1; i&lt;Length; i++) {
    if(Data[i] &gt; m &amp;&amp; Data[i] &gt; Data[i-1]) // mind Data order: Data[0] is newest!
      nl++;
    else if(Data[i] &lt; m &amp;&amp; Data[i] &lt; Data[i-1])
      nh++;
  }
  return 100.*(nl+nh)/(Length-1);
}</pre>
<p>This code is in C for Zorro, but meanwhile also versions for MT4, Amibroker, Ninja Trader, and other platforms have been programmed by users. As the name suggests, the indicator measures the meanness of the market &#8211; its tendency to revert to the mean after pretending to start a trend. If that happens too often, all trend following systems will bite the dust.</p>
<h3>The Three-Quarter Rule</h3>
<p>Any series of independent random numbers reverts to the mean &#8211; or more precisely, to their median &#8211; with a probability of 75%. Assume you have a sequence of random, uncorrelated daily data &#8211; for instance, the daily rates of change of a random walk price curve. If Monday&#8217;s data value was above the median, then in 75% of all cases Tuesday&#8217;s data will be lower than Monday&#8217;s. And if Monday was below the median, 75% chance is that Tuesday will be higher. The proof of the 75% rule is relatively simple and won&#8217;t require integral calculus. Consider a data series with median <strong>M</strong>. By definition, half the values are less than <strong>M</strong> and half are greater (for simplicity&#8217;s sake we&#8217;re ignoring the case when a value is exactly <strong>M</strong>). Now combine the values to pairs each consisting of a value <strong>Py</strong> and the following value <strong>Pt</strong>. Thus each pair represents a change from <strong>Py</strong> to <strong>Pt</strong>. We now got a lot of changes that we divide into four sets:</p>
<ol>
<li><strong>(Pt &lt; M, Py &lt; M)</strong></li>
<li><strong><span style="line-height: 1.75;">(Pt &lt; M, Py &gt; M)</span></strong></li>
<li><strong><span style="line-height: 1.75;">(Pt &gt; M, Py &lt; M)</span></strong></li>
<li><strong><span style="line-height: 1.75;">(Pt &gt; M, Py &gt; M) </span></strong></li>
</ol>
<p><span style="line-height: 1.75;">These four sets have obviously the same number of elements &#8211; that is, 1/4 of all <strong>Py-&gt;Pt</strong> changes &#8211; when <strong>Pt</strong> and <strong>Py</strong> are uncorrelated, i.e. completely independent of one another. The value of <strong>M</strong> and the kind of data in the series won&#8217;t matter for this. Now how many data pairs revert to the median? All pairs that fulfill this condition:</span> <strong>(Py &lt; M and Pt &gt; Py) or (Py &gt; M and Pt &lt; Py)</strong> <span style="line-height: 1.75;">The condition in the first bracket is fulfilled for half the data in set 1 (in the other half is <strong>Pt</strong> less than<strong> Py</strong>) and in the whole set 3 (because <strong>Pt</strong> is always higher than <strong>Py</strong> in set 3). So the first bracket is true for </span><span style="line-height: 1.75;">1/2 * 1/4 + 1/4 = 3/8 of all data changes. Likewise,  the second bracket is true in half the set 4 and in the whole set 2, thus also for 3/8 of all data changes. 3/8 + 3/8 yields 6/8, i.e. <strong>75%</strong>. This is the three-quarter rule for random numbers.</span></p>
<p><span style="line-height: 1.75;">The <strong>MMI</strong> function just counts the number of data pairs for which the conditition is met, and returns their percentage. The <strong>Data</strong> series may contain prices or price changes. Prices have always some serial correlation: If EUR / USD today is at 1.20, it will also be tomorrow around 1.20. That it will end up tomorrow at 70 cents or 2 dollars per EUR is rather unlikely. This serial correlation is also true for a price series calculated from random numbers, as not the prices themselves are random, but their changes. Thus, the MMI function should return a smaller percentage, such as 55%, when fed with prices.</span></p>
<p><span style="line-height: 1.75;"> </span><span style="line-height: 1.75;">Unlike prices, price changes have not necessarily serial correlation. A one hundred percent efficient market has no correlation between the price change from yesterday to today and the price change from today to tomorrow. If the MMI function is fed with perfectly random price changes from a perfectly efficient market, it will return a value of about 75%. The less efficient and the more trending the market become</span><span style="line-height: 1.75;">s, the more the MMI decreases. Thus a falling MMI is a indicator of an upcoming trend. A rising MMI hints that the market will get nastier, at least for trend trading systems.</span></p>
<h3>Using the MMI in a trend strategy</h3>
<p>One could assume that MMI predicts the price direction. A high MMI value indicates a high chance of mean reversion, so when prices were moving up in the last time and MMI is high, can we expect a soon price drop? Unfortunately it doesn&#8217;t work this way. The probability of mean reversion is not evenly distributed over the <strong>Length</strong> of the <strong>Data</strong> interval. For the early prices it is high (since the median is computed from future prices), but for the late prices, at the very time when MMI is calculated, it is down to just 50%. Predicting the next price with the MMI would work as well as flipping a coin.</p>
<p>Another mistake would be using the MMI for detecting a cyclic or mean-reverting market regime. True, the MMI will rise in such a situation, but it will also rise when the market becomes more random and more effective. A rising MMI alone is no promise of profit by cycle trading systems.</p>
<p>So the MMI won&#8217;t tell us the next price, and it won&#8217;t tell us if the market is mean reverting or just plain mean, but it can reveal information about the success chance of trend following. For this we&#8217;re making an assumption: <strong>Trend itself is trending</strong>. The market does not jump in and out of trend mode suddenly, but with some inertia. Thus, when we know that MMI is rising, we assume that the market is becoming more efficient, more random, more cyclic, more reversing or whatever, but in any case bad for trend trading. However when MMI is falling, chances are good that the next beginning trend will last longer than normal.</p>
<p>This way the MMI can be an excellent trend filter &#8211; in theory. But we all know that there&#8217;s often a large gap between theory and practice, especially in algorithmic trading. So I&#8217;m now going to test what the Market Meanness Index does to the collection of the <a href="http://www.financial-hacker.com/trend-and-exploiting-it/">900 trend following systems</a> that I&#8217;ve accumulated. For a first quick test, this was the equity curve of one of the systems, <strong>TrendEMA</strong>, without MMI (44% average annual return):</p>
<figure id="attachment_375" aria-describedby="caption-attachment-375" style="width: 1079px" class="wp-caption alignnone"><a href="http://www.financial-hacker.com/wp-content/uploads/2015/09/TrendEMA_EURUSD.png"><img loading="lazy" decoding="async" class="wp-image-375 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/09/TrendEMA_EURUSD.png" alt="" width="1079" height="301" srcset="https://financial-hacker.com/wp-content/uploads/2015/09/TrendEMA_EURUSD.png 1079w, https://financial-hacker.com/wp-content/uploads/2015/09/TrendEMA_EURUSD-300x84.png 300w, https://financial-hacker.com/wp-content/uploads/2015/09/TrendEMA_EURUSD-1024x286.png 1024w" sizes="auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a><figcaption id="caption-attachment-375" class="wp-caption-text">EMA strategy without MMI</figcaption></figure>
<p>This is the same system with MMI (55% average annual return):</p>
<figure id="attachment_377" aria-describedby="caption-attachment-377" style="width: 1079px" class="wp-caption alignnone"><a href="http://www.financial-hacker.com/wp-content/uploads/2015/09/TrendEMA_EURUSD1.png"><img loading="lazy" decoding="async" class="wp-image-377 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/09/TrendEMA_EURUSD1.png" alt="" width="1079" height="301" srcset="https://financial-hacker.com/wp-content/uploads/2015/09/TrendEMA_EURUSD1.png 1079w, https://financial-hacker.com/wp-content/uploads/2015/09/TrendEMA_EURUSD1-300x84.png 300w, https://financial-hacker.com/wp-content/uploads/2015/09/TrendEMA_EURUSD1-1024x286.png 1024w" sizes="auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a><figcaption id="caption-attachment-377" class="wp-caption-text">EMA strategy with MMI</figcaption></figure>
<p>We can see that the profit has doubled, from $250 to $500. The profit factor climbed from 1.2 to 1.8, and the number of trades (green and red lines) is noticeable reduced. On the other hand, the equity curve started with a drawdown that wasn&#8217;t there with the original system. So MMI obviously does not improve all trades. And this was just a randomly selected system. If our assumption about trend trendiness is true, the indicator should have a significant effect also on the other 899 systems.</p>
<p>This experiment will be the topic of the next article, in about a week. As usually I&#8217;ll include all the source code for anyone to reproduce it. Will the MMI miserably fail? Or improve only a few systems, but worsen others? Or will it light up the way to the Holy Grail of trend strategies? Let the market be the judge.</p>
<p><a href="http://www.financial-hacker.com/boosting-systems-by-trade-filtering/">Next: Testing the Market Meanness Index</a></p>
<hr />
<p><strong>Addendum (2022).</strong> I thought my above proof of the 3/4 rule was trivial and no math required, but judging from some comments, it is not so. The rule appears a bit counter-intuitive at first glance. Some comments also confuse a random walk (for example, prices) with a random sequence (for example, price differences). Maybe I have just bad explained it &#8211; in that case, read up the proof anywhere else. I found the two most elaborate proofs of the 3/4 rule, geometrical and analytical, in this book:</p>
<p>(1)  Andrew Pole, Statistical Arbitrage, Wiley 2007</p>
<p>And with no reading and no math: Take a dice, roll it 100 times, write down each result, get the median of all, and then count how often a pair reverted to the median.</p>
<p>Below you can see the MMI applied to a synthetic price curve, first sidewards (black) and then with added trend (blue). For using the MMI with real prices or price differences, read the next article.</p>
<p><img decoding="async" src="http://financial-hacker.com/images/Regime.png " alt="MMI" /></p>
<p>The code:</p>
<pre class="prettyprint">function run()
{
	BarPeriod = 60;
	MaxBars = 1000;
	LookBack = 500;
	asset(""); // dummy asset
	ColorUp = ColorDn = 0; // don't plot a price curve
	set(PLOTNOW);
	
	if(Init) seed(1000);
	int TrendStart = LookBack + 0.4*(MaxBars-LookBack);
	vars Signals = series(1 + 0.5*genNoise());
	if(Bar &gt; TrendStart) 
		Signals[0] += 0.003*(Bar-TrendStart);
	int Color = RED;
	int TimePeriod = 0.5*LookBack;
	if(Bar &lt; TrendStart)
		plot("Sidewards",Signals,MAIN,BLACK);
	else
		plot("Trending",Signals,MAIN,BLUE);
	plot("MMI",MMI(Signals,TimePeriod),NEW|LINE,Color);
}</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://financial-hacker.com/the-market-meanness-index/feed/</wfw:commentRss>
			<slash:comments>139</slash:comments>
		
		
			</item>
		<item>
		<title>White&#8217;s Reality Check</title>
		<link>https://financial-hacker.com/whites-reality-check/</link>
					<comments>https://financial-hacker.com/whites-reality-check/#comments</comments>
		
		<dc:creator><![CDATA[jcl]]></dc:creator>
		<pubDate>Mon, 14 Sep 2015 08:48:17 +0000</pubDate>
				<category><![CDATA[Research]]></category>
		<category><![CDATA[System Evaluation]]></category>
		<category><![CDATA[Aronson]]></category>
		<category><![CDATA[Data mining bias]]></category>
		<category><![CDATA[Detrending]]></category>
		<category><![CDATA[Momentum]]></category>
		<category><![CDATA[White's reality check]]></category>
		<guid isPermaLink="false">http://www.financial-hacker.com/?p=188</guid>

					<description><![CDATA[This is the third part of the Trend Experiment article series. We now want to evaluate if the positive results from the 900 tested trend following strategies are for real, or just caused by Data Mining Bias. But what is Data Mining Bias, after all? And what is this ominous White&#8217;s Reality Check? Suppose you &#8230; <a href="https://financial-hacker.com/whites-reality-check/" class="more-link">Continue reading<span class="screen-reader-text"> "White&#8217;s Reality Check"</span></a>]]></description>
										<content:encoded><![CDATA[<p>This is the third part of the <a href="http://www.financial-hacker.com/trend-delusion-or-reality/" target="_blank" rel="noopener noreferrer">Trend Experiment</a> article series. We now want to evaluate if the positive results from the 900 tested trend following strategies are for real, or just caused by <strong>Data Mining Bias</strong>. But what is Data Mining Bias, after all? And what is this ominous <strong>White&#8217;s Reality Check</strong>?<span id="more-188"></span></p>
<p>Suppose you want to trade by moon phases. But you&#8217;re not sure if you shall buy at full moon and sell at new moon, or the other way around. So you do a series of moon phase backtests and find out that the best system, which opens positions at any first quarter moon, achieves 30% annual return. Is this finally the proof that astrology works?</p>
<p>A trade system based on a nonexisting effect has normally a profit expectancy of zero (minus trade costs). But you won&#8217;t get zero when you backtest variants of such a system. Due to statistical fluctuations, some of them will produce a positive and some a negative return. When you now pick the best performer, such as the first quarter moon trading system, you might get a high return and an impressive equity curve in the backtest. Sadly, its test result is not necessarily caused by clever trading. It might be just by clever selecting the random best performer from a pool of useless systems.</p>
<p>For finding out if the 30% return by quarter moon trading are for real or just the fool&#8217;s gold of Data Mining Bias, <strong>Halbert White</strong> (1959-2012) invented a test method in 2000.  <strong>White&#8217;s Reality Check </strong>(aka <strong>Bootstrap Reality Check</strong>) is explained in detail in the book &#8216;Evidence-Based Technical Analysis&#8217; by <strong>David Aronson</strong>. It works this way:</p>
<ol>
<li>Develop a strategy. During the development process, keep a record of all strategy variants that were tested and discarded because of their test results, including all abandoned algorithms, ideas, methods, and parameters. It does not matter if they were discarded by human decision or by a computer search or optimizing process.</li>
<li>Produce balance curves of all strategy variants, using detrended trade results and no trade costs. Note down the profit <strong>P</strong> of the best strategy.</li>
<li>Detrend all balance curves by subtracting the mean return per bar (not to be confused with detrending the trade results!). This way you get a series of curves with the same characteristics of the tested systems, but zero profit.</li>
<li>Randomize all curves by bootstrap with replacement. This produces new curves from the random returns of the old curves. Because the same bars can be selected multiple times, most new curves now produce losses or profits different from zero.</li>
<li>Select the best performer from the randomized curves, and note down its profit.</li>
<li> Repeat steps 4 and 5 a couple 1000 times.</li>
<li>You now have a list of several 1000 best profits. The median <strong>M</strong> of that list is the Data Mining Bias by your strategy development process.</li>
<li>Check where the original best profit <strong>P</strong> appears in the list. The percentage of best bootstrap profits greater than <strong>P</strong> is the so-called <strong>p-Value</strong> of the best strategy. You want the p-Value to be as low as possible. If <strong>P</strong> is better than 95% of the best bootstrap profits, the best strategy has a real edge with 95% probability.</li>
<li><strong>P</strong> minus <strong>M</strong> minus trade costs is the result to be expected in real trading the best strategy.</li>
</ol>
<p>The method is not really intuitive, but mathematically sound. However, it suffers from a couple problems that makes WRC difficult to use  in real strategy development:</p>
<ul style="list-style-type: square;">
<li>You can see the worst problem already in step 1. During strategy development you&#8217;re permanently testing ideas, adding or removing parameters, or checking out different assets and time frames. Putting aside all discarded variants and producing balance curves of all combinations of them is a cumbersome process. It gets even more diffcult with machine learning algorithms that optimize weight factors and usually do not produce discarded variants. However, the good news are that you can easily apply the WRC when your strategy variants are produced by a transparent mechanical process with no human decisions involved. That&#8217;s fortunately the case for our trend experiment.</li>
<li>WRC tends to type II errors. That means it can reject strategies although they have an edge. When more irrelevant variants &#8211; systems with random trading and zero profit expectancy &#8211; are added to the pool,  more positive results can be produced in steps 4 and 5, which reduces the probability that your selected strategy survives the test. WRC can determine rather good that a system is profitable, but can not as well determine that it is worthless.</li>
<li>It gets worse when variants have a negative expectancy.  WRC can then over-estimate Data Mining Bias (see paper 2 at the end of the article). This could theoretically also happen with our trend systems, as some variants may suffer from a phase reversal due to the delay by the smoothing indicators, and thus in fact trade against the trend instead of with it.</li>
</ul>
<h3>The Experiment</h3>
<p>First you need to collect daily return curves from all tested strategies. This requires adding a few lines to the <strong>Trend.c</strong> script from the <a href="http://www.financial-hacker.com/trend-and-exploiting-it/">previous article</a>:</p>
<pre class="prettyprint"><span style="color: #0000ff;">// some global variables</span>
int Period;
var Daily[3000];
...
<span style="color: #0000ff;">// in the run function, set all trading costs to zero</span>
 Spread = Commission = RollLong = RollShort = Slippage = 0;<span style="color: #0000ff;">
...
// store daily results in an equity curve</span>
  Daily[Day] = Equity;
}
...
<span style="color: #0000ff;">// in the objective function, save the curves in a file for later evaluation</span>
string FileName = "Log\\TrendDaily.bin";
string Name = strf("%s_%s_%s_%i",Script,Asset,Algo,Period);
int Size = Day*sizeof(var); 
file_append(FileName,Name,strlen(Name)+1);
file_append(FileName,&amp;Size,sizeof(int));
file_append(FileName,Daily,Size);</pre>
<p>The second part of the above code stores the equity at the end of any day in the <strong>Daily</strong> array. The third part stores a string with the name of the strategy, the length of the curve,  and the equity values itself in a file named <strong>TrendDaily.bin</strong> in the <strong>Log</strong> folder. After running the 10 trend scripts, all 900 resulting curves are collected together in the file.</p>
<p>The next part of our experiment is the <strong>Bootstrap.c</strong> script that applies White&#8217;s Reality Check. I&#8217;ll write it in two parts. The first part just reads the 900 curves from the <strong>TrendDaily.bin</strong> file, stores them for later evaluation, finds the best one and displays a histogram of the profit factors. Once we got that, we did already 80% of the work for the Reality Check. This is the code:</p>
<pre class="prettyprint">void _plotHistogram(string Name,var Value,var Step,int Color)
{
  var Bucket = floor(Value/Step);
  plotBar(Name,Bucket,Step*Bucket,1,SUM+BARS+LBL2,Color);
}

typedef struct curve
{
  string Name;
  int Length;
  var *Values;
} curve;

curve Curve[900];
var Daily[3000];

void main()
{
  byte *Content = file_content("Log\\TrendDaily.bin");
  int i,j,N = 0;
  int MaxN = 0;
  var MaxPerf = 0.0;
	
  while(N&lt;900 &amp;&amp; *Content)
  {
<span style="color: #0000ff;">// extract the next curve from the file</span>
    string Name = Content;
    Content += strlen(Name)+1;
    int Size = *((int*)Content);
    int Length = Size/sizeof(var); // number of values
    Content += 4;
    var *Values = Content;
    Content += Size;

<span style="color: #0000ff;">// store and plot the curve</span>		
    Curve[N].Name = Name;
    Curve[N].Length = Length;
    Curve[N].Values = Values;
    var Performance = 1.0/ProfitFactor(Values,Length);
    printf("\n%s: %.2f",Name,Performance);
    _plotHistogram("Profit",Performance,0.005,RED);

<span style="color: #0000ff;">// find the best curve</span>		
    if(MaxPerf &lt; Performance) {
      MaxN = N; MaxPerf = Performance;
    }
    N++;
  }
  printf("\n\nBenchmark: %s, %.2f",Curve[MaxN].Name,MaxPerf); 
}</pre>
<p>Most of the code is just for reading and storing all the equity curves. The indicator <strong>ProfitFactor </strong>calculates the profit factor of the curve, the sum of all daily wins divided by the sum of all daily losses. However, here we need to consider the array order. Like many platforms, Zorro stores time series in reverse chronological order,  with the most recent data at the begin. However we stored the daily equity curve in straight chronological order. So the losses are actually wins and the wins actually losses, which is why we need to inverse the profit factor. The curve with the best profit factor will be our benchmark for the test.</p>
<p>This is the resulting histogram, the profit factors of all 900 (or rather, 705 due to the trade number minimum) equity curves:</p>
<figure id="attachment_244" aria-describedby="caption-attachment-244" style="width: 833px" class="wp-caption alignnone"><a href="http://www.financial-hacker.com/wp-content/uploads/2015/09/trend_s.png"><img loading="lazy" decoding="async" class="wp-image-244 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/09/trend_s.png" alt="" width="833" height="201" srcset="https://financial-hacker.com/wp-content/uploads/2015/09/trend_s.png 833w, https://financial-hacker.com/wp-content/uploads/2015/09/trend_s-300x72.png 300w" sizes="auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a><figcaption id="caption-attachment-244" class="wp-caption-text">Profit factor distribution (without trade costs)</figcaption></figure>
<p>Note that the profit factors are slightly different to the parameter charts of the previous article because they were now calculated from daily returns, not from trade results. We removed trading costs, so the histogram is centered at a profit factor 1.0, aka zero profit. Only a few systems achieved a profit factor in the 1.2 range, the two best made about 1.3. Now we&#8217;ll see what White has to say to that. This is the rest of the <strong>main</strong> function in <strong>Bootstrap.c</strong> that finally applies his Reality Check:</p>
<pre>plotBar("Benchmark",MaxPerf/0.005,MaxPerf,50,BARS+LBL2,BLUE);	
printf("\nBootstrap - please wait");
int Worse = 0, Better = 0;
for(i=0; i&lt;1000; i++) {
  var MaxBootstrapPerf = 0;
  for(j=0; j&lt;N; j++) {
    randomize(BOOTSTRAP|DETREND,Daily,Curve[j].Values,Curve[j].Length);
    var Performance = 1.0/ProfitFactor(Daily,Curve[j].Length);
    MaxBootstrapPerf = max(MaxBootstrapPerf,Performance);
  }
  if(MaxPerf &gt; MaxBootstrapPerf)
    Better++;
  else
    Worse++;
  _plotHistogram("Profit",MaxBootstrapPerf,0.005,RED);
  progress(100*i/SAMPLES,0);
}
printf("\nBenchmark beats %.0f%% of samples!",
  (var)Better*100./(Better+Worse));
</pre>
<p>This code needs about 3 minutes to run; we&#8217;re sampling the 705 curves 1000 times. The <strong>randomize</strong> function will shuffle the daily returns by bootstrap with replacement; the <strong>DETREND</strong> flag tells it to subtract the mean return from all returns before. The number of random curves that are better and worse than the benchmark is stored, for printing the percentage at the end. The <strong>progress</strong> function moves the progress bar while Zorro grinds through the 705,000 curves. And this is the result:</p>
<figure id="attachment_245" aria-describedby="caption-attachment-245" style="width: 703px" class="wp-caption alignnone"><a href="http://www.financial-hacker.com/wp-content/uploads/2015/09/bootstrap_s.png"><img loading="lazy" decoding="async" class="wp-image-245 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/09/bootstrap_s.png" alt="" width="703" height="201" srcset="https://financial-hacker.com/wp-content/uploads/2015/09/bootstrap_s.png 703w, https://financial-hacker.com/wp-content/uploads/2015/09/bootstrap_s-300x86.png 300w" sizes="auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a><figcaption id="caption-attachment-245" class="wp-caption-text">Bootstrap results (red), benchmark system (black)</figcaption></figure>
<p>Hmm. We can see that the best system &#8211; the black bar &#8211; is at the right side of the histogram, indicating that it might be significant. But only with about 80% probability (the script gives a slightly different result every time due to the randomizing). 20% of the random curves achieve better profit factors than the best system from the experiment. The median of the randomized samples is about 1.26. Only the two best systems from the original distribution (first image) have profit factors above 1.26 &#8211; all the rest is at or below the bootstrap median.</p>
<p>So we have to conclude that this simple way of trend trading does not really work. Interestingly, one of those 900 tested systems is a system that I use for myself since 2012, although with additional filters and conditions. This system has produced good live returns and a positive result by the end of every year so far. And there&#8217;s still the fact that EUR/USD and silver in all variants produced better statistics than S&amp;P500. This hints that some trend effect exists in their price curves, but the profit factors by the simple algorithms are not high enough to pass White&#8217;s Reality Check. We need a better approach for trend exploitation. For instance, a filter that detects if trend is there or not. This will be the topic of the <a href="http://www.financial-hacker.com/the-market-meanness-index/" target="_blank" rel="noopener noreferrer">next articl</a>e of this series. We will see that a filter can have a surprising effect on reality checks. Since we now have the <strong>Bootstrap </strong>script for applying White&#8217;s Reality Check, we can quickly do further experiments.</p>
<p>The <strong>Bootstrap.c</strong> script has been added to the 2015 script collection downloadable on the sidebar.</p>
<h3>Conclusion</h3>
<ul style="list-style-type: square;">
<li>None of the 10 tested low-lag indicators, and none of the 3 tested markets shows significant positive expectancy with trend trading.</li>
<li>There is evidence of a trend effect in currencies and commodities, but it is too weak or too infrequent for being effectively exploited with simple trade signals by a filtered price curve.</li>
<li>We have now a useful code framework for comparing indicators and assets, and for further experiments with trade strategies.</li>
</ul>
<h3>Papers</h3>
<ol>
<li>Original paper by Dr. H. White:  <a href="http://www.ssc.wisc.edu/~bhansen/718/White2000.pdf" target="_blank" rel="noopener noreferrer">White2000</a></li>
<li>WRC modification by P. Hansen: <a href="http://www-siepr.stanford.edu/workp/swp05003.pdf" target="_blank" rel="noopener noreferrer">Hansen2005</a></li>
<li>Stepwise WRC Testing by J. Romano, M. Wolf: <a href="http://www.ssc.wisc.edu/~bhansen/718/RomanoWolf2005.pdf" target="_blank" rel="noopener noreferrer">RomanoWolf2005</a></li>
<li>Technical Analysis examined with WRC, by P. Hsu, C. Kuan: <a href="http://front.cc.nctu.edu.tw/Richfiles/15844-930305.pdf" target="_blank" rel="noopener noreferrer">HsuKuan2006</a></li>
<li>WRC and its Extensions by V. Corradi, N. Swanson: <a href="http://econweb.rutgers.edu/nswanson/papers/corradi_swanson_whitefest_1108_2011_09_06.pdf" target="_blank" rel="noopener noreferrer">CorradiSwanson2011</a></li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://financial-hacker.com/whites-reality-check/feed/</wfw:commentRss>
			<slash:comments>32</slash:comments>
		
		
			</item>
		<item>
		<title>The Trend Experiment</title>
		<link>https://financial-hacker.com/trend-and-exploiting-it/</link>
					<comments>https://financial-hacker.com/trend-and-exploiting-it/#comments</comments>
		
		<dc:creator><![CDATA[jcl]]></dc:creator>
		<pubDate>Mon, 07 Sep 2015 06:44:42 +0000</pubDate>
				<category><![CDATA[Research]]></category>
		<category><![CDATA[System Development]]></category>
		<category><![CDATA[System Evaluation]]></category>
		<category><![CDATA[Decycler]]></category>
		<category><![CDATA[Experiment]]></category>
		<category><![CDATA[Low-Lag]]></category>
		<category><![CDATA[Momentum]]></category>
		<guid isPermaLink="false">http://www.financial-hacker.com/?p=53</guid>

					<description><![CDATA[This is the second part of the trend experiment article series, involving 900 systems and 10 different &#8220;smoothing&#8221; or &#8220;low-lag&#8221; indicators for finding out if trend really exists and can be exploited by a simple algorithmic system. When you do such an experiment, you have normally some expectations about the outcome, such as: Trend exists, but is difficult &#8230; <a href="https://financial-hacker.com/trend-and-exploiting-it/" class="more-link">Continue reading<span class="screen-reader-text"> "The Trend Experiment"</span></a>]]></description>
										<content:encoded><![CDATA[<p>This is the second part of the <a href="http://www.financial-hacker.com/trend-delusion-or-reality/">trend experiment</a> article series, involving 900 systems and 10 different &#8220;smoothing&#8221; or &#8220;low-lag&#8221; indicators for finding out if trend really exists and can be exploited by a <strong>simple algorithmic system</strong>. When you do such an experiment, you have normally some expectations about the outcome, such as:<span id="more-53"></span></p>
<ul style="list-style-type: square;">
<li>Trend exists, but is difficult to detect and to exploit. The experiment will find only a few profitable and a lot more unprofitable systems (with realistic trade costs).</li>
<li>More sophisticated indicators, such as the Decycler or the Lowpass filter, will produce better results than the old SMA, EMA, or HMA. Modern indicators have less lag and thus react faster on the begin and end of a trend.</li>
<li>White&#8217;s Reality Check will reveal a data mining bias rather close to the returns of the best systems from the experiment. If algorithmic trend trading were easy, anyone would be doing it.</li>
<li>EUR/USD will return better results because according to trader&#8217;s wisdom, currencies are &#8220;more trending&#8221;.</li>
</ul>
<p>However the results were quite a surprise.</p>
<h3>The Trend Test System</h3>
<p>This is the script <strong>Trend.c</strong> used for the trend experiment:</p>
<pre class="prettyprint">var objective() 
{ 
  return WinTotal/max(1,LossTotal); <span style="color: #0000ff;">// Profit factor</span>
}

var filter(var* Data,int Period);

void run()
{
  set(PARAMETERS|LOGFILE);
  PlotHeight1 = 200;
  PlotScale = 8;
  ColorBars[1] = BLACK; <span style="color: #0000ff;">// winning trades</span>
  ColorBars[2] = GREY; <span style="color: #0000ff;">// losing trades</span>

  StartDate = 2010;
  BarPeriod = 15;
  LookBack = 80*4*24; <span style="color: #0000ff;">// 80 trading days ~ 4 months</span>
	
  while(asset(loop("EUR/USD","SPX500","XAG/USD")))
  while(algo(loop("M15","H1","H4")))
  {
    if(Algo == "M15")
      TimeFrame = 1; // 15 minutes
    else if(Algo == "H1")
      TimeFrame = 4; // 1 hour
    else if(Algo == "H4")
      TimeFrame = 16;	// 4 hours

    int Periods[10] = { 10,20,50,100,200,500,1000,2000,5000,10000 };
    int Period = Periods[optimize(0,0,9,1)];
		
    vars Prices = series(price());
    vars Smoothed = series(filter(Prices,Period));

    if(valley(Smoothed))
      enterLong();
    else if(peak(Smoothed))
      enterShort();
  } 
}</pre>
<p>This script is supposed to run in Zorro&#8217;s &#8220;Train&#8221; mode. We&#8217;re not really training the systems, but Train mode produces parameter histograms, and that&#8217;s what we want. The script is basically the same as described in the <a href="http://www.financial-hacker.com/trend-delusion-or-reality/">previous article</a>, but two asset and algo loops are now used for cycling through three different assets (EUR/USD, S&amp;P 500, and Silver) and three time frames (15 minutes, 1 hour, 4 hours). The <strong>optimize</strong> function selects the time period of the smoothing indicator, in 10 steps from 10 to 10,000 time frames. The meaning of the Zorro-specific functions like <strong>asset</strong>, <strong>algo</strong>, <strong>loop</strong>, <strong>optimize</strong> can be found in the <a href="http://manual.zorro-trader.com" target="_blank" rel="noopener noreferrer">Zorro manual</a>.</p>
<p>6 years of price history from 2010 to 2015 are used for the simulation. The default trade costs &#8211; commission, bid/ask spread, and rollover &#8211; are taken from the average 2015 parameters of a FXCM microlot account. FXCM is not the cheapest broker, so the expectation value of a random-trading simulation is not zero, but a loss, dependent on the number of trades. For comparing results we&#8217;re using the profit factor, calculated in the <strong>objective</strong> function. The script calls a <strong>filter</strong> function that is defined as a prototype, and contained in a main script that includes <strong>Trend.c</strong>. So any of the indicators is represented by a very short main script like this (<strong>TrendLowpass.c</strong>):</p>
<pre class="prettyprint">#include "Strategy\Trend.c"

var filter(var* Data,int Period)
{
  return LowPass(Data,Period);
}</pre>
<p>All the scripts can be downloaded from the <strong>scripts2015</strong> archive at the sidebar. There&#8217;s also a batch file included that starts them all and lets them run in parallel.</p>
<h3>The Results</h3>
<p>When you select one of the scripts and click Zorro&#8217;s  <strong>[Train]</strong> button, it will grind its wheels about 10 minutes and then spit out a sheet of histograms like this (for the ZMA):</p>
<p><a href="http://www.financial-hacker.com/wp-content/uploads/2015/09/ZMA.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-159" src="http://www.financial-hacker.com/wp-content/uploads/2015/09/ZMA.png" alt="ZMA" width="1253" height="641" srcset="https://financial-hacker.com/wp-content/uploads/2015/09/ZMA.png 1253w, https://financial-hacker.com/wp-content/uploads/2015/09/ZMA-300x153.png 300w, https://financial-hacker.com/wp-content/uploads/2015/09/ZMA-1024x524.png 1024w, https://financial-hacker.com/wp-content/uploads/2015/09/ZMA-1200x614.png 1200w" sizes="auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>We got 9 histograms from the combinations of EUR/USD, S&amp;P 500, and Silver (horizontally) with bar sizes of 15 minutes, 1 hour, and 4 hours. The red bars are the <strong>objective</strong> return &#8211; in this case, the <strong>profit factor</strong>,  total win divided by total loss. If they are above <strong>1.0</strong> (left scale), the system was profitable. The black and grey bars are the number of winning and losing trades (right scale). The steps on the X axis are the indicator time period; they normally don&#8217;t go all the way to 10 because systems are discarded when the time period exceeded 4 months or the system entered less than 30 trades. That&#8217;s why the experiment didn&#8217;t produce 900 systems, but only 705.</p>
<p>We can see that the profit generally increases, and the number of trades decreases with the time frame. As typical for trend trading systems we got far more losing trades (grey) than winning trades (black). 13 of the 82 systems in the histograms above have been profitable, 69 were losers. Most of the profitable systems traded EUR/USD. Only one S&amp;P 500 system, and only three silver trading systems produced any profit. Here&#8217;s a statistic of all winners and losers from the 705 tested systems:</p>
<table>
<tbody>
<tr>
<td>Asset, Period, Indicator</td>
<td style="text-align: right;">Rate</td>
<td style="text-align: right;">Total</td>
<td style="text-align: right;">Won</td>
<td style="text-align: right;">Lost</td>
</tr>
<tr>
<td><strong>EUR/USD</strong></td>
<td style="text-align: right;"><strong>38%</strong></td>
<td style="text-align: right;"><strong>237</strong></td>
<td style="text-align: right;"><strong>89</strong></td>
<td style="text-align: right;"><strong>148</strong></td>
</tr>
<tr>
<td><strong>S&amp;P 500</strong></td>
<td style="text-align: right;"><strong>3%</strong></td>
<td style="text-align: right;"><strong>237</strong></td>
<td style="text-align: right;"><strong>6</strong></td>
<td style="text-align: right;"><strong>231</strong></td>
</tr>
<tr>
<td><strong>Silver</strong></td>
<td style="text-align: right;"><strong>21%</strong></td>
<td style="text-align: right;"><strong>231</strong></td>
<td style="text-align: right;"><strong>48</strong></td>
<td style="text-align: right;"><strong>183</strong></td>
</tr>
<tr>
<td><strong>15 Minutes</strong></td>
<td style="text-align: right;"><strong>14%</strong></td>
<td style="text-align: right;"><strong>297</strong></td>
<td style="text-align: right;"><strong>41</strong></td>
<td style="text-align: right;"><strong>256</strong></td>
</tr>
<tr>
<td><strong>1 Hour</strong></td>
<td style="text-align: right;"><strong>20%</strong></td>
<td style="text-align: right;"><strong>239</strong></td>
<td style="text-align: right;"><strong>48</strong></td>
<td style="text-align: right;"><strong>191</strong></td>
</tr>
<tr>
<td><strong>4 Hours</strong></td>
<td style="text-align: right;"><strong>32%</strong></td>
<td style="text-align: right;"><strong>169</strong></td>
<td style="text-align: right;"><strong>54</strong></td>
<td style="text-align: right;"><strong>115</strong></td>
</tr>
<tr>
<td><strong>ALMA</strong></td>
<td style="text-align: right;"><strong>16%</strong></td>
<td style="text-align: right;"><strong>64</strong></td>
<td style="text-align: right;"><strong>10</strong></td>
<td style="text-align: right;"><strong>54</strong></td>
</tr>
<tr>
<td><strong>Decycle</strong></td>
<td style="text-align: right;"><strong>15%</strong></td>
<td style="text-align: right;"><strong>74</strong></td>
<td style="text-align: right;"><strong>11</strong></td>
<td style="text-align: right;"><strong>63</strong></td>
</tr>
<tr>
<td><strong>EMA</strong></td>
<td style="text-align: right;"><strong>20%</strong></td>
<td style="text-align: right;"><strong>69</strong></td>
<td style="text-align: right;"><strong>14</strong></td>
<td style="text-align: right;"><strong>55</strong></td>
</tr>
<tr>
<td><strong>HMA</strong></td>
<td style="text-align: right;"><strong>25%</strong></td>
<td style="text-align: right;"><strong>63</strong></td>
<td style="text-align: right;"><strong>16</strong></td>
<td style="text-align: right;"><strong>47</strong></td>
</tr>
<tr>
<td><strong>Laguerre</strong></td>
<td style="text-align: right;"><strong>31%</strong></td>
<td style="text-align: right;"><strong>32</strong></td>
<td style="text-align: right;"><strong>10</strong></td>
<td style="text-align: right;"><strong>22</strong></td>
</tr>
<tr>
<td><strong>LinearReg</strong></td>
<td style="text-align: right;"><strong>26%</strong></td>
<td style="text-align: right;"><strong>74</strong></td>
<td style="text-align: right;"><strong>19</strong></td>
<td style="text-align: right;"><strong>53</strong></td>
</tr>
<tr>
<td><strong>Lowpass</strong></td>
<td style="text-align: right;"><strong>20%</strong></td>
<td style="text-align: right;"><strong>71</strong></td>
<td style="text-align: right;"><strong>14</strong></td>
<td style="text-align: right;"><strong>57</strong></td>
</tr>
<tr>
<td><strong>SMA</strong></td>
<td style="text-align: right;"><strong>23%</strong></td>
<td style="text-align: right;"><strong> 70</strong></td>
<td style="text-align: right;"><strong> 16</strong></td>
<td style="text-align: right;"><strong> 54</strong></td>
</tr>
<tr>
<td><strong>Smooth</strong></td>
<td style="text-align: right;"><strong>19%</strong></td>
<td style="text-align: right;"><strong>108</strong></td>
<td style="text-align: right;"><strong>20</strong></td>
<td style="text-align: right;"><strong>88</strong></td>
</tr>
<tr>
<td><strong>ZMA</strong></td>
<td style="text-align: right;"><strong>16%</strong></td>
<td style="text-align: right;"><strong>82</strong></td>
<td style="text-align: right;"><strong>13</strong></td>
<td style="text-align: right;"><strong>69</strong></td>
</tr>
</tbody>
</table>
<p>Since the results are for 2010-2015, you might get different figures when testing different time periods. The <strong>Rate</strong> column shows the percentage of successful systems. We got a mix of expected and unexpected results. Almost 40% of the EUR/USD systems are winners,  which seems to confirm that currencies tend to trend. The S&amp;P 500 index however is not trending at all &#8211;  and this despite the fact that it shows the most significant trend in the long run, as visible in the title image. But here we&#8217;re looking for shorter term trends that can be exploited by day trading. Silver, with 20% winners, has at least some trend. Longer time frames produce dramatically better results, mostly due to less trade costs, but also partly because trend seems to prefer long cycles and low frequencies. (You can see that the difference comes not from trade costs alone when you test the systems with spread, commission, slippage, and rollover set to zero). 1-day bar periods would be even more profitable. But I haven&#8217;t included them in the test because they produce not enough trades for statistical significance.</p>
<p>The indicators show a surprising behavior. The old traditional indicators put up a good fight. Ehler&#8217;s smoothing, decycling, and zero-lag indicators, produce less profitable systems than their classic counterparts. However we&#8217;ll see later that the modern indicators are in fact more profitable, although within a smaller parameter range. But they all occupy the top of the profit list. The best systems, with modern indicators and long time frames, have profit factors up to <strong>2</strong>.</p>
<p>Does this mean that we can put them together in a compound system and will get rich? I don&#8217;t know, because I haven&#8217;t determined yet the Data Mining Bias produced by this experiment. For this we need to store and randomize the balance curves, and apply <strong>White&#8217;s Reality Check</strong>. This will be the topic of the <a href="http://www.financial-hacker.com/whites-reality-check/">next article</a> of the Trend Experiment series.</p>
<h3>Conclusion</h3>
<ul style="list-style-type: square;">
<li>Different markets show very different behavior. EUR/USD and silver are significantly more profitable with short-term trend following than S&amp;P500.</li>
<li>Low-lag smoothing indicators have a smaller profitable parameter range than traditional indicators, but produce higher profits.</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://financial-hacker.com/trend-and-exploiting-it/feed/</wfw:commentRss>
			<slash:comments>12</slash:comments>
		
		
			</item>
		<item>
		<title>Trend Indicators</title>
		<link>https://financial-hacker.com/trend-delusion-or-reality/</link>
					<comments>https://financial-hacker.com/trend-delusion-or-reality/#comments</comments>
		
		<dc:creator><![CDATA[jcl]]></dc:creator>
		<pubDate>Fri, 04 Sep 2015 16:48:13 +0000</pubDate>
				<category><![CDATA[Indicators]]></category>
		<category><![CDATA[System Evaluation]]></category>
		<category><![CDATA[Decycler]]></category>
		<category><![CDATA[Ehlers]]></category>
		<category><![CDATA[Low-Lag]]></category>
		<category><![CDATA[Momentum]]></category>
		<category><![CDATA[Zorro]]></category>
		<guid isPermaLink="false">http://www.lotter.org/hacker/?p=19</guid>

					<description><![CDATA[The most common trade method is &#8216;going with the trend&#8216;. While it&#8217;s not completely clear how one can go with the trend without knowing it beforehand, most traders believe that &#8216;trend&#8217; exists and can be exploited. &#8216;Trend&#8217; is supposed to manifest itself in price curves as a sort of momentum or inertia that continues a price &#8230; <a href="https://financial-hacker.com/trend-delusion-or-reality/" class="more-link">Continue reading<span class="screen-reader-text"> "Trend Indicators"</span></a>]]></description>
										<content:encoded><![CDATA[<p>The most common trade method is &#8216;<strong>going with the trend</strong>&#8216;. While it&#8217;s not completely clear how one can go with the trend without knowing it beforehand, most traders believe that &#8216;trend&#8217; exists and can be exploited. &#8216;Trend&#8217; is supposed to manifest itself in price curves as a sort of <strong>momentum</strong> or <strong>inertia</strong> that continues a price movement once it started. This inertia effect does not appear in random walk curves.<span id="more-19"></span> One can speculate about possible causes of trend, such as:</p>
<ul style="list-style-type: square;">
<li>Information spreads slowly, thus producing a delayed, prolonged reaction and price movement. (There are examples where it took the majority of traders <strong>more than a year</strong> to become aware of essential, fundamental information about a certain market!)</li>
<li>Events trigger other events with a similar effect on the price, causing a sort of avalanche effect.</li>
<li>Traders see the price move, shout &#8220;Ah! Trend!&#8221; and jump onto the bandwagon, thus creating a self fulfilling prophecy.</li>
<li>Trade algorithms detect a trend, attempt to exploit it and amplify it this way.</li>
<li>All of this, but maybe on different time scales.</li>
</ul>
<p>Whatever the cause, hackers prefer experiment over speculation, so let&#8217;s test once and for all if trend in price curves really exists and can be exploited in an algorithmic strategy. Exploiting trend obviously means buying at the begin of a trend, and selling at the end. For this, we simply assume that trend begins at the bottom of a price curve valley and ends at a peak, or vice versa. Obviously this assumption makes no difference between &#8216;real&#8217; trends and random price fluctuations. Such a difference could anyway only be determined in hindsight. However, trade profits and losses by random fluctuations should cancel out each other in the long run, at least when trade costs are disregarded. When trends exist in price curves, this method should produce an overall profit from the the remaining trades that are triggered by real trends and last longer than in random walk curves. And hopefully this profit will exceed the costs of the random trades. At least &#8211; that&#8217;s the theory. So we&#8217;re just looking for peaks and valleys of the price curve. The script of the trend following experiment would look like this (all scripts here are in C for the <a href="http://www.financial-hacker.com/hackers-tools-zorro-and-r/">Zorro</a> platform; <strong>var</strong> is typedef&#8217;d to <strong>double</strong>):</p>
<pre>void run()
{
  var *Price = series(price());
  var *Smoothed = series(Filter(Price,Period));
  
  if(valley(Smoothed))
    enterLong();
  else if(peak(Smoothed))
    enterShort();
}</pre>
<p>This strategy is simple enough. It is basically the first strategy from the <a href="http://manual.zorro-trader.com/tutorial_var.htm" target="_blank" rel="noopener noreferrer">Zorro tutorial</a>. The <strong>valley</strong> function returns <strong>true</strong> when the last price was below the current price and also below the last-but-one price; the <strong>peak</strong> function returns <strong>true</strong> when the last price was above the current and the last-but-one. Trades are thus entered at all peaks and valleys and closed by reversal only. For not getting too many random trades and too high trade costs, we&#8217;re removing the high frequencies from the price curve with some smoothing indicator, named <strong>Filter</strong> in the code above. Trend, after all, is supposed to be longer-lasting and should manifest itself in the lower frequencies. This is an example trade produced by this system: <a href="http://www.financial-hacker.com/wp-content/uploads/2015/09/work4_detail.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-195" src="http://www.financial-hacker.com/wp-content/uploads/2015/09/work4_detail.png" alt="work4_detail" width="680" height="321" srcset="https://financial-hacker.com/wp-content/uploads/2015/09/work4_detail.png 680w, https://financial-hacker.com/wp-content/uploads/2015/09/work4_detail-300x142.png 300w" sizes="auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a> The black jagged line in the chart above is the raw price curve, the red line is the filtered curve. You can see that it lags behind the black curve a little, which is typical of smoothing indicators. It has a peak at the end of September and thus entered a short trade (tiny green dot). The red line continues going down all the way until November 23, when a valley was reached. A long trade (not shown in this chart) was then entered and the short trade was closed by reversal (other tiny green dot). The green straight line connects the entry and exit points of the trade. It was open almost 2 months and made in that time a profit of ~ 13 cents per unit, or 1300 pips.</p>
<p>The only remaining question is &#8211; which indicator shall we use for filtering out the high frequencies, the ripples and jaggies, from the price curve? We&#8217;re spoilt for choice.</p>
<h3><strong>The Smoothing Candidates</strong></h3>
<p>Smoothing a curve in some way is a common task of all trend strategies. Consequently, there&#8217;s a multitude of smoothing, averaging, low-lag and spectral filter indicators at our disposal. We have to test them. The following candidates were selected for the experiment, traditional indicators as well as fancier algorithms:</p>
<ul>
<li><strong>SMA</strong>, the simple moving average, the sum of the last <strong>n</strong> prices divided by <strong>n</strong>.</li>
<li><strong>EMA</strong>, exponential moving average, the current price multiplied with a small factor plus the last EMA multiplied with a large factor. The sum of both factors must be <strong>1</strong>. This is a first order lowpass filter.</li>
<li><strong>LowPass</strong>, a second order lowpass filter with the following source code:
<pre>var LowPass(var *Data,int Period)
{
  var* LP = series(Data[0]);
  var a = 2.0/(1+Period);
  return LP[0] = (a-0.25*a*a)*Data[0]
    + 0.5*a*a*Data[1]
    - (a-0.75*a*a)*Data[2]
    + 2*(1.-a)*LP[1]
    - (1.-a)*(1.-a)*LP[2];
}</pre>
</li>
<li><strong>HMA</strong>, the Hull Moving Average, with the following source code:
<pre>var HMA(var *Data,int Period)
{
  return WMA(series(2*WMA(Data,Period/2)-WMA(Data,Period),sqrt(Period))
}</pre>
</li>
<li><strong>ZMA</strong>, Ehler&#8217;s Zero-Lag Moving Average, an EMA with a correction term for removing lag. This is the source code:
<pre>var ZMA(var *Data,int Period)
{
  var *ZMA = series(Data[0]);
  var a = 2.0/(1+Period);
  var Ema = EMA(Data,Period);
  var Error = 1000000;
  var Gain, GainLimit=5, BestGain=0;
  for(Gain = -GainLimit; Gain &lt; GainLimit; Gain += 0.1) {
     ZMA[0] = a*(Ema + Gain*(Data[0]-ZMA[1])) + (1-a)*ZMA[1];
     var NewError = Data[0] - ZMA[0];
     if(abs(Error) &lt; newError) {
       Error = abs(newError);
       BestGain = Gain;
     }
  }
  return ZMA[0] = a*(Ema + BestGain*(Data[0]-ZMA[1])) + (1-a)*ZMA[1];
}</pre>
</li>
<li><strong>ALMA</strong>, Arnaud Legoux Moving Average, based on a shifted Gaussian distribution (described in <a href="http://www.forexfactory.com/attachment.php?attachmentid=1123528&amp;d=1359078631" target="_blank" rel="noopener noreferrer">this paper</a>):
<pre>var ALMA(var *Data, int Period)
{
  var m = floor(0.85*(Period-1));
  var s = Period/6.0;
  var alma = 0., wSum = 0.;
  int i;
  for (i = 0; i &lt; Period; i++) {
    var w = exp(-(i-m)*(i-m)/(2*s*s));
    alma += Data[Period-1-i] * w;
    wSum += w;
  }
  return alma / wSum;
}</pre>
</li>
<li><strong>Laguerre</strong>, a 4-element Laguerre filter:
<pre>var Laguerre(var *Data, var alpha)
{
  var *L = series(Data[0]);
  L[0] = alpha*Data[0] + (1-alpha)*L[1];
  L[2] = -(1-alpha)*L[0] + L[1] + (1-alpha)*L[2+1];
  L[4] = -(1-alpha)*L[2] + L[2+1] + (1-alpha)*L[4+1];
  L[6] = -(1-alpha)*L[4] + L[4+1] + (1-alpha)*L[6+1];
  return (L[0]+2*L[2]+2*L[4]+L[6])/6;
}</pre>
</li>
<li><strong>Linear regression</strong>, fits a straight line between the data points in a way that the distance between each data point and the line is minimized by the least-squares rule.</li>
<li><strong>Smooth</strong>, John Ehlers&#8217; &#8220;Super Smoother&#8221;, a 2-pole Butterworth filter combined with a 2-bar SMA that suppresses the Nyquist frequency:
<pre>var Smooth(var *Data,int Period)
{
  var f = (1.414*PI) / Period;
  var a = exp(-f);
  var c2 = 2*a*cos(f);
  var c3 = -a*a;
  var c1 = 1 - c2 - c3;
  var *S = series(Data[0]);
  return S[0] = c1*(Data[0]+Data[1])*0.5 + c2*S[1] + c3*S[2];
}</pre>
</li>
<li><strong>Decycle</strong>, another low-lag indicator by John Ehlers. His decycler is simply the difference between the price and its fluctuation, retrieved with a highpass filter:
<pre>var Decycle(var* Data,int Period)
{
  return Data[0]-HighPass2(Data,Period);
}</pre>
</li>
</ul>
<p>The above source codes have been taken from the <strong>indicators.c</strong> file of the Zorro platform, which contains source codes of all supplied indicators.</p>
<h3>Comparing Step Responses</h3>
<p>What is the best of all those indicators? For a first impression here&#8217;s a chart showing them reacting on a simulated sudden price step. You can see that some react slow, some very slow, some fast, and some overshoot: <a href="http://www.financial-hacker.com/wp-content/uploads/2015/09/LowLag_EURUSD.png"><img loading="lazy" decoding="async" class="alignnone wp-image-139 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/09/LowLag_EURUSD.png" alt="" width="795" height="351" srcset="https://financial-hacker.com/wp-content/uploads/2015/09/LowLag_EURUSD.png 795w, https://financial-hacker.com/wp-content/uploads/2015/09/LowLag_EURUSD-300x132.png 300w" sizes="auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a> You can generate such a step response diagram with this Zorro script:</p>
<pre>// compare the step responses of some low-lag MAs
function run()
{
  set(PLOTNOW);
  BarPeriod = 60;
  MaxBars = 1000;
  LookBack = 150;
  asset("");   // don't load an asset
  ColorUp = ColorDn = 0;  // don't plot a price curve
  PlotWidth = 800;
  PlotHeight1 = 400;

  var *Impulse = series(ifelse(Bar&gt;200 &amp;&amp; Bar&lt;400,1,0)); // 0-&gt;1 impulse
  int Period = 50;
  plot("Impulse",Impulse[0],0,GREY);
  plot("SMA",SMA(Impulse,Period),0,BLACK);
  plot("EMA",EMA(Impulse,Period),0,0x808000);
  plot("ALMA",ALMA(Impulse,Period),0,0x008000);
  plot("Laguerre",Laguerre(Impulse,4.0/Period),0,0x800000);
  plot("Hull MA",HMA(Impulse,Period),0,0x00FF00);
  plot("Zero-Lag MA",ZMA(Impulse,Period),0,0x00FFFF); 
  plot("Decycle",Decycle(Impulse,Period),0,0xFF00FF);
  plot("LowPass",LowPass(Impulse,Period),0,0xFF0000);
  plot("Smooth",Smooth(Impulse,Period),0,0x0000FF);
}</pre>
<p>We can see that from all the indicators, the <strong>ALMA</strong> seems to be the best representation of the step, while the <strong>ZMA</strong> produces the fastest response with no overshoot, the <strong>Decycler</strong> the fastest with some overshoot, and <strong>Laguerre</strong> lags a lot behind anything else. Obviously, all this has not much meaning because the time period parameters of the indicators are not really comparable. So the step response per se does not reveal if the indicator is well suited for trend detection. We have no choice: We must use them all.</p>
<h3>The Trend Experiment</h3>
<p>For the experiment, all smoothing indicators above will be applied to a currency, a stock index, and a commodity, and will compete in exploiting trend. Because different time frames can represent different trader groups and thus different markets, the indicators will be applied to price curves made of 15-minutes, 1-hour, and 4-hours bars. And we&#8217;ll also try different indicator time periods in 10 steps from 10 to 10000 bars.</p>
<p>So we&#8217;ll have to program 10 indicators * 3 assets * 3 bar sizes * 10 time periods = 900 systems. Some of the 900 results will be positive, some negative, and some zero. If there are no significant positive results, we&#8217;ll have to conclude that trend in price curves either does not exist, or can at least not be exploited with this all-too-obvious method. However we&#8217;ll likely get some winning systems, if only for statistical reasons.</p>
<p>The next step will be checking if their profits are for real or just caused by a statistical effect dubbed <strong>Data Mining Bias</strong>. There is a method to measure Data Mining Bias from the resulting equity curves: the notorious <strong>White&#8217;s Reality Check</strong>. We&#8217;ll apply that check to the results of our experiment. If some systems survive White&#8217;s Reality Check, we&#8217;ll have the once-and-for-all proof that markets are ineffective, trends really exist, and algorithmic trend trading works.</p>
<p><a href="http://www.financial-hacker.com/trend-and-exploiting-it/">Next Step</a>&#8230;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://financial-hacker.com/trend-delusion-or-reality/feed/</wfw:commentRss>
			<slash:comments>15</slash:comments>
		
		
			</item>
	</channel>
</rss>
