<?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>CHF &#8211; The Financial Hacker</title>
	<atom:link href="https://financial-hacker.com/tag/chf/feed/" rel="self" type="application/rss+xml" />
	<link>https://financial-hacker.com</link>
	<description>A new view on algorithmic trading</description>
	<lastBuildDate>Sat, 28 Oct 2017 08:00:03 +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>CHF &#8211; The Financial Hacker</title>
	<link>https://financial-hacker.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<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 fetchpriority="high" 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="(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 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="(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 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="(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="(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="(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="(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>Build Better Strategies!</title>
		<link>https://financial-hacker.com/build-better-strategies/</link>
					<comments>https://financial-hacker.com/build-better-strategies/#comments</comments>
		
		<dc:creator><![CDATA[jcl]]></dc:creator>
		<pubDate>Mon, 09 Nov 2015 10:27:03 +0000</pubDate>
				<category><![CDATA[Introductory]]></category>
		<category><![CDATA[No Math]]></category>
		<category><![CDATA[System Development]]></category>
		<category><![CDATA[CHF]]></category>
		<category><![CDATA[Economy]]></category>
		<category><![CDATA[Grid trading]]></category>
		<guid isPermaLink="false">http://www.financial-hacker.com/?p=799</guid>

					<description><![CDATA[Enough blog posts, papers, and books deal with how to properly optimize and test trading systems. But there is little information about how to get to such a system in the first place. The described strategies often seem to have appeared out of thin air. Does a trading system require some sort of epiphany? Or is &#8230; <a href="https://financial-hacker.com/build-better-strategies/" class="more-link">Continue reading<span class="screen-reader-text"> "Build Better Strategies!"</span></a>]]></description>
										<content:encoded><![CDATA[<p>Enough blog posts, papers, and books deal with how to properly optimize and test trading systems. But there is little information about how to get to such a system in the first place. The described strategies often seem to have appeared out of thin air. Does a trading system require some sort of epiphany? Or is there a systematic approach to developing it?<br />   This post is the first of a small series in which I&#8217;ll attempt a methodical way to build trading strategies. The first part deals with the two main methods of strategy development, with market hypotheses and with a Swiss Franc case study.<span id="more-799"></span></p>
<h3>Strategies come in two flavors</h3>
<p>You can use mainly two methods to develop trading systems: <strong>model-based</strong> and <strong>data-mining</strong>. A model-based system starts with a model of a <strong>market inefficiency</strong> &#8211; based on trader psychology, economy, market microstructure, or any other price affecting force. The inefficiency produces a price curve anomaly or pattern that deviates from the random walk and can &#8211; when predictive &#8211; be used for a trade algorithm. Examples of model based trading methods are trend following, mean reversion, price cycles, price clusters, statistical arbitrage, and seasonality.</p>
<p>The problem: A model is not the reality. It is a simplified image of it. It can not be proven and can often not even be falsified. Its validity can only be determined by its effects on the price curve. The usefulness of this method thus depends on the significance and long-term stability of its price curve anomalies. For judging this you need good test algorithms. </p>
<p>The <strong>pure data mining method</strong> works the other way around. It just looks for price curve patterns and attempts to fit an algorithm to them. By which market forces the patterns are caused is of no interest; only assumption is that patterns of the past will repeat in the future. This allows the generation of trade systems, often, but not always with machine learning software. The most popular methods in this approach are trial-and-error TA, candle patterns, regression, autocorrelation, k-means clustering, neural networks, support vector machines, and decision trees.</p>
<p>The advantage of data mining is that you do not need to care about market hypotheses. The disadvantage: those methods usually find a vast amount of random patterns and thus generate a vast amount of worthless strategies. Since mere data mining is a blind approach, distinguishing real patterns &#8211; caused by real market inefficiencies &#8211; from random patterns is a challenging task. Even sophisticated <a href="http://www.financial-hacker.com/whites-reality-check/">reality checks</a> can normally not eliminate all data mining bias. Not many successful trading systems generated by data mining methods are known today.</p>
<h3>Are you cleverer than the market?</h3>
<p>Obviously, no trading system would work when market inefficiencies do not exist. And it would not work either when they exist, but can not be exploited since better equipped players are doing that already. In this first part of the mini-series I look into the possibility of <strong>trading better than the majority</strong> of market participants, a prerequisite of a successful strategy. </p>
<p>The three hypotheses of market efficiency that you&#8217;ll hear from time to time are as follows: </p>
<ul style="list-style-type: square;">
<li><strong>Hypothesis A: The markets are efficient.</strong> Prices follow real events, such as the publication of company results, and reflect the real value of the asset. All traders are &#8216;informed&#8217;, decide rationally and act immediately. Price curves are mostly random-walk curves with no information for predicting future prices. Technical trading systems can not work, or if they do, it&#8217;s just luck.<br />  </li>
<li><strong>Hypothesis B: The markets are not efficient, but their inefficiencies are of no value</strong> for private traders. Only large trading firms and hedge funds can exploit them successfully, since they have lots of capital, very fast computers, very experienced analysts and very clever quants &#8211; much more intelligent than you. Beware of entering their terrain, or else you&#8217;ll become their prey.<br />  </li>
<li><strong>Hypothesis C: Enough market inefficiencies are free for you to exploit.</strong> Large trading firms and hedge funds are too slow and cumbersome to tackle them effectively. Their capital and their fast computers give them no real advantage in the game that you&#8217;re going to play. Neither do their clueless analysts, overpaid traders, and overestimated quants.</li>
</ul>
<p>Not many today do still believe in hypothesis A. It can be easily shown that most price curves do not follow a random walk (a fellow blogger recently posted a great article about <a href="http://www.turingfinance.com/hacking-the-random-walk-hypothesis/" target="_blank">Hacking the Random Walk Hypothesis</a>). And the markets are anything but rational or effective. Counter-examples are plenty. Jack Schwager, in his book &#8216;Market Sense and Nonsense&#8217;, listed cases of <strong>blatant market dumbness and grotesque analyst failures</strong>. More often than not, asset prices are far, far away from their true value. Although all this is anecdotical evidence, a pattern is visible. The markets react fast and firm when rumors or news give them a clear direction. But when the information is a little more subtle and requires a minimum of interpretation, they react slow or not at all. Here&#8217;s the story of a typical example.</p>
<h3>The Swiss Franc case</h3>
<p>In September 2011 the Swiss National Bank established a price cap to the Swiss Franc. Purpose was protecting the tourism and export industries against an overvalued currency. The limit was set to an EUR/CHF price of 1.20, and the SNB vowed to defend it against all enemies.</p>
<p>A price cap is a <strong>rare and striking market inefficiency</strong>. It can immediately be translated into a highly profitable, almost risk-free trading system (how this works is explained below). So you would normally expect a strong market reaction after the EUR/CHF price move to 1.20. But the reaction was a long time in the coming.</p>
<p>No doubt, Switzerland is an obscure European country and for the major US trading firms probably known for cheese, if at all. They did either not notice the price cap, or they had just forgotten to equip their European offices with modern communication gear. So it took the mounted messenger from Europe three months riding over hill and dale, sailing over the Atlantic Ocean, maybe fighting off brigands, pirates, and indians on his way, to reach New York City and shout: &#8220;The Swiss have a price cap!&#8221;.</p>
<p>But what the heck can you do with a price cap? By January 2012, large market participants had finally come up with an idea. Not something as subtle as a trading system. Instead, they began to buy mad amounts of Francs for bringing pressure on the EUR/CHF price: </p>
<figure style="width: 879px" class="wp-caption alignnone"><img loading="lazy" decoding="async" class="alignnone wp-image-869 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/11/chf1.png" alt="" width="879" height="321" /><figcaption class="wp-caption-text">EUR/CHF price curve, September 2011 &#8211; August 2012</figcaption></figure>
<p>The obvious idea was that when there is a price boundary, there must be some profit in breaking it. A lot of effort, patience and money was put in that game. From May 2012 on the EUR/CHF price was nailed shut to its 1.20 limit. But alas, the price cap collapse did not happen. You do not mess with the SNB. During 2012 the Swiss erected a <strong>wall of 200 billion dollars</strong> for defending the price cap. The attackers never had a chance. The first gave up in September 2012, and by the end of January 2013 all had retreated with their tails between their legs (and probably painful losses):</p>
<figure id="attachment_869" aria-describedby="caption-attachment-869" style="width: 879px" class="wp-caption alignnone"><a href="http://www.financial-hacker.com/wp-content/uploads/2015/11/chf2.png"><img loading="lazy" decoding="async" class="wp-image-869 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/11/chf2.png" alt="" width="879" height="321" srcset="https://financial-hacker.com/wp-content/uploads/2015/11/chf2.png 879w, https://financial-hacker.com/wp-content/uploads/2015/11/chf2-300x110.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a><figcaption id="caption-attachment-869" class="wp-caption-text">EUR/CHF price curve, September 2012 &#8211; May 2013</figcaption></figure>
<p>Now the way was free for algorithmic systems. During the 2012 CHF battle they were forced to inactivity, since private traders and hackers lack the capital to participate in a market manipulation game. In January 2013 the first hackers started to exploit the market inefficiency with a specific method, a <strong>Grid Trader</strong>.<a id="gridtrader"></a> This turned out a money-printing machine.</p>
<h3>The money press algorithm</h3>
<p>A grid trader is a very simple system. It places pending long and short trades at a fixed grid above and below the current price, with profit targets of the same grid distance. So trades are opened and closed whenever the price crosses a grid line in any direction. Such a system has a hypothetical 100% win rate, since trades close either in profit or not at all. But grid traders normally use a <strong>virtual hedging mechanism</strong> that closes an open position instead of opening a new one in opposite direction. This improves the total profit by reducing trade costs and margin. But it allows trades to be closed with a loss. So the real win rate of a grid trader is in the 60% area.</p>
<p>This is the Zorro script of such a grid trader:</p>
<pre class="prettyprint">// helper function to check if the grid line has no trade
bool isFree(var Price,var Grid,bool IsShort)
{
  bool result = true;
  for(open_trades) {
    if(TradeIsShort == IsShort
      &amp;&amp; between(TradeEntryLimit,Price-Grid/2,Price+Grid/2))
        result = false;
  }
  return result;
}

// EUR/CHF grid trader main function
int run() 
{
  BarPeriod = 60;
  Hedge = 5; // activate virtual hedging

  var Grid = 20*PIP; // set grid distance to 20 pips
  var Close = priceClose();
 
// place pending trades at 5 grid lines above and below the Close
  int i;
  for(i = Close/Grid - 5; i &lt; Close/Grid + 5; i++)
  {
    var Price = i*Grid;
// place short trades with profit target below the current price
    if(Price &lt; Close &amp;&amp; isFree(Price,Grid,true))
      enterShort(1,Price,0,Grid); 
// place long trades with profit target above the current price
    else if(Price &gt; Close &amp;&amp; isFree(Price,Grid,false))
      enterLong(1,Price,0,Grid);
  }
}</pre>
<p>A grid trader is a typical <strong>model-based system</strong>. It assumes that some market force keeps the price inside a channel. This is the case here: The cap prevents the EUR/CHF from falling below 1.20, but it also prevents it from rising too high, since the SNB must eventually buy back all the Francs they have sold for defending the cap. The mathematical model of this would be a random walk with a 1.20 boundary and some drift term that pulls the price down. Such a constraint is a prerequisite for a grid trader; without it grid trading would be just high-risk gambling and is consequently listed in the <a href="http://www.financial-hacker.com/seventeen-popular-trade-strategies-that-i-dont-really-understand/">irrational trade methods</a> collection.</p>
<p>This is the P&amp;L-curve (blue) of the above script applied to the EUR/CHF in 2013:</p>
<figure id="attachment_894" aria-describedby="caption-attachment-894" style="width: 879px" class="wp-caption alignnone"><a href="http://www.financial-hacker.com/wp-content/uploads/2015/11/chf3.png"><img loading="lazy" decoding="async" class="wp-image-894 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/11/chf3.png" alt="" width="879" height="401" srcset="https://financial-hacker.com/wp-content/uploads/2015/11/chf3.png 879w, https://financial-hacker.com/wp-content/uploads/2015/11/chf3-300x137.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a><figcaption id="caption-attachment-894" class="wp-caption-text">EUR/CHF grid trading P&amp;L curve 2013</figcaption></figure>
<p>We can see that large price fluctuations, as in January and May, cause large drawdowns (the red underwater peaks in the chart). But since the fluctuations have a limit, we can estimate the maximum loss and just keep enough capital on the account. This way the above script produces an annual return of 130% and a Sharpe Ratio of 1.7 &#8211; with virtually no risk ( as long as the price cap stays in place).</p>
<p>The news of such a trading strategy slowly spread in 2013. More and more private traders and financial hackers, and also more and more large market participants jumped on the bandwagon. Three years after installation of the price cap, thousands of such systems sat on the EUR/CHF price curve like leeches and sucked off money. The result was a continuously falling price volatility:</p>
<figure id="attachment_902" aria-describedby="caption-attachment-902" style="width: 879px" class="wp-caption alignnone"><a href="http://www.financial-hacker.com/wp-content/uploads/2015/11/chf4.png"><img loading="lazy" decoding="async" class="wp-image-902 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/11/chf4.png" alt="" width="879" height="438" srcset="https://financial-hacker.com/wp-content/uploads/2015/11/chf4.png 879w, https://financial-hacker.com/wp-content/uploads/2015/11/chf4-300x149.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a><figcaption id="caption-attachment-902" class="wp-caption-text">EUR/CHF price and volatility, July 2013 &#8211; Dec 2014</figcaption></figure>
<p>Lower volatility means lower profits to a grid trader. More capital must be invested and the grid must be tightened for compensating. But there is a natural limit. You can not have a grid size smaller than the trading costs. By autumn 2014 the volatility was close to zero. And this was accompanied by an ominous price downwards drift, as if some large market participant (possibly the SNB itself) would continously sell EUR and buy CHF in anticipation of some future event. That would have been high time for private traders to retreat from the game. Of course, thickheads like me didn&#8217;t. It is well known what then happened to the Swiss Franc:</p>
<figure id="attachment_917" aria-describedby="caption-attachment-917" style="width: 879px" class="wp-caption alignnone"><a href="http://www.financial-hacker.com/wp-content/uploads/2015/11/chf5.png"><img loading="lazy" decoding="async" class="wp-image-917 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2015/11/chf5.png" alt="" width="879" height="321" srcset="https://financial-hacker.com/wp-content/uploads/2015/11/chf5.png 879w, https://financial-hacker.com/wp-content/uploads/2015/11/chf5-300x110.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a><figcaption id="caption-attachment-917" class="wp-caption-text">EUR/CHF price, January 2015</figcaption></figure>
<p>In the morning of 15 January 2015, the SNB gave a press conference and announced the cancellation of the price cap. The EUR/CHF fell in minutes like a stone from the 1.20 limit to below parity. Obviously a fast and extreme market reaction &#8211; very different to the introduction of the price cap 4 years before. The price drop killed many accounts and even a few brokers. By the way, the &#8216;real value&#8217; of the EUR/CHF, based on the relative buying power of the two currencies, was in the 1.50 area all the time. </p>
<p>What can we learn from this and from similar examples?</p>
<h3>Conclusions</h3>
<ul>
<li>The financial markets react immediately and often hysterically on news with a clear price upwards/downwards direction.</li>
<li>The markets react slow or not at all on more subtle information. It can take years until they become aware of new inefficiencies or trading methods.</li>
<li>The markets prefer brute-force methods. Complex strategies are normally only used by a small part of market participants.</li>
<li>Simple systems based on very obvious inefficiencies can be extremely profitable, but have a limited lifetime. </li>
</ul>
<p>The next parts of the <strong>Build Better Strategies</strong> series will deal with model-based systems, with known market inefficiencies and with a methodical approach of exploiting them. </p>
<p style="text-align: right;"><strong>⇒ <a href="http://www.financial-hacker.com/build-better-strategies-part-2-model-based-systems/">Build Better Strategies &#8211; Part 2</a></strong></p>
]]></content:encoded>
					
					<wfw:commentRss>https://financial-hacker.com/build-better-strategies/feed/</wfw:commentRss>
			<slash:comments>17</slash:comments>
		
		
			</item>
	</channel>
</rss>
