<?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>Money management &#8211; The Financial Hacker</title>
	<atom:link href="https://financial-hacker.com/tag/money-management/feed/" rel="self" type="application/rss+xml" />
	<link>https://financial-hacker.com</link>
	<description>A new view on algorithmic trading</description>
	<lastBuildDate>Mon, 24 Aug 2020 10:05:14 +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>Money management &#8211; The Financial Hacker</title>
	<link>https://financial-hacker.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Get Rich Slowly</title>
		<link>https://financial-hacker.com/get-rich-slowly/</link>
					<comments>https://financial-hacker.com/get-rich-slowly/#comments</comments>
		
		<dc:creator><![CDATA[jcl]]></dc:creator>
		<pubDate>Sat, 02 Jul 2016 14:15:00 +0000</pubDate>
				<category><![CDATA[System Development]]></category>
		<category><![CDATA[Correlation matrix]]></category>
		<category><![CDATA[Covariance matrix]]></category>
		<category><![CDATA[Efficient frontier]]></category>
		<category><![CDATA[ETF]]></category>
		<category><![CDATA[Heatmap]]></category>
		<category><![CDATA[Markowitz]]></category>
		<category><![CDATA[Mean-variance optimization]]></category>
		<category><![CDATA[Money management]]></category>
		<category><![CDATA[MVO]]></category>
		<category><![CDATA[Portfolio rotation]]></category>
		<category><![CDATA[Robo-advisor]]></category>
		<category><![CDATA[Sharpe ratio]]></category>
		<guid isPermaLink="false">http://www.financial-hacker.com/?p=1702</guid>

					<description><![CDATA[Most trading systems are of the get-rich-quick type. They exploit temporary market inefficiencies and aim for annual returns in the 100% area. They require regular supervision and adaption to market conditions, and still have a limited lifetime. Their expiration is often accompanied by large losses. But what if you&#8217;ve nevertheless collected some handsome gains, and &#8230; <a href="https://financial-hacker.com/get-rich-slowly/" class="more-link">Continue reading<span class="screen-reader-text"> "Get Rich Slowly"</span></a>]]></description>
										<content:encoded><![CDATA[<p>Most trading systems are of the get-rich-quick type. They exploit temporary market inefficiencies and aim for annual returns in the 100% area. They require regular supervision and adaption to market conditions, and still have a limited lifetime. Their expiration is often accompanied by large losses. But what if you&#8217;ve nevertheless collected some handsome gains, and now want to park them in a more safe haven? Put the money under the pillow? Take it into the bank? Give it to a hedge funds? Obviously, all that goes against an algo trader&#8217;s honor code. Here&#8217;s an alternative.<span id="more-1702"></span></p>
<p>The old-fashioned investing method is buying some low-risk stocks and then waiting a long time. Any portfolio of stocks has a certain mean return and a certain fluctuation in value; you normally want to minimize the latter and maximize the former. Since the mean return and the fluctuation changes all the time, this task requires rebalancing the portfolio in regular intervals. The <strong>optimal capital allocation</strong> among the portfolio components produces either maximum mean return for a given allowed risk, or minimum risk &#8211; respectively, minimum variance &#8211; for a given mean return. This optimal allocation is often very different to investing the same amount in all N components of the portfolio. An easy way to solve this mean / variance optimization problem was published 60 years ago by <a href="https://en.wikipedia.org/wiki/Harry_Markowitz" target="_blank" rel="noopener noreferrer"><strong>Harry Markowitz</strong></a>. It won him later the Nobel prize.</p>
<h3>The unfashionable Markowitz</h3>
<p>Unfortunately, Markowitz got largely out of fashion since then. The problem is the same as with all trading algorithms: You can only calculate the optimal capital allocation in hindsight. Optimized portfolios mysteriously failed in live trading. They were said to often return less than a simple 1/N capital distribution. But this was challenged recently in <a href="http://papers.ssrn.com/sol3/papers.cfm?abstract_id=2606884">an interesting paper</a> (1) by Keller, Butler, and Kipnis, of which I quote the first paragraph:</p>
<p><em>Mean-Variance Optimization (MVO) as introduced by Markowitz (1952) is often presented as an elegant but impractical theory. MVO is an<strong> &#8220;unstable and error-maximizing</strong>&#8221; procedure (Michaud 1989), and is &#8220;<strong>nearly always beaten by simple 1/N portfolios</strong>&#8221; (DeMiguel, 2007). And to quote Ang (2014): &#8220;Mean-variance weights <strong>perform horribly</strong>… The optimal mean-variance portfolio is a complex function of estimated means, volatilities, and correlations of asset returns. There are many parameters to estimate. Optimized mean-variance portfolios can <strong>blow up</strong> when there are tiny errors in any of these inputs&#8230;&#8221;.</em></p>
<p>The optimized portfolios of the quoted authors indeed blew up. But Markowitz is not to blame. They just did not understand what &#8216;optimal capital allocation&#8217; means. Suppose you have a portfolio of very similar assets, all with almost identical mean return and variance, only one of them is a tiny bit better. The Markowitz algorithm will then tend to assign all capital to that single asset. That&#8217;s just logical, as it is the optimal capital allocation. But it&#8217;s not the optimal portfolio. You don&#8217;t want to expose all capital to a single stock. If that company goes belly up, your portfolio will too. This is the mentioned &#8216;stability problem&#8217;. However there is a simple and obvious solution: a per-asset weight limit.</p>
<p>Aside from that, the Markowitz vituperators used too long, mean-reverting time periods for sampling the returns and covariances, and they applied the MVO algorithm wrongly to mixed long/short portfolios. When correctly applied to a momentum-governed time period and long-only, well diversified portfolios with a weight limit, MVO produced out of sample results <strong>far superior to 1/N</strong>. This was proven by testing a number of example portfolios in (1) with a R MVO implementation by fellow blogger <a href="http://quantstrattrader.wordpress.com/">Ilya Kipnis</a>.</p>
<p>However, a R implementation is not very practical for live trading. For this we have to implement MVO in a real trade platform. Then we can park our money in an optimized portfolio of stocks and ETFs, let the platform rebalance the capital allocation in regular intervals, lean back, wait, and get rich slowly.</p>
<h3>Implementing MVO</h3>
<p>The Zorro implementation is based on Markowitz&#8217; 1959 publication (2). In chapter 8, he described the MVO algorithm in a clear and easy to follow way. For simple minded programmers like me, he even included a brief introduction to linear algebra! I only modified his original algorithm by adding the mentioned weight constraint. This constraint stabilizes the algorithm and keeps the portfolio diversified.</p>
<p>In wise anticipation of future computing machines, Markowitz also included an example portfolio for checking if you programmed his algorithm correctly. The proof:</p>
<pre class="prettyprint">function main()
{
	var Means[3] = { .062,.146,.128 };
	var Covariances[3][3] = {.0146,.0187,.0145,.0187,.0854,.0104,.0145,.0104,.0289};
	var Weights[3];
	
	var BestVariance = markowitz(Covariances,Means,3,0);

	markowitzReturn(Weights,1);
	printf("\nMax:  %.2f %.2f %.2f",Weights[0],Weights[1],Weights[2]);
	markowitzReturn(Weights,BestVariance);
	printf("\nBest: %.2f %.2f %.2f",Weights[0],Weights[1],Weights[2]);
	markowitzReturn(Weights,0);
	printf("\nMin:  %.2f %.2f %.2f",Weights[0],Weights[1],Weights[2]);
}</pre>
<p>The means and covariances arrays in the script are from Markowitz&#8217; example portfolio. The <strong>markowitz</strong> function runs the algorithm and returns the variance value associated with the best Sharpe ratio. The <strong>markowitzReturn</strong> function then calculates the capital allocation weights with the maximum mean return for a given variance. The weights for maximum, best, and minimum variance are printed. If I did it right, they should be exactly the same as in Markowitz&#8217; publication:</p>
<pre class="prettyprint">Max:  0.00 1.00 0.00
Best: 0.00 0.22 0.78
Min:  0.99 0.00 0.01
</pre>
<h3>Selecting the assets</h3>
<p>For long-term portfolios you can&#8217;t use the same high-leverage Forex or CFD instruments that you preferred for your short-term strategies. Instead you normally invest in stocks, ETFs, or similar instruments. They offer several advantages for algo trading:</p>
<ul style="list-style-type: square;">
<li><strong>No zero-sum game.</strong> In the long run, stocks and index ETFs have positive mean returns due to dividends and accumulated value, while Forex pairs and index CFDs have negative mean returns due to swap/rollover fees.<br />
  </li>
<li><strong>Serious brokers.</strong> Stock/ETF brokers are all regulated, what can not be said of all Forex/CFD brokers.<br />
  </li>
<li><strong>More data</strong> for your algorithms, such as volume and market depth information.<br />
  </li>
<li><strong>Bigger choice of assets</strong> from many different market sectors.<br />
   </li>
<li><strong>More trading methods,</strong> such as pairs trading (&#8220;stat arb&#8221;), trading risk-free assets such as T-bills, or trading volatility.</li>
</ul>
<p>The obvious disadvantage is low leverage, like 1:2 compared with 1:100 or more for Forex instruments. Low leverage is ok for a long-term system, but not for getting rich quick. More restrictions apply to long-term portfolios. MVO obviously won&#8217;t work well with components that have no positive mean return. And it won&#8217;t work well either when the returns are strongly correlated. So when selecting assets for your long-term portfolio, you have to look not only for returns, but also for correlation. Here&#8217;s the main part of a Zorro script for that:</p>
<pre class="prettyprint">#define NN  30  // max number of assets

function run()
{
	BarPeriod = 1440;
	NumYears = 7;
	LookBack = 6*252; // 6 years

	string	Names[NN];
	vars	Returns[NN];
	var	Correlations[NN][NN];

	int N = 0;
	while(Names[N] = loop( 
		"TLT","LQD","SPY","GLD","VGLT","AOK"))
	{
		if(is(INITRUN))
			assetHistory(Names[N],FROM_YAHOO);
		asset(Names[N]);
		Returns[N] = series((priceClose(0)-priceClose(1))/priceClose(1));
		if(N++ &gt;= NN) break;
	}
	if(is(EXITRUN)) {
		int i,j;
		for(i=0; i&lt;N; i++)
		for(j=0; j&lt;N; j++)
			Correlations[N*i+j] = 
				Correlation(Returns[i],Returns[j],LookBack);
		plotHeatmap("Correlation",Correlations,N,N);
		for(i=0; i&lt;N; i++)
			printf("\n%i - %s: Mean %.2f%%  Variance %.2f%%",
				i+1,Names[i],
				100*annual(Moment(Returns[i],LookBack,1)),
				252*100*Moment(Returns[i],LookBack,2));
	}
}
</pre>
<p>The script first sets up some parameters, then goes into a loop over <strong>N</strong> assets. Here I&#8217;ve just entered some popular ETFs; for replacing them, websites such as <a href="http://etfdb.com/etfs/">etfdb.com</a> give an overview and help searching for the optimal ETF combination.</p>
<p>In the initial run, the asset prices are downloaded from Yahoo. They are corrected for splits and dividends. The <strong>assetHistory</strong> function stores them as historical price data files. Then the assets are selected and their returns are calculated and stored in the <strong>Returns</strong> data series. This is repeated with all 1-day bars of a 7 years test period (obviously the period depends on since when the selected ETFs are available). In the final run the script prints the annual mean returns and variances of all assets, which are the first and second <strong>moments</strong> of the return series. The <strong>annual</strong> function and the 252 multiplication factor convert daily values to annual values. The results for the selected ETFs:</p>
<pre class="prettyprint">1 - TLT: Mean 10.75% Variance 2.29%
2 - LQD: Mean 6.46% Variance 0.31%
3 - SPY: Mean 13.51% Variance 2.51%
4 - GLD: Mean 3.25% Variance 3.04%
5 - VGLT: Mean 9.83% Variance 1.65%
6 - AOK: Mean 4.70% Variance 0.23%</pre>
<p>The ideal ETF has high mean return, low variance, and low correlation to all other assets of the portfolio. The correlation can be seen in the <strong>correlation matrix</strong> that is computed from all collected returns in the above code, then plotted in a <strong>N*N</strong> heatmap:</p>
<p><a href="http://www.financial-hacker.com/wp-content/uploads/2016/12/Heatmap_s-1.png"><img fetchpriority="high" decoding="async" class="alignnone wp-image-1777 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2016/12/Heatmap_s-1.png" width="379" height="351" srcset="https://financial-hacker.com/wp-content/uploads/2016/12/Heatmap_s-1.png 379w, https://financial-hacker.com/wp-content/uploads/2016/12/Heatmap_s-1-300x278.png 300w" sizes="(max-width: 379px) 85vw, 379px" /></a></p>
<p>The correlation matrix contains the correlation coefficients of every asset with every other asset. The rows and columns of the heatmap are the 6 assets. The colors go from blue for low correlation between the row and column asset, to red for high correlation. Since any asset correlates perfectly with itself, we always have a red diagonal. But you can see from the other red squares that some of my 6 popular ETFs were no good choice. Finding the perfect ETF combination, with the heatmap as blue as possible, is left as an exercise to the reader.</p>
<h3>The efficient frontier</h3>
<p>After selecting the assets for our portfolio, we now have to calculate the optimal capital allocation, using the MVO algorithm. However, &#8220;optimal&#8221; depends on the desired risk, i.e. volatility of the portfolio. For every risk value there&#8217;s a optimal allocation that generates the maximum return. So the optimal allocation is not a point, but a curve in the return / variance plane, named the <strong>Efficient Frontier</strong>. We can calculate and plot it with this script:</p>
<pre class="prettyprint">function run()
{
	... // similar to Heatmap script
 
	if(is(EXITRUN)) {
		int i,j;
		for(i=0; i&lt;N; i++) {
			Means[i] = Moment(Returns[i],LookBack,1);
			for(j=0; j&lt;N; j++)
				Covariances[N*i+j] =
					Covariance(Returns[i],Returns[j],LookBack);	
		}

		var BestV = markowitz(Covariances,Means,N,0);	
		var MinV = markowitzVariance(0,0);
		var MaxV = markowitzVariance(0,1);

		int Steps = 50;
		for(i=0; i&lt;Steps; i++) {
			var V = MinV + i*(MaxV-MinV)/Steps;
			var R = markowitzReturn(0,V);
			plotBar("Frontier",i,V,100*R,LINE|LBL2,BLACK);
		}
		plotGraph("Max Sharpe",(BestV-MinV)*Steps/(MaxV-MinV),
			100*markowitzReturn(0,BestV),SQUARE,GREEN);
	}
}</pre>
<p>I&#8217;ve omitted the first part since it&#8217;s identical to the heatmap script. Only the covariance matrix is now calculated instead of the correlation matrix. Covariances and mean returns are fed to the <strong>markowitz</strong> function that again returns the variance with the best Sharpe ratio. The subsequent calls to <strong>markowitzVariance</strong> also return the highest and the lowest variance of the efficient frontier and establish the borders of the plot. Finally the script plots 50 points of the annual mean return from the lowest to the highest variance:</p>
<p><a href="http://www.financial-hacker.com/wp-content/uploads/2016/12/EFrontier_s.png"><img decoding="async" class="alignnone wp-image-1780 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2016/12/EFrontier_s.png" width="629" height="301" srcset="https://financial-hacker.com/wp-content/uploads/2016/12/EFrontier_s.png 629w, https://financial-hacker.com/wp-content/uploads/2016/12/EFrontier_s-300x144.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>At the right side we can see that the portfolio reaches a maximum annual return of about 12.9%, which is simply all capital allocated to SPY. On the left side we achieve only 5.4% return, but with less than a tenth of the daily variance. The green dot is the point on the frontier with the best Sharpe ratio (= return divided by square root of variance) at 10% annual return and 0.025 variance. This is the optimal portfolio &#8211; at least in hindsight. </p>
<h3>Experiments</h3>
<p>How will a mean / variance optimized portfolio fare in an out of sample test, compared with with 1/N? Here&#8217;s a script for experiments with different portfolio compositions, lookback periods, weight constraints, and variances:</p>
<pre class="prettyprint">#define DAYS	252 // 1 year lookback period
#define NN	30  // max number of assets

function run()
{
	... // similar to Heatmap script

	int i,j;
	static var BestVariance = 0;
	if(tdm() == 1 &amp;&amp; !is(LOOKBACK)) {
		for(i=0; i&lt;N; i++) {
			Means[i] = Moment(Returns[i],LookBack,1);
			for(j=0; j&lt;N; j++)
				Covariances[N*i+j] = Covariance(Returns[i],Returns[j],LookBack);	
		}
		BestVariance = markowitz(Covariances,Means,N,0.5);
	}
	
	var Weights[NN]; 
	static var Return, ReturnN, ReturnMax, ReturnBest, ReturnMin;
	if(is(LOOKBACK)) {
		Month = 0;
		ReturnN = ReturnMax = ReturnBest = ReturnMin = 0;
	}

	if(BestVariance &gt; 0) {
		for(Return=0,i=0; i&lt;N; i++) Return += (Returns[i])[0]/N; // 1/N 
		ReturnN = (ReturnN+1)*(Return+1)-1;
		
		markowitzReturn(Weights,0);	// min variance
		for(Return=0,i=0; i&lt;N; i++) Return += Weights[i]*(Returns[i])[0];
		ReturnMin = (ReturnMin+1)*(Return+1)-1;
		
		markowitzReturn(Weights,1);	// max return
		for(Return=0,i=0; i&lt;N; i++) Return += Weights[i]*(Returns[i])[0];
		ReturnMax = (ReturnMax+1)*(Return+1)-1;

		markowitzReturn(Weights,BestVariance); // max Sharpe
		for(Return=0,i=0; i&lt;N; i++) Return += Weights[i]*(Returns[i])[0];
		ReturnBest = (ReturnBest+1)*(Return+1)-1;

		plot("1/N",100*ReturnN,AXIS2,BLACK);
		plot("Max Sharpe",100*ReturnBest,AXIS2,GREEN);
		plot("Max Return",100*ReturnMax,AXIS2,RED);
		plot("Min Variance",100*ReturnMin,AXIS2,BLUE);
	}
}</pre>
<p>The script goes through 7 years of historical data, and stores the daily returns in the <strong>Returns</strong> data series. At the first trading day of every month (<strong>tdm() == 1</strong>) it computes the means and the covariance matrix of the last 252 days, then calculates the efficient frontier. This time we also apply a 0.5 weight constraint to the minimum variance point. Based on this efficient frontier, we compute the daily total return with equal weights (<strong>ReturnN</strong>), best Sharpe ratio (<strong>ReturnBest</strong>), minimum variance (<strong>ReturnMin</strong>) and maximum Return (<strong>ReturnMax</strong>). The weights remain unchanged until the next rebalancing, this way establishing an out of sample test. The four daily returns are added up to 4 different equity curves :</p>
<p> <a href="http://www.financial-hacker.com/wp-content/uploads/2016/12/MVO_AOK-1.png"><img decoding="async" class="alignnone wp-image-1788 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2016/12/MVO_AOK-1.png" width="1079" height="301" srcset="https://financial-hacker.com/wp-content/uploads/2016/12/MVO_AOK-1.png 1079w, https://financial-hacker.com/wp-content/uploads/2016/12/MVO_AOK-1-300x84.png 300w, https://financial-hacker.com/wp-content/uploads/2016/12/MVO_AOK-1-768x214.png 768w, https://financial-hacker.com/wp-content/uploads/2016/12/MVO_AOK-1-1024x286.png 1024w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>We can see that MVO improves the portfolio in all three variants, in spite of its bad reputation. The black line is the 1/N portfolio with equal weights for all asset. The blue line is the minimum variance portfolio &#8211; we can see that it produces slightly better profits than 1/N, but with much lower volatility. The red line is the maximum return portfolio with the best profit, but high volatility and sharp drawdowns. The green line, the maximum Sharpe portfolio, is somewhere inbetween. Different portfolio compositions can produce a different order of lines, but the blue and green lines have almost always a much better Sharpe ratio than the black line. Since the minimum variance portfolio can be traded with higher leverage due to the smaller drawdowns, it often produces the highest profits.</p>
<p>For checking the monthly rebalancing of the capital allocation weights, we can display the weights in a heatmap:</p>
<p><a href="http://www.financial-hacker.com/wp-content/uploads/2016/12/MVO_s.png"><img loading="lazy" decoding="async" class="alignnone wp-image-1790 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2016/12/MVO_s.png" width="1551" height="162" srcset="https://financial-hacker.com/wp-content/uploads/2016/12/MVO_s.png 1551w, https://financial-hacker.com/wp-content/uploads/2016/12/MVO_s-300x31.png 300w, https://financial-hacker.com/wp-content/uploads/2016/12/MVO_s-768x80.png 768w, https://financial-hacker.com/wp-content/uploads/2016/12/MVO_s-1024x107.png 1024w, https://financial-hacker.com/wp-content/uploads/2016/12/MVO_s-1200x125.png 1200w" sizes="auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>The horizontal axis is the month of the simulation, the vertical axis the asset number. High weights are red and low weights are blue. The weight distribution above is for the maximum Sharpe portfolio of the 6 ETFs.</p>
<h3>The final money parking system</h3>
<p>After all those experiments we can now code our long-term system. It shall work in the following way:</p>
<ul style="list-style-type: square;">
<li>The efficient frontier is calculated from daily returns of the last 252 trading days, i.e. one year. That&#8217;s a good time period for MVO according to (1), since most ETFs show 1-year momentum.<br />
  </li>
<li>The system rebalances the portfolio once per month. Shorter time periods, such as daily or weekly rebalancing, showed no advantage in my tests, but reduced the profit due to higher trading costs. Longer time periods, such as 3 months, let the system deteriorate.<br />
  </li>
<li> The point on the efficient frontier can be set up with a slider between minimum variance and maximum Sharpe. This way you can control the risk of the system. <br />
  </li>
<li>We use a 50% weight constraint at minimum variance. It&#8217;s then not anymore the optimal portfolio, but according to (1) &#8211; and my tests have confirmed this &#8211; it often improves the out of sample balance due to better diversification.</li>
</ul>
<p>Here&#8217;s the script:</p>
<pre class="prettyprint">#define LEVERAGE 4	// 1:4 leverage
#define DAYS	252 	// 1 year
#define NN	30	// max number of assets

function run()
{
	BarPeriod = 1440;
	LookBack = DAYS;

	string Names[NN];
	vars	Returns[NN];
	var	Means[NN];
	var	Covariances[NN][NN];
	var	Weights[NN];

	var TotalCapital = slider(1,1000,0,10000,"Capital","Total capital to distribute");
	var VFactor = slider(2,10,0,100,"Risk","Variance factor");
	
	int N = 0;
	while(Names[N] = loop( 
		"TLT","LQD","SPY","GLD","VGLT","AOK"))
	{
		if(is(INITRUN))
			assetHistory(Names[N],FROM_YAHOO);
		asset(Names[N]);
		Returns[N] = series((priceClose(0)-priceClose(1))/priceClose(1));
		if(N++ &gt;= NN) break;
	}

	if(is(EXITRUN)) {
		int i,j;
		for(i=0; i&lt;N; i++) {
			Means[i] = Moment(Returns[i],LookBack,1);
			for(j=0; j&lt;N; j++)
				Covariances[N*i+j] = Covariance(Returns[i],Returns[j],LookBack);	
		}
		var BestVariance = markowitz(Covariances,Means,N,0.5);
		var MinVariance = markowitzVariance(0,0);
		markowitzReturn(Weights,MinVariance+VFactor/100.*(BestVariance-MinVariance));

		for(i=0; i&lt;N; i++) {
			asset(Names[i]);
			MarginCost = priceClose()/LEVERAGE;
			int Position = TotalCapital*Weights[i]/MarginCost;
			printf("\n%s:  %d Contracts at %.0f$",Names[i],Position,priceClose());
		}
	}
}</pre>
<p>On Zorro&#8217;s panel you can set up the invested capital with a slider (<strong>TotalCapital</strong>) between 0 and 10,000$. A second slider (<strong>VFactor</strong>) is for setting up the desired risk from 0 to 100%: At 0 you&#8217;re trading with minimum variance, at 100 with maximum Sharpe ratio.</p>
<p><a href="http://www.financial-hacker.com/wp-content/uploads/2016/05/sliders.png"><img loading="lazy" decoding="async" class="alignnone wp-image-1808 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2016/05/sliders.png" width="289" height="85" /></a></p>
<p>This script advises only, but does not trade: For automated trading it, you would need an <a href="http://www.financial-hacker.com/dear-brokers/" target="_blank" rel="noopener noreferrer">API plugin</a> to a ETF broker, such as IB. But the free Zorro version only has plugins for Forex/CFD brokers; the IB plugin is not free. However, since positions are only opened or closed once per month and price data is free from Yahoo, you do not really need an API connection for trading a MVO portfolio. Just fire up the above script once every month, and check what it prints out:</p>
<pre class="prettyprint">TLT:  0 Contracts at 129$
LQD:  0 Contracts at 120$
SPY:  3 Contracts at 206$
GLD:  16 Contracts at 124$
VGLT:  15 Contracts at 80$
AOK:  0 Contracts at 32$
</pre>
<p>Apparently, the optimal portfolio for this month consists of 3 contracts SPY, 16 contracts GLD, and 15 VGLT contracts. You can now manually open or close those positions in your broker&#8217;s trading platform until your portfolio matches the printed advice. Leverage is 4 by default, but you can change this to your broker&#8217;s leverage in the #define at the begin of the script. For a script that trades, simply replace the <strong>printf</strong> statement with a trade command that opens or closes the difference to the current position of the asset. This, too, is left as an exercise to the reader&#8230;</p>
<h3>MVO vs. OptimalF</h3>
<p>It seems natural to use MVO not only for a portfolio of many assets, but also for a portfolio of many trading systems. I&#8217;ve tested this with the <a href="http://manual.zorro-project.com/zsystems.htm" target="_blank" rel="noopener noreferrer">Z12 system</a> that comes with Zorro and contains about 100 different system/asset combinations. It turned out that MVO did not produce better results than Ralph Vince&#8217;s <strong>OptimalF</strong> factors that are originally used by the system. OptimalF factors do not consider correlations between components, but they do consider the drawdown depths, while MVO is only based on means and covariances. The ultimate solution for such a portfolio of many trading systems might be a combination of MVO for the capital distribution and OptimalF for weight constraints. I have not tested this yet, but it&#8217;s on my to do list.</p>
<p>I&#8217;ve added all scripts to the 2016 script repository. You&#8217;ll need Zorro 1.44 or above for running them. And after you made your first million with the MVO script, don&#8217;t forget to <a href="http://manual.zorro-project.com/restrictions.htm" target="_blank" rel="noopener noreferrer">sponsor</a> Zorro generously! <img src="https://s.w.org/images/core/emoji/16.0.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<hr />
<h3>Papers</h3>
<ol>
<li>Momentum and Markowitz &#8211; A Golden Combination: <a href="http://papers.ssrn.com/sol3/papers.cfm?abstract_id=2606884" target="_blank" rel="noopener noreferrer">Keller.Butler.Kipnis.2015</a><br />
  </li>
<li>Harry M. Markowitz, Portfolio Selection, Wiley 1959<br />
  </li>
<li>MVO overview at <a href="https://www.guidedchoice.com/video/dr-harry-markowitz-father-of-modern-portfolio-theory/" target="_blank" rel="noopener noreferrer">guidedchoice.com</a></li>
</ol>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://financial-hacker.com/get-rich-slowly/feed/</wfw:commentRss>
			<slash:comments>89</slash:comments>
		
		
			</item>
		<item>
		<title>Build Better Strategies! Part 3: The Development Process</title>
		<link>https://financial-hacker.com/build-better-strategies-part-3-the-development-process/</link>
					<comments>https://financial-hacker.com/build-better-strategies-part-3-the-development-process/#comments</comments>
		
		<dc:creator><![CDATA[jcl]]></dc:creator>
		<pubDate>Mon, 22 Feb 2016 16:46:32 +0000</pubDate>
				<category><![CDATA[3 Most Useful]]></category>
		<category><![CDATA[System Development]]></category>
		<category><![CDATA[Cycles]]></category>
		<category><![CDATA[Detrending]]></category>
		<category><![CDATA[Drawdown]]></category>
		<category><![CDATA[Medallion fund]]></category>
		<category><![CDATA[Money management]]></category>
		<category><![CDATA[Spectral filter]]></category>
		<category><![CDATA[Walk forward analysis]]></category>
		<guid isPermaLink="false">http://www.financial-hacker.com/?p=1191</guid>

					<description><![CDATA[This is the third part of the Build Better Strategies series. In the previous part we&#8217;ve discussed the 10 most-exploited market inefficiencies and gave some examples of their trading strategies. In this part we&#8217;ll analyze the general process of developing a model-based trading system. As almost anything, you can do trading strategies in (at least) &#8230; <a href="https://financial-hacker.com/build-better-strategies-part-3-the-development-process/" class="more-link">Continue reading<span class="screen-reader-text"> "Build Better Strategies! Part 3: The Development Process"</span></a>]]></description>
										<content:encoded><![CDATA[<p>This is the third part of the <a href="http://www.financial-hacker.com/build-better-strategies/">Build Better Strategies</a> series. In the previous part we&#8217;ve discussed the 10 most-exploited market inefficiencies and gave some examples of their trading strategies. In this part we&#8217;ll analyze the general process of developing a model-based trading system. As almost anything, you can do trading strategies in (at least) two different ways: There&#8217;s the <strong>ideal way</strong>, and there&#8217;s the <strong>real way</strong>. We begin with the <strong>ideal development process</strong>, broken down to 10 steps.<span id="more-1191"></span></p>
<h3>The ideal model-based strategy development<br />
Step 1: The model</h3>
<p>Select one of the known market inefficiencies listed in the <a href="http://www.financial-hacker.com/build-better-strategies-part-2-model-based-systems/">previous part</a>, or discover a new one. You could eyeball through price curves and look for something suspicious that can be explained by a certain market behavior. Or the other way around, &nbsp;theoretize about a behavior pattern and check if you can find it reflected in the prices. If you discover something new, feel invited to post it here! But be careful: Models of non-existing inefficiencies (such as&nbsp;<a href="http://www.financial-hacker.com/seventeen-popular-trade-strategies-that-i-dont-really-understand/">Elliott Waves</a>) already outnumber real inefficiencies by a large amount. It is not likely that a real inefficiency remains unknown to this day.</p>
<p>Once you&#8217;ve decided for a model, determine which <strong>price curve anomaly</strong> it would produce, and describe it with a quantitative formula or at least a qualitative criteria. You&#8217;ll need that for the next step. As an example we&#8217;re using the <strong>Cycles Model</strong> from the previous part:</p>
<p>[latex display=&#8221;true&#8221;]y_t ~=~ \hat{y} + \sum_{i}{a_i sin(2 \pi t/C_i+D_i)} + \epsilon[/latex]</p>
<p>(Cycles are not to be underestimated. One of the most successful funds in history &#8211; Jim Simons&#8217; <strong>Renaissance Medallion</strong> fund &#8211; is rumored to exploit cycles in price curves by analyzing their lengths (<em><strong>C<sub>i</sub></strong></em>), phases (<em><strong>D<sub>i</sub></strong></em>) and amplitudes (<em><strong>a<sub>i</sub></strong></em>) with a Hidden Markov Model. Don&#8217;t worry, we&#8217;ll use a somewhat simpler approach in our example.)</p>
<h3>Step 2: Research</h3>
<p>Find out if the hypothetical anomaly really appears in the price curves of the assets that you want to trade. For this you first need enough historical data of the traded assets &#8211; D1, M1, or Tick data, dependent on the time frame of the anomaly. How far back? As far as possible, since you want to find out the lifetime of your anomaly and the market conditions under which it appears. Write a script to detect and display the anomaly in price data. For our Cycles Model, this would be the frequency spectrum:</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 frequency spectrum, cycle amplitude vs. cycle length in bars</figcaption></figure>
<p>Check out how the spectrum changes over the months and years. Compare with the spectrum of random data (with <a href="http://www.financial-hacker.com/hackers-tools-zorro-and-r/" target="_blank" rel="noopener noreferrer">Zorro</a> you can use the <a href="http://zorro-project.com/manual/en/detrend.htm" target="_blank" rel="noopener noreferrer">Detrend</a> function for randomizing price curves). If you find no clear signs of the anomaly, or no significant difference to random data, improve your detection method. And if you then still don&#8217;t succeed, go back to step 1.</p>
<h3>Step 3: The algorithm</h3>
<p>Write an algorithm that generates the&nbsp;<strong>trade signals</strong> for buying in the direction of the anomaly. A market inefficiency has normally only a <strong>very weak effect</strong> on the price curve. So your algorithm must be really good in distinguishing it from random noise. At the same time it should be as simple as possible, and rely on as few free parameters as possible. &nbsp;In our example with the Cycles Model, the script reverses the position at every valley and peak of a sine curve that runs ahead of the dominant cycle:</p>
<pre class="prettyprint">function run()
{
  vars Price = series(price());
  var Phase = DominantPhase(Price,10);
  vars Signal = series(sin(Phase+PI/4));

  if(valley(Signal))
    reverseLong(1); 
  else if(peak(Signal))
    reverseShort(1);
}</pre>
<p>This is the core of the system. Now it&#8217;s time for a first backtest. The precise performance does not matter much at this point &#8211; just determine whether the algorithm has an edge or not. Can&nbsp;it produce a series of profitable trades at least in certain market periods or situations? If not, improve the algorithm or write a another one that exploits the same anomaly with a different method. But do not yet use any stops, trailing, or other bells and whistles. They would only distort the result, and give you the illusion of profit where none is there. Your algorithm must be able to produce positive returns either with pure reversal, or at least with a timed exit.</p>
<p>In this step you must also decide about the <strong>backtest data</strong>. You normally need M1 or tick data for a realistic test. Daily data won&#8217;t do. The data amount depends on the lifetime (determined in step 2) and the nature of the price anomaly. Naturally, the longer the period, the better the test &#8211; but more is not always better. Normally it makes no sense to go further back than 10 years, at least not when your system exploits some real market behavior. Markets change extremely in a decade. Outdated historical price data can produce very misleading results. Most systems that had an edge 15 years ago will fail miserably on today&#8217;s markets. But they can deceive you with a seemingly profitable backtest.</p>
<h3>Step 4: The filter</h3>
<p>No market inefficiency exits all the time. Any market goes through periods of random behavior. It is essential for any system to have a filter mechanism that detects if the inefficiency is present or not. The filter is at least as important as the trade signal, if not more &#8211; but it&#8217;s often forgotten in trade systems. This is our example script with a filter:</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));
  var Threshold = 1*PIP;
  ExitTime = 10*rDominantPeriod;
	
  if(Amplitude(Dominant,100) &gt; Threshold) {
    if(valley(Signal))
      reverseLong(1); 
    else if(peak(Signal))
      reverseShort(1);
  }
}</pre>
<p>We apply a bandpass filter centered at the dominant cycle period to the price curve and measure its amplitude. If the amplitude is above a threshold, we conclude that the inefficiency is there, and we trade. The trade duration is now also restricted to a maximum of 10 cycles since we found in step 2 that dominant cycles appear and disappear in relatively short time.</p>
<p>What can go wrong in this step is falling to the temptation to add a filter just because it improves the test result. Any filter must have a rational reason in the market behavior or in the used signal algorithm. If your algorithm only works by adding irrational filters: back to step 3.</p>
<h3>Step 5: Optimizing (but not too much!)</h3>
<p>All parameters of a system affect the result, but only a few directly determine entry and exit points of trades dependent on the price curve. These &#8216;adaptable&#8217; parameters should be identified and optimized. In the above example, trade entry is determined by the phase of the forerunning sine curve and by the filter threshold, and trade exit is determined by the exit time. Other parameters &#8211; such as the filter constants of the <strong>DominantPhase</strong> and the <strong>BandPass</strong> functions &#8211; need not be adapted since their values do not depend on the market situation.</p>
<p>Adaption is an optimizing procdure, and a big opportunity to fail without even noticing it. Often, genetic or brute force methods are applied for finding the &#8220;best&#8221; parameter combination at a profit peak in the parameter space. Many platforms even have &#8220;optimizers&#8221; for this purpose. Although this method indeed produces the best backtest result, it won&#8217;t help at all for the live performance of the system. In fact, a recent study (<a href="http://papers.ssrn.com/sol3/papers.cfm?abstract_id=2745220">Wiecki et.al. 2016</a>) showed that the better you optimize your parameters, the worse your system will fare in live trading! The reason of this paradoxical effect is that optimizing to maximum profit fits your system mostly to the noise in the historical price curve, since noise affects result peaks much more than market inefficiencies.</p>
<p>Rather than generating top backtest results, correct optimizing has other purposes:</p>
<ul style="list-style-type: square;">
<li>It can determine the <strong>susceptibility</strong> of your system to its parameters. If the system is great with a certain parameter combination, but loses its edge when their values change a tiny bit: back to step 3.</li>
<li>It can identify the parameter&#8217;s <strong>sweet spots</strong>. The sweet spot is the area of highest parameter robustness, i.e. where small parameter changes have little effect on the return. They are not the peaks, but the centers of broad hills in the parameter space.</li>
<li>It can adapt the system to different assets, and enable it to trade a <strong>portfolio</strong> of assets with slightly different parameters.&nbsp;It can also extend the <strong>lifetime</strong> of the system by adapting it to the current market situation in regular time intervals, parallel to live trading.</li>
</ul>
<p>This is our example script with entry parameter optimization:</p>
<pre class="prettyprint">function run()
{
  vars Price = series(price());
  var Phase = DominantPhase(Price,10);
  vars Signal = series(sin(Phase+optimize(1,0.7,2)*PI/4));
  vars Dominant = series(BandPass(Price,rDominantPeriod,1));
  ExitTime = 10*rDominantPeriod;
  var Threshold = optimize(1,0.7,2)*PIP;
	
  if(Amplitude(Dominant,100) &gt; Threshold) {
    if(valley(Signal))
      reverseLong(1); 
    else if(peak(Signal))
      reverseShort(1);
  }
}</pre>
<p>The two <a href="http://manual.zorro-project.com/optimize.htm" target="_blank" rel="noopener noreferrer">optimize</a> calls use a start value (<strong>1.0</strong> in both cases) and a range (<strong>0.7..2.0</strong>) for determining the sweet spots of the two essential parameters of the system. You can identify the spots in the profit factor curves (red bars) of the two parameters that are generated by the optimization process:</p>
<figure id="attachment_1377" aria-describedby="caption-attachment-1377" style="width: 391px" class="wp-caption alignnone"><a href="http://www.financial-hacker.com/wp-content/uploads/2016/02/CyclesDev_EURUSD_p1.png"><img loading="lazy" decoding="async" class="wp-image-1377 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2016/02/CyclesDev_EURUSD_p1.png" alt="" width="391" height="321" srcset="https://financial-hacker.com/wp-content/uploads/2016/02/CyclesDev_EURUSD_p1.png 391w, https://financial-hacker.com/wp-content/uploads/2016/02/CyclesDev_EURUSD_p1-300x246.png 300w" sizes="auto, (max-width: 391px) 85vw, 391px" /></a><figcaption id="caption-attachment-1377" class="wp-caption-text">Sine phase in pi/4 units</figcaption></figure>
<figure id="attachment_1376" aria-describedby="caption-attachment-1376" style="width: 391px" class="wp-caption alignnone"><a href="http://www.financial-hacker.com/wp-content/uploads/2016/02/CyclesDev_EURUSD_p2.png"><img loading="lazy" decoding="async" class="wp-image-1376 size-full" src="http://www.financial-hacker.com/wp-content/uploads/2016/02/CyclesDev_EURUSD_p2.png" alt="" width="391" height="321" srcset="https://financial-hacker.com/wp-content/uploads/2016/02/CyclesDev_EURUSD_p2.png 391w, https://financial-hacker.com/wp-content/uploads/2016/02/CyclesDev_EURUSD_p2-300x246.png 300w" sizes="auto, (max-width: 391px) 85vw, 391px" /></a><figcaption id="caption-attachment-1376" class="wp-caption-text">Amplitude threshold in pips</figcaption></figure>
<p>In this case the optimizer would select a parameter value of about 1.3 for the sine phase and about 1.0 (not the peak at 0.9) for the amplitude threshold for the current asset (EUR/USD). The exit time is not optimized in this step, as we&#8217;ll do that later together with the other exit parameters when risk management is implemented.</p>
<h3>Step 6: Out-of-sample analysis</h3>
<p>Of course the parameter optimization improved the backtest performance of the strategy, since the system was now better adapted to the price curve. So the test result so far is worthless. For getting an idea of the real performance, we first need to split the data into in-sample and out-of-sample periods. The in-sample periods are used for training, the out-of-sample periods for testing. The best method for this is <a href="http://manual.zorro-project.com/numwfocycles.htm" target="_blank" rel="noopener noreferrer">Walk Forward Analysis</a>. It uses a rolling window into the historical data for separating test and training periods.</p>
<p>Unfortunately, WFA adds two more parameters to the system: the training time and the test time of a WFA cycle. The test time should be long enough for trades to properly open and close, and small enough for the parameters to stay valid. The training time is more critical. Too short training will not get enough price data for effective optimization, training too long will also produce bad results since the market can already undergo changes during the training period. So the training time itself is a parameter that had to be optimized.</p>
<p>A five&nbsp;cycles walk forward analysis (add &#8220;<strong>NumWFOCycles = 5;</strong>&#8221; to the above script) reduces the backtest performance from 100% annual return to a more realistic 60%. For preventing that WFA still produces too optimistic results just by a lucky selection of test and training periods, it makes also sense to perform WFA several times with slightly different starting points of the simulation. If the system has an edge, the results should be not too different. If they vary wildly: back to step 3.</p>
<h3>Step 7: Reality Check</h3>
<p>Even though the test is now out-of-sample, the mere development process &#8211; selecting algorithms, assets, test periods and other ingredients by their performance &#8211; has added a lot of <strong>selection bias</strong> to the results. Are they caused by a real edge of the system, or just by biased development? Determining this with some certainty is the hardest part of strategy development.</p>
<p>The best way to find out is <a href="http://www.financial-hacker.com/whites-reality-check/">White&#8217;s Reality Check</a>. But it&#8217;s also the least practical because it requires strong discipline in parameter and algorithm selection. Other methods are not as good, but easier to apply:</p>
<ul>
<li><strong>Montecarlo</strong>. Randomize the price curve by shuffling without replacement, then train and test again. Repeat this many times. Plot a distribution of the results (an example of this method can be found in chapter 6 of the <a href="http://www.amazon.de/Das-B%C3%B6rsenhackerbuch-Finanziell-algorithmische-Handelssysteme/dp/1530310784" target="_blank" rel="noopener noreferrer">Börsenhackerbuch</a>). Randomizing removes all price anomalies, so you hope for significantly worse performance. But if the result from the real price curve lies not far east of the random distribution peak, it is probably also caused by randomness. That would mean: back to step 3.</li>
<li><strong>Variants.</strong> It&#8217;s the opposite of the Montecarlo method: Apply the trained system on variants of the price curve and hope for positive results. Variants that maintain most anomalies are <a href="http://www.financial-hacker.com/better-tests-with-oversampling/">oversampling</a>, detrending, or inverting the price curve. If the system stays profitable with those variants, but not with randomized prices, you might really have found a solid system.</li>
<li><strong>Really-out-of-sample (ROOS) Test</strong>. While developing the system, ignore the last year (2015) completely. Even delete all 2015 price history from your PC. Only when the system is completely finished, download the data and run a 2015 test. Since the 2015 data can be only used once this way and is then tainted, you can&nbsp;not modify the system anymore if it fails in 2015. Just abandon it. Assemble all your metal strength and go back to step 1.</li>
</ul>
<h3>Step 8: Risk management</h3>
<p>Your system has so far survived all tests. Now you can concentrate on reducing its risk and improving its performance. Do not touch anymore the entry algorithm and its parameters. You&#8217;re now optimizing the exit. Instead of the simple timed and reversal exits that we&#8217;ve used during the development phase, we can now apply various trailing stop mechanisms. For instance:</p>
<ul style="list-style-type: square;">
<li>Instead of exiting after a certain time, raise the stop loss by a certain amount per hour. This has the same effect, but will close unprofitable trades sooner and profitable trades later.</li>
<li>When a trade has won a certain amount, place the stop loss at a distance above the break even point. Even when locking a profit percentage does not improve the total performance, it&#8217;s good for your health. Seeing profitable trades wander back into the losing zone can cause serious ulcers.</li>
</ul>
<p>This is our example script with the initial timed exit replaced by a stop loss limit that rises at every bar:</p>
<pre class="prettyprint">function run()
{
  vars Price = series(price());
  var Phase = DominantPhase(Price,10);
  vars Signal = series(sin(Phase+optimize(1,0.7,2)*PI/4));
  vars Dominant = series(BandPass(Price,rDominantPeriod,1));
  var Threshold = optimize(1,0.7,2)*PIP;

  Stop = ATR(100);
  for(open_trades)
    TradeStopLimit -= TradeStopDiff/(10*rDominantPeriod);
	
  if(Amplitude(Dominant,100) &gt; Threshold) {
    if(valley(Signal))
      reverseLong(1); 
    else if(peak(Signal))
      reverseShort(1);
  }
}</pre>
<p>The&nbsp;<strong>for(open_trades)</strong> loop increases the stop level of all open trades by a fraction of the initial stop loss distance at the end of every bar.</p>
<p>Of course you now have to optimize and run a walk forward analysis again with the exit parameters. If the performance didn&#8217;t improve, think about better exit methods.</p>
<h3>Step 9: Money management</h3>
<p>Money management serves three purposes. First, reinvesting your profits. Second, distributing your capital among portfolio components. And third, quickly finding out if a trading book is useless. Open the &#8220;Money Management&#8221; chapter and read the author&#8217;s investment advice. If it&#8217;s &#8220;invest 1% of your capital per trade&#8221;, you know why he&#8217;s writing trading books. He probably has not yet earned money with real trading.</p>
<p>Suppose your trade volume at a given time <em><strong>t</strong></em> is&nbsp;<em><strong>V(t)</strong></em>. If your system is profitable, on average your capital <em><strong>C</strong></em> will rise proportionally to <b><i>V</i></b> with a growth factor <em><strong>c</strong></em>:</p>
<p>[latex display=&#8221;true&#8221;]\frac{dC}{dt} = c V(t)~~\rightarrow~~ C(t) = C_0 + c \int_{0}^{t}{V(t) dt}[/latex]</p>
<p>When you follow trading book advices and always invest a fixed percentage <em><strong>p</strong></em>&nbsp;of your capital, so that <em><strong>V</strong><strong><em>(t)</em> = p C(t)</strong></em>, your capital will grow exponentially with exponent&nbsp;<em><strong>p c</strong></em>:</p>
<p>[latex display=&#8221;true&#8221;]\frac{dC}{dt} ~=~ c p C(t)&nbsp;~~\rightarrow~~&nbsp;C(t) ~=~ C_0 e^{p c t}[/latex]</p>
<p>Unfortunately your capital will also undergo random fluctuations, named <strong>Drawdowns</strong>. Drawdowns are proportial to the trade volume <em><strong>V(t)</strong></em>. On leveraged accounts with no limit to drawdowns, it can be shown from statistical considerations that the maximum drawdown depth <em><strong>D<sub>max</sub></strong></em> grows proportional to the square root of time <em><strong>t</strong></em>:</p>
<p>[latex display=&#8221;true&#8221;]{D_{max}}(t) ~=~ q V(t) \sqrt{t}[/latex]</p>
<p>So, with the fixed percentage investment:</p>
<p>[latex display=&#8221;true&#8221;]{D_{max}}(t) ~=~ q p C(t) \sqrt{t}[/latex]</p>
<p>and at the time <em><strong>T = 1/(q p)<sup>2</sup></strong></em>:</p>
<p>[latex display=&#8221;true&#8221;]{D_{max}}(T) ~=~ q p C(T) \frac{1}{q p} ~=~ C(T)[/latex]</p>
<p>You can see that around the time <em><strong>T&nbsp;= 1/(q p)<sup>2</sup></strong></em> a drawdown will eat up all your capital <em><strong>C(T)</strong></em>, no matter how profitable your strategy is and how you&#8217;ve choosen&nbsp;<em><strong>p</strong></em>! That&#8217;s why the 1% rule is a bad advice. And why I advise clients not to raise the trade volume proportionally to their accumulated profit, but to its square root &#8211; at least on leveraged accounts. Then, as long as the strategy does not deteriorate, they keep a safe distance from a margin call.</p>
<p>Dependent on whether you trade a single asset and algorithm or a portfolio of both, you can calculate the optimal investment with several methods. There&#8217;s the OptimalF formula by <strong>Ralph Vince</strong>, the Kelly formula by <strong>Ed Thorp</strong>, or <a href="http://www.financial-hacker.com/get-rich-slowly/">mean/variance optimization</a> by <strong>Harry Markowitz</strong>. Usually you won&#8217;t hard code reinvesting in your strategy, but calculate the investment volume externally, since you might want to withdraw or deposit money from time to time. This requires the overall volume to be set up manually, not by an automated process. A formula for proper reinvesting and withdrawing can be found in the Black Book.</p>
<h3>Step 10: Preparation for live trading</h3>
<p>You can now define the <strong>user interface</strong> of your trading system. Determine which parameters you want to change in real time, and which ones only at start of the system. Provide a method to control the trade volume, and a &#8216;Panic Button&#8217; for locking profit or cashing out in case of bad news. Display all trading relevant parameters in real time. Add buttons for re-training the system, and provide a method for comparing live results with backtest results, such as the <a href="http://www.financial-hacker.com/the-cold-blood-index/">Cold Blood Index</a>. Make sure that you can supervise the system from whereever you are, for instance through an online status page. Don&#8217;t be tempted to look onto it every five minutes. But you can make a mighty impression when you pull out your mobile phone on the summit of Mt. Ararat and explain to your fellow climbers: &#8220;Just checking my trades.&#8221;</p>
<h3>The real strategy development</h3>
<p>So far the theory. All fine and dandy, but how do you really develop a trading system? Everyone knows that there&#8217;s a huge gap between theory and practice. This is the real development process as testified by many seasoned algo traders:</p>
<p><strong>Step 1.</strong>&nbsp;Visit trader forums and find the thread about the new indicator with the fabulous returns.</p>
<p><strong>Step 2.</strong>&nbsp;Get the indicator working with a test system after a long coding session. Ugh, the backtest result does not look this good. You must have made some coding mistake. Debug. Debug some more.</p>
<p><strong>Step 3.</strong>&nbsp;Still no good result, but you have more tricks up your sleeve. Add a trailing stop. The results now look already better. Run a week analysis. Tuesday is a particular bad day for this strategy? Add a filter that prevents trading on Tuesday. Add more filters that prevent trades between 10 and 12 am, and when the price is below $14.50, and at full moon except on Fridays. Wait a long time for the simulation to finish. Wow, finally the backtest is in the green!</p>
<p><strong>Step 4.</strong> Of course you&#8217;re not fooled by in-sample results. After optimizing all 23 parameters, run a walk forward analysis. Wait a long time for the simulation to finish. Ugh, the result does not look this good. Try different WFA cycles. Try different bar periods. Wait a long time for the simulation to finish. Finally, with a 19-minutes bar period and 31 cycles, you get a sensational backtest result! And this completely out of sample!</p>
<p><strong>Step 5.</strong> Trade the system live.</p>
<p><strong>Step 6.</strong> Ugh, the result does not look this good.</p>
<p><strong>Step 7.</strong> Wait a long time for your bank account to recover. Inbetween, write a trading book.</p>
<hr>
<p>I&#8217;ve added the example script to the 2016 script repository. In the next part of this series we&#8217;ll look into the data mining approach with machine learning systems. We will examine price pattern detection, regression, neural networks, deep learning, decision trees, and support vector machines.</p>
<p style="text-align: right;"><strong>⇒&nbsp;<a href="http://www.financial-hacker.com/build-better-strategies-part-4-machine-learning/">Build Better Strategies &#8211; Part 4</a></strong></p>
]]></content:encoded>
					
					<wfw:commentRss>https://financial-hacker.com/build-better-strategies-part-3-the-development-process/feed/</wfw:commentRss>
			<slash:comments>61</slash:comments>
		
		
			</item>
	</channel>
</rss>
