Files
catalyst/example-algos.html
T
2018-02-21 15:52:05 -07:00

1380 lines
151 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Example Algorithms &mdash; Catalyst 0.4 documentation</title>
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="genindex.html"/>
<link rel="search" title="Search" href="search.html"/>
<link rel="top" title="Catalyst 0.4 documentation" href="index.html"/>
<link rel="next" title="Utilities" href="utilities.html"/>
<link rel="prev" title="Features" href="features.html"/>
<script src="_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="index.html" class="icon icon-home"> Catalyst
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="beginner-tutorial.html">Catalyst Beginner Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="live-trading.html">Live Trading</a></li>
<li class="toctree-l1"><a class="reference internal" href="features.html">Features</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Example Algorithms</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#overview">Overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="#buy-btc-simple-algorithm">Buy BTC Simple Algorithm</a></li>
<li class="toctree-l2"><a class="reference internal" href="#buy-and-hodl-algorithm">Buy and Hodl Algorithm</a></li>
<li class="toctree-l2"><a class="reference internal" href="#dual-moving-average-crossover">Dual Moving Average Crossover</a></li>
<li class="toctree-l2"><a class="reference internal" href="#mean-reversion-algorithm">Mean Reversion Algorithm</a></li>
<li class="toctree-l2"><a class="reference internal" href="#simple-universe">Simple Universe</a></li>
<li class="toctree-l2"><a class="reference internal" href="#portfolio-optimization">Portfolio Optimization</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="utilities.html">Utilities</a></li>
<li class="toctree-l1"><a class="reference internal" href="videos.html">Videos</a></li>
<li class="toctree-l1"><a class="reference internal" href="resources.html">Resources</a></li>
<li class="toctree-l1"><a class="reference internal" href="development-guidelines.html">Development Guidelines</a></li>
<li class="toctree-l1"><a class="reference internal" href="releases.html">Release Notes</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">Catalyst</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html">Docs</a> &raquo;</li>
<li>Example Algorithms</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/example-algos.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="line-block">
<div class="line"><br /></div>
</div>
<div class="section" id="example-algorithms">
<h1>Example Algorithms<a class="headerlink" href="#example-algorithms" title="Permalink to this headline"></a></h1>
<p>This section documents a number of example algorithms to complement the
beginner tutorial, and show how other trading algorithms can be implemented
using Catalyst.</p>
<div class="section" id="overview">
<h2>Overview<a class="headerlink" href="#overview" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><a class="reference internal" href="#buy-btc-simple"><span class="std std-ref">Buy BTC Simple</span></a>: The simplest algorithm that introduces
the <code class="docutils literal"><span class="pre">initialize()</span></code> and <code class="docutils literal"><span class="pre">handle_data()</span></code> functions, and is used in the
<a class="reference internal" href="beginner-tutorial.html"><span class="doc">beginner tutorial</span></a> to show how to run catalyst
for the first time.</li>
<li><a class="reference internal" href="#buy-and-hodl"><span class="std std-ref">Buy and Hodl</span></a>: A very straightforward <em>buy and hold</em> that
makes one single buy at the very beginning. Introduces the notions of
<code class="docutils literal"><span class="pre">cash</span></code>, management of outstanding <code class="docutils literal"><span class="pre">orders</span></code>, and <code class="docutils literal"><span class="pre">order_target_value</span></code>
to place orders. It also introduces the <code class="docutils literal"><span class="pre">analyze()</span></code> function to visualize
the performance of our strategy using the external library <code class="docutils literal"><span class="pre">matplotlib</span></code>.</li>
<li><a class="reference internal" href="#dual-moving-average"><span class="std std-ref">Dual Moving Average Crossover</span></a>: A classic momentum
strategy used in the second part of the
<a class="reference external" href="beginner-tutorial.html#history">beginner tutorial</a> to introduce the
<code class="docutils literal"><span class="pre">data.history()</span></code> function. It makes a heavy use of <code class="docutils literal"><span class="pre">matplotlib</span></code> library
in the <code class="docutils literal"><span class="pre">analyze()</span></code> function to chart the performance of the algorithm.</li>
<li><a class="reference internal" href="#mean-reversion"><span class="std std-ref">Mean Reversion Algorithm</span></a>: Another simple momentum
strategy that is used in our
<a class="reference external" href="videos.html#backtesting-a-strategy">two-part video tutorial</a> to show how
to get started in backtesting and live trading with Catalyst.</li>
<li><a class="reference internal" href="#simple-universe"><span class="std std-ref">Simple Universe</span></a>: This code provides the universe
of available trading pairs on a given exchange on any given day. You can use
this code to dynamically select which currency pairs you want to trade each
day of your strategy. This example does not make any trades.</li>
<li><a class="reference internal" href="#portfolio-optimization"><span class="std std-ref">Portfolio Optimization</span></a>: Use this code to
execute a portfolio optimization model. This strategy will select the
portfolio with the maximum Sharpe Ratio. The parameters are set to use 180
days of historical data and rebalance every 30 days. This code was used in
writting the following article:
<a class="reference external" href="https://blog.enigma.co/markowitz-portfolio-optimization-for-cryptocurrencies-in-catalyst-b23c38652556">Markowitz Portfolio Optimization for Cryptocurrencies</a>.</li>
</ul>
</div>
<div class="section" id="buy-btc-simple-algorithm">
<span id="buy-btc-simple"></span><h2>Buy BTC Simple Algorithm<a class="headerlink" href="#buy-btc-simple-algorithm" title="Permalink to this headline"></a></h2>
<p>Source code: <a class="reference external" href="https://github.com/enigmampc/catalyst/blob/master/catalyst/examples/buy_btc_simple.py">examples/buy_btc_simple.py</a></p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> This is a very simple example referenced in the beginner&#39;s tutorial:</span>
<span class="sd"> https://enigmampc.github.io/catalyst/beginner-tutorial.html</span>
<span class="sd"> Run this example, by executing the following from your terminal:</span>
<span class="sd"> catalyst ingest-exchange -x bitfinex -f daily -i btc_usdt</span>
<span class="sd"> catalyst run -f buy_btc_simple.py -x bitfinex --start 2016-1-1 \</span>
<span class="sd"> --end 2017-9-30 -o buy_btc_simple_out.pickle</span>
<span class="sd"> If you want to run this code using another exchange, make sure that</span>
<span class="sd"> the asset is available on that exchange. For example, if you were to run</span>
<span class="sd"> it for exchange Poloniex, you would need to edit the following line:</span>
<span class="sd"> context.asset = symbol(&#39;btc_usdt&#39;) # note &#39;usdt&#39; instead of &#39;usd&#39;</span>
<span class="sd"> and specify exchange poloniex as follows:</span>
<span class="sd"> catalyst ingest-exchange -x poloniex -f daily -i btc_usdt</span>
<span class="sd"> catalyst run -f buy_btc_simple.py -x poloniex --start 2016-1-1 \</span>
<span class="sd"> --end 2017-9-30 -o buy_btc_simple_out.pickle</span>
<span class="sd"> To see which assets are available on each exchange, visit:</span>
<span class="sd"> https://www.enigma.co/catalyst/status</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="kn">from</span> <span class="nn">catalyst</span> <span class="kn">import</span> <span class="n">run_algorithm</span>
<span class="kn">from</span> <span class="nn">catalyst.api</span> <span class="kn">import</span> <span class="n">order</span><span class="p">,</span> <span class="n">record</span><span class="p">,</span> <span class="n">symbol</span>
<span class="kn">import</span> <span class="nn">pandas</span> <span class="kn">as</span> <span class="nn">pd</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">context</span><span class="p">):</span>
<span class="n">context</span><span class="o">.</span><span class="n">asset</span> <span class="o">=</span> <span class="n">symbol</span><span class="p">(</span><span class="s1">&#39;btc_usdt&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">handle_data</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="n">order</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">asset</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">record</span><span class="p">(</span><span class="n">btc</span><span class="o">=</span><span class="n">data</span><span class="o">.</span><span class="n">current</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">asset</span><span class="p">,</span> <span class="s1">&#39;price&#39;</span><span class="p">))</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
<span class="n">run_algorithm</span><span class="p">(</span>
<span class="n">capital_base</span><span class="o">=</span><span class="mi">10000</span><span class="p">,</span>
<span class="n">data_frequency</span><span class="o">=</span><span class="s1">&#39;daily&#39;</span><span class="p">,</span>
<span class="n">initialize</span><span class="o">=</span><span class="n">initialize</span><span class="p">,</span>
<span class="n">handle_data</span><span class="o">=</span><span class="n">handle_data</span><span class="p">,</span>
<span class="n">exchange_name</span><span class="o">=</span><span class="s1">&#39;poloniex&#39;</span><span class="p">,</span>
<span class="n">algo_namespace</span><span class="o">=</span><span class="s1">&#39;buy_and_hodl&#39;</span><span class="p">,</span>
<span class="n">base_currency</span><span class="o">=</span><span class="s1">&#39;usdt&#39;</span><span class="p">,</span>
<span class="n">start</span><span class="o">=</span><span class="n">pd</span><span class="o">.</span><span class="n">to_datetime</span><span class="p">(</span><span class="s1">&#39;2015-03-01&#39;</span><span class="p">,</span> <span class="n">utc</span><span class="o">=</span><span class="bp">True</span><span class="p">),</span>
<span class="n">end</span><span class="o">=</span><span class="n">pd</span><span class="o">.</span><span class="n">to_datetime</span><span class="p">(</span><span class="s1">&#39;2017-10-31&#39;</span><span class="p">,</span> <span class="n">utc</span><span class="o">=</span><span class="bp">True</span><span class="p">),</span>
<span class="p">)</span>
</pre></div>
</div>
<p>This simple algorithm does not produce any output nor displays any chart.</p>
</div>
<div class="section" id="buy-and-hodl-algorithm">
<span id="buy-and-hodl"></span><h2>Buy and Hodl Algorithm<a class="headerlink" href="#buy-and-hodl-algorithm" title="Permalink to this headline"></a></h2>
<p>First ingest the historical pricing data needed to run this algorithm:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>catalyst ingest-exchange -x bitfinex -f daily -i btc_usd
</pre></div>
</div>
<p>Then, you can run the code below with the following command:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>catalyst run -f buy_and_hodl.py --start <span class="m">2015</span>-3-1 --end <span class="m">2017</span>-10-31 --capital-base <span class="m">100000</span> -x bitfinex -c btc -o bah.pickle
</pre></div>
</div>
<p>or using the same parameters specified in the run_algorithm() function at the
end of the file:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>python buy_and_hodl.py
</pre></div>
</div>
<p>This command will run the trading algorithm in the specified time range and
plot the resulting performance using the matplotlib library. You can choose any
date interval with the <code class="docutils literal"><span class="pre">--start</span></code> and <code class="docutils literal"><span class="pre">--end</span></code> parameters, but bear in mind
that 2015-3-1 is the earliest date that Catalyst supports (if you choose an
earlier date, youll get an error), and the most recent date you can choose is
one day prior to the current date.</p>
<p>Source code: <a class="reference external" href="https://github.com/enigmampc/catalyst/blob/master/catalyst/examples/buy_and_hodl.py">examples/buy_and_hodl.py</a></p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env python</span>
<span class="c1">#</span>
<span class="c1"># Copyright 2017 Enigma MPC, Inc.</span>
<span class="c1"># Copyright 2015 Quantopian, Inc.</span>
<span class="c1">#</span>
<span class="c1"># Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span>
<span class="c1"># you may not use this file except in compliance with the License.</span>
<span class="c1"># You may obtain a copy of the License at</span>
<span class="c1">#</span>
<span class="c1"># http://www.apache.org/licenses/LICENSE-2.0</span>
<span class="c1">#</span>
<span class="c1"># Unless required by applicable law or agreed to in writing, software</span>
<span class="c1"># distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span>
<span class="c1"># WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span>
<span class="c1"># See the License for the specific language governing permissions and</span>
<span class="c1"># limitations under the License.</span>
<span class="kn">import</span> <span class="nn">pandas</span> <span class="kn">as</span> <span class="nn">pd</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="kn">as</span> <span class="nn">plt</span>
<span class="kn">from</span> <span class="nn">catalyst</span> <span class="kn">import</span> <span class="n">run_algorithm</span>
<span class="kn">from</span> <span class="nn">catalyst.api</span> <span class="kn">import</span> <span class="p">(</span><span class="n">order_target_value</span><span class="p">,</span> <span class="n">symbol</span><span class="p">,</span> <span class="n">record</span><span class="p">,</span>
<span class="n">cancel_order</span><span class="p">,</span> <span class="n">get_open_orders</span><span class="p">,</span> <span class="p">)</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">context</span><span class="p">):</span>
<span class="n">context</span><span class="o">.</span><span class="n">ASSET_NAME</span> <span class="o">=</span> <span class="s1">&#39;btc_usdt&#39;</span>
<span class="n">context</span><span class="o">.</span><span class="n">TARGET_HODL_RATIO</span> <span class="o">=</span> <span class="mf">0.8</span>
<span class="n">context</span><span class="o">.</span><span class="n">RESERVE_RATIO</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="o">-</span> <span class="n">context</span><span class="o">.</span><span class="n">TARGET_HODL_RATIO</span>
<span class="n">context</span><span class="o">.</span><span class="n">is_buying</span> <span class="o">=</span> <span class="bp">True</span>
<span class="n">context</span><span class="o">.</span><span class="n">asset</span> <span class="o">=</span> <span class="n">symbol</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">ASSET_NAME</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">def</span> <span class="nf">handle_data</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="n">context</span><span class="o">.</span><span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">starting_cash</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">portfolio</span><span class="o">.</span><span class="n">starting_cash</span>
<span class="n">target_hodl_value</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">TARGET_HODL_RATIO</span> <span class="o">*</span> <span class="n">starting_cash</span>
<span class="n">reserve_value</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">RESERVE_RATIO</span> <span class="o">*</span> <span class="n">starting_cash</span>
<span class="c1"># Cancel any outstanding orders</span>
<span class="n">orders</span> <span class="o">=</span> <span class="n">get_open_orders</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">asset</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">order</span> <span class="ow">in</span> <span class="n">orders</span><span class="p">:</span>
<span class="n">cancel_order</span><span class="p">(</span><span class="n">order</span><span class="p">)</span>
<span class="c1"># Stop buying after passing the reserve threshold</span>
<span class="n">cash</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">portfolio</span><span class="o">.</span><span class="n">cash</span>
<span class="k">if</span> <span class="n">cash</span> <span class="o">&lt;=</span> <span class="n">reserve_value</span><span class="p">:</span>
<span class="n">context</span><span class="o">.</span><span class="n">is_buying</span> <span class="o">=</span> <span class="bp">False</span>
<span class="c1"># Retrieve current asset price from pricing data</span>
<span class="n">price</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">current</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">asset</span><span class="p">,</span> <span class="s1">&#39;price&#39;</span><span class="p">)</span>
<span class="c1"># Check if still buying and could (approximately) afford another purchase</span>
<span class="k">if</span> <span class="n">context</span><span class="o">.</span><span class="n">is_buying</span> <span class="ow">and</span> <span class="n">cash</span> <span class="o">&gt;</span> <span class="n">price</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="s1">&#39;buying&#39;</span><span class="p">)</span>
<span class="c1"># Place order to make position in asset equal to target_hodl_value</span>
<span class="n">order_target_value</span><span class="p">(</span>
<span class="n">context</span><span class="o">.</span><span class="n">asset</span><span class="p">,</span>
<span class="n">target_hodl_value</span><span class="p">,</span>
<span class="n">limit_price</span><span class="o">=</span><span class="n">price</span> <span class="o">*</span> <span class="mf">1.1</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">record</span><span class="p">(</span>
<span class="n">price</span><span class="o">=</span><span class="n">price</span><span class="p">,</span>
<span class="n">volume</span><span class="o">=</span><span class="n">data</span><span class="o">.</span><span class="n">current</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">asset</span><span class="p">,</span> <span class="s1">&#39;volume&#39;</span><span class="p">),</span>
<span class="n">cash</span><span class="o">=</span><span class="n">cash</span><span class="p">,</span>
<span class="n">starting_cash</span><span class="o">=</span><span class="n">context</span><span class="o">.</span><span class="n">portfolio</span><span class="o">.</span><span class="n">starting_cash</span><span class="p">,</span>
<span class="n">leverage</span><span class="o">=</span><span class="n">context</span><span class="o">.</span><span class="n">account</span><span class="o">.</span><span class="n">leverage</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">def</span> <span class="nf">analyze</span><span class="p">(</span><span class="n">context</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">results</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="c1"># Plot the portfolio and asset data.</span>
<span class="n">ax1</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">611</span><span class="p">)</span>
<span class="n">results</span><span class="p">[[</span><span class="s1">&#39;portfolio_value&#39;</span><span class="p">]]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ax</span><span class="o">=</span><span class="n">ax1</span><span class="p">)</span>
<span class="n">ax1</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">&#39;Portfolio</span><span class="se">\n</span><span class="s1">Value</span><span class="se">\n</span><span class="s1">(USD)&#39;</span><span class="p">)</span>
<span class="n">ax2</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">612</span><span class="p">,</span> <span class="n">sharex</span><span class="o">=</span><span class="n">ax1</span><span class="p">)</span>
<span class="n">ax2</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">&#39;{asset}</span><span class="se">\n</span><span class="s1">(USD)&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">asset</span><span class="o">=</span><span class="n">context</span><span class="o">.</span><span class="n">ASSET_NAME</span><span class="p">))</span>
<span class="n">results</span><span class="p">[[</span><span class="s1">&#39;price&#39;</span><span class="p">]]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ax</span><span class="o">=</span><span class="n">ax2</span><span class="p">)</span>
<span class="n">trans</span> <span class="o">=</span> <span class="n">results</span><span class="o">.</span><span class="n">ix</span><span class="p">[[</span><span class="n">t</span> <span class="o">!=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">results</span><span class="o">.</span><span class="n">transactions</span><span class="p">]]</span>
<span class="n">buys</span> <span class="o">=</span> <span class="n">trans</span><span class="o">.</span><span class="n">ix</span><span class="p">[</span>
<span class="p">[</span><span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s1">&#39;amount&#39;</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">trans</span><span class="o">.</span><span class="n">transactions</span><span class="p">]</span>
<span class="p">]</span>
<span class="n">ax2</span><span class="o">.</span><span class="n">scatter</span><span class="p">(</span>
<span class="n">buys</span><span class="o">.</span><span class="n">index</span><span class="o">.</span><span class="n">to_pydatetime</span><span class="p">(),</span>
<span class="n">results</span><span class="o">.</span><span class="n">price</span><span class="p">[</span><span class="n">buys</span><span class="o">.</span><span class="n">index</span><span class="p">],</span>
<span class="n">marker</span><span class="o">=</span><span class="s1">&#39;^&#39;</span><span class="p">,</span>
<span class="n">s</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span>
<span class="n">c</span><span class="o">=</span><span class="s1">&#39;g&#39;</span><span class="p">,</span>
<span class="n">label</span><span class="o">=</span><span class="s1">&#39;&#39;</span>
<span class="p">)</span>
<span class="n">ax3</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">613</span><span class="p">,</span> <span class="n">sharex</span><span class="o">=</span><span class="n">ax1</span><span class="p">)</span>
<span class="n">results</span><span class="p">[[</span><span class="s1">&#39;leverage&#39;</span><span class="p">,</span> <span class="s1">&#39;alpha&#39;</span><span class="p">,</span> <span class="s1">&#39;beta&#39;</span><span class="p">]]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ax</span><span class="o">=</span><span class="n">ax3</span><span class="p">)</span>
<span class="n">ax3</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">&#39;Leverage &#39;</span><span class="p">)</span>
<span class="n">ax4</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">614</span><span class="p">,</span> <span class="n">sharex</span><span class="o">=</span><span class="n">ax1</span><span class="p">)</span>
<span class="n">results</span><span class="p">[[</span><span class="s1">&#39;starting_cash&#39;</span><span class="p">,</span> <span class="s1">&#39;cash&#39;</span><span class="p">]]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ax</span><span class="o">=</span><span class="n">ax4</span><span class="p">)</span>
<span class="n">ax4</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">&#39;Cash (USD)&#39;</span><span class="p">)</span>
<span class="n">results</span><span class="p">[[</span>
<span class="s1">&#39;treasury&#39;</span><span class="p">,</span>
<span class="s1">&#39;algorithm&#39;</span><span class="p">,</span>
<span class="s1">&#39;benchmark&#39;</span><span class="p">,</span>
<span class="p">]]</span> <span class="o">=</span> <span class="n">results</span><span class="p">[[</span>
<span class="s1">&#39;treasury_period_return&#39;</span><span class="p">,</span>
<span class="s1">&#39;algorithm_period_return&#39;</span><span class="p">,</span>
<span class="s1">&#39;benchmark_period_return&#39;</span><span class="p">,</span>
<span class="p">]]</span>
<span class="n">ax5</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">615</span><span class="p">,</span> <span class="n">sharex</span><span class="o">=</span><span class="n">ax1</span><span class="p">)</span>
<span class="n">results</span><span class="p">[[</span>
<span class="s1">&#39;treasury&#39;</span><span class="p">,</span>
<span class="s1">&#39;algorithm&#39;</span><span class="p">,</span>
<span class="s1">&#39;benchmark&#39;</span><span class="p">,</span>
<span class="p">]]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ax</span><span class="o">=</span><span class="n">ax5</span><span class="p">)</span>
<span class="n">ax5</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">&#39;Percent</span><span class="se">\n</span><span class="s1">Change&#39;</span><span class="p">)</span>
<span class="n">ax6</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">616</span><span class="p">,</span> <span class="n">sharex</span><span class="o">=</span><span class="n">ax1</span><span class="p">)</span>
<span class="n">results</span><span class="p">[[</span><span class="s1">&#39;volume&#39;</span><span class="p">]]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ax</span><span class="o">=</span><span class="n">ax6</span><span class="p">)</span>
<span class="n">ax6</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">&#39;Volume&#39;</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">legend</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="c1"># Show the plot.</span>
<span class="n">plt</span><span class="o">.</span><span class="n">gcf</span><span class="p">()</span><span class="o">.</span><span class="n">set_size_inches</span><span class="p">(</span><span class="mi">18</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
<span class="n">run_algorithm</span><span class="p">(</span>
<span class="n">capital_base</span><span class="o">=</span><span class="mi">10000</span><span class="p">,</span>
<span class="n">data_frequency</span><span class="o">=</span><span class="s1">&#39;daily&#39;</span><span class="p">,</span>
<span class="n">initialize</span><span class="o">=</span><span class="n">initialize</span><span class="p">,</span>
<span class="n">handle_data</span><span class="o">=</span><span class="n">handle_data</span><span class="p">,</span>
<span class="n">analyze</span><span class="o">=</span><span class="n">analyze</span><span class="p">,</span>
<span class="n">exchange_name</span><span class="o">=</span><span class="s1">&#39;poloniex&#39;</span><span class="p">,</span>
<span class="n">algo_namespace</span><span class="o">=</span><span class="s1">&#39;buy_and_hodl&#39;</span><span class="p">,</span>
<span class="n">base_currency</span><span class="o">=</span><span class="s1">&#39;usdt&#39;</span><span class="p">,</span>
<span class="n">start</span><span class="o">=</span><span class="n">pd</span><span class="o">.</span><span class="n">to_datetime</span><span class="p">(</span><span class="s1">&#39;2015-03-01&#39;</span><span class="p">,</span> <span class="n">utc</span><span class="o">=</span><span class="bp">True</span><span class="p">),</span>
<span class="n">end</span><span class="o">=</span><span class="n">pd</span><span class="o">.</span><span class="n">to_datetime</span><span class="p">(</span><span class="s1">&#39;2017-10-31&#39;</span><span class="p">,</span> <span class="n">utc</span><span class="o">=</span><span class="bp">True</span><span class="p">),</span>
<span class="p">)</span>
</pre></div>
</div>
<img alt="https://s3.amazonaws.com/enigmaco-docs/github.io/example_buy_and_hodl.png" src="https://s3.amazonaws.com/enigmaco-docs/github.io/example_buy_and_hodl.png" />
</div>
<div class="section" id="dual-moving-average-crossover">
<span id="dual-moving-average"></span><h2>Dual Moving Average Crossover<a class="headerlink" href="#dual-moving-average-crossover" title="Permalink to this headline"></a></h2>
<p>This strategy is covered in detail in the last part of
<a class="reference external" href="beginner-tutorial.html#history">this tutorial</a>.</p>
<p>Source Code: <a class="reference external" href="https://github.com/enigmampc/catalyst/blob/master/catalyst/examples/dual_moving_average.py">examples/dual_moving_average.py</a></p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="kn">as</span> <span class="nn">plt</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="kn">as</span> <span class="nn">np</span>
<span class="kn">import</span> <span class="nn">pandas</span> <span class="kn">as</span> <span class="nn">pd</span>
<span class="kn">from</span> <span class="nn">logbook</span> <span class="kn">import</span> <span class="n">Logger</span>
<span class="kn">from</span> <span class="nn">catalyst</span> <span class="kn">import</span> <span class="n">run_algorithm</span>
<span class="kn">from</span> <span class="nn">catalyst.api</span> <span class="kn">import</span> <span class="p">(</span><span class="n">record</span><span class="p">,</span> <span class="n">symbol</span><span class="p">,</span> <span class="n">order_target_percent</span><span class="p">,</span>
<span class="n">get_open_orders</span><span class="p">)</span>
<span class="kn">from</span> <span class="nn">catalyst.exchange.utils.stats_utils</span> <span class="kn">import</span> <span class="n">extract_transactions</span>
<span class="n">NAMESPACE</span> <span class="o">=</span> <span class="s1">&#39;dual_moving_average&#39;</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">Logger</span><span class="p">(</span><span class="n">NAMESPACE</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">context</span><span class="p">):</span>
<span class="n">context</span><span class="o">.</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">context</span><span class="o">.</span><span class="n">asset</span> <span class="o">=</span> <span class="n">symbol</span><span class="p">(</span><span class="s1">&#39;ltc_usd&#39;</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">base_price</span> <span class="o">=</span> <span class="bp">None</span>
<span class="k">def</span> <span class="nf">handle_data</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="c1"># define the windows for the moving averages</span>
<span class="n">short_window</span> <span class="o">=</span> <span class="mi">2</span>
<span class="n">long_window</span> <span class="o">=</span> <span class="mi">3</span>
<span class="c1"># Skip as many bars as long_window to properly compute the average</span>
<span class="n">context</span><span class="o">.</span><span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">context</span><span class="o">.</span><span class="n">i</span> <span class="o">&lt;</span> <span class="n">long_window</span><span class="p">:</span>
<span class="k">return</span>
<span class="c1"># Compute moving averages calling data.history() for each</span>
<span class="c1"># moving average with the appropriate parameters. We choose to use</span>
<span class="c1"># minute bars for this simulation -&gt; freq=&quot;1m&quot;</span>
<span class="c1"># Returns a pandas dataframe.</span>
<span class="n">short_data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">history</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">asset</span><span class="p">,</span>
<span class="s1">&#39;price&#39;</span><span class="p">,</span>
<span class="n">bar_count</span><span class="o">=</span><span class="n">short_window</span><span class="p">,</span>
<span class="n">frequency</span><span class="o">=</span><span class="s2">&quot;1T&quot;</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">short_mavg</span> <span class="o">=</span> <span class="n">short_data</span><span class="o">.</span><span class="n">mean</span><span class="p">()</span>
<span class="n">long_data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">history</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">asset</span><span class="p">,</span>
<span class="s1">&#39;price&#39;</span><span class="p">,</span>
<span class="n">bar_count</span><span class="o">=</span><span class="n">long_window</span><span class="p">,</span>
<span class="n">frequency</span><span class="o">=</span><span class="s2">&quot;1T&quot;</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">long_mavg</span> <span class="o">=</span> <span class="n">long_data</span><span class="o">.</span><span class="n">mean</span><span class="p">()</span>
<span class="c1"># Let&#39;s keep the price of our asset in a more handy variable</span>
<span class="n">price</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">current</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">asset</span><span class="p">,</span> <span class="s1">&#39;price&#39;</span><span class="p">)</span>
<span class="c1"># If base_price is not set, we use the current value. This is the</span>
<span class="c1"># price at the first bar which we reference to calculate price_change.</span>
<span class="k">if</span> <span class="n">context</span><span class="o">.</span><span class="n">base_price</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">context</span><span class="o">.</span><span class="n">base_price</span> <span class="o">=</span> <span class="n">price</span>
<span class="n">price_change</span> <span class="o">=</span> <span class="p">(</span><span class="n">price</span> <span class="o">-</span> <span class="n">context</span><span class="o">.</span><span class="n">base_price</span><span class="p">)</span> <span class="o">/</span> <span class="n">context</span><span class="o">.</span><span class="n">base_price</span>
<span class="c1"># Save values for later inspection</span>
<span class="n">record</span><span class="p">(</span><span class="n">price</span><span class="o">=</span><span class="n">price</span><span class="p">,</span>
<span class="n">cash</span><span class="o">=</span><span class="n">context</span><span class="o">.</span><span class="n">portfolio</span><span class="o">.</span><span class="n">cash</span><span class="p">,</span>
<span class="n">price_change</span><span class="o">=</span><span class="n">price_change</span><span class="p">,</span>
<span class="n">short_mavg</span><span class="o">=</span><span class="n">short_mavg</span><span class="p">,</span>
<span class="n">long_mavg</span><span class="o">=</span><span class="n">long_mavg</span><span class="p">)</span>
<span class="c1"># Since we are using limit orders, some orders may not execute immediately</span>
<span class="c1"># we wait until all orders are executed before considering more trades.</span>
<span class="n">orders</span> <span class="o">=</span> <span class="n">get_open_orders</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">asset</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">orders</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span>
<span class="c1"># Exit if we cannot trade</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">data</span><span class="o">.</span><span class="n">can_trade</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">asset</span><span class="p">):</span>
<span class="k">return</span>
<span class="c1"># We check what&#39;s our position on our portfolio and trade accordingly</span>
<span class="n">pos_amount</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">portfolio</span><span class="o">.</span><span class="n">positions</span><span class="p">[</span><span class="n">context</span><span class="o">.</span><span class="n">asset</span><span class="p">]</span><span class="o">.</span><span class="n">amount</span>
<span class="c1"># Trading logic</span>
<span class="k">if</span> <span class="n">short_mavg</span> <span class="o">&gt;</span> <span class="n">long_mavg</span> <span class="ow">and</span> <span class="n">pos_amount</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="c1"># we buy 100% of our portfolio for this asset</span>
<span class="n">order_target_percent</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">asset</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">short_mavg</span> <span class="o">&lt;</span> <span class="n">long_mavg</span> <span class="ow">and</span> <span class="n">pos_amount</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="c1"># we sell all our positions for this asset</span>
<span class="n">order_target_percent</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">asset</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">analyze</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">perf</span><span class="p">):</span>
<span class="c1"># Get the base_currency that was passed as a parameter to the simulation</span>
<span class="n">exchange</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">exchanges</span><span class="o">.</span><span class="n">values</span><span class="p">())[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">base_currency</span> <span class="o">=</span> <span class="n">exchange</span><span class="o">.</span><span class="n">base_currency</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span>
<span class="c1"># First chart: Plot portfolio value using base_currency</span>
<span class="n">ax1</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">411</span><span class="p">)</span>
<span class="n">perf</span><span class="o">.</span><span class="n">loc</span><span class="p">[:,</span> <span class="p">[</span><span class="s1">&#39;portfolio_value&#39;</span><span class="p">]]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ax</span><span class="o">=</span><span class="n">ax1</span><span class="p">)</span>
<span class="n">ax1</span><span class="o">.</span><span class="n">legend_</span><span class="o">.</span><span class="n">remove</span><span class="p">()</span>
<span class="n">ax1</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">&#39;Portfolio Value</span><span class="se">\n</span><span class="s1">({})&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">base_currency</span><span class="p">))</span>
<span class="n">start</span><span class="p">,</span> <span class="n">end</span> <span class="o">=</span> <span class="n">ax1</span><span class="o">.</span><span class="n">get_ylim</span><span class="p">()</span>
<span class="n">ax1</span><span class="o">.</span><span class="n">yaxis</span><span class="o">.</span><span class="n">set_ticks</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="p">,</span> <span class="p">(</span><span class="n">end</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">/</span> <span class="mi">5</span><span class="p">))</span>
<span class="c1"># Second chart: Plot asset price, moving averages and buys/sells</span>
<span class="n">ax2</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">412</span><span class="p">,</span> <span class="n">sharex</span><span class="o">=</span><span class="n">ax1</span><span class="p">)</span>
<span class="n">perf</span><span class="o">.</span><span class="n">loc</span><span class="p">[:,</span> <span class="p">[</span><span class="s1">&#39;price&#39;</span><span class="p">,</span> <span class="s1">&#39;short_mavg&#39;</span><span class="p">,</span> <span class="s1">&#39;long_mavg&#39;</span><span class="p">]]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span>
<span class="n">ax</span><span class="o">=</span><span class="n">ax2</span><span class="p">,</span>
<span class="n">label</span><span class="o">=</span><span class="s1">&#39;Price&#39;</span><span class="p">)</span>
<span class="n">ax2</span><span class="o">.</span><span class="n">legend_</span><span class="o">.</span><span class="n">remove</span><span class="p">()</span>
<span class="n">ax2</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">&#39;{asset}</span><span class="se">\n</span><span class="s1">({base})&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">asset</span><span class="o">=</span><span class="n">context</span><span class="o">.</span><span class="n">asset</span><span class="o">.</span><span class="n">symbol</span><span class="p">,</span>
<span class="n">base</span><span class="o">=</span><span class="n">base_currency</span>
<span class="p">))</span>
<span class="n">start</span><span class="p">,</span> <span class="n">end</span> <span class="o">=</span> <span class="n">ax2</span><span class="o">.</span><span class="n">get_ylim</span><span class="p">()</span>
<span class="n">ax2</span><span class="o">.</span><span class="n">yaxis</span><span class="o">.</span><span class="n">set_ticks</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="p">,</span> <span class="p">(</span><span class="n">end</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">/</span> <span class="mi">5</span><span class="p">))</span>
<span class="n">transaction_df</span> <span class="o">=</span> <span class="n">extract_transactions</span><span class="p">(</span><span class="n">perf</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">transaction_df</span><span class="o">.</span><span class="n">empty</span><span class="p">:</span>
<span class="n">buy_df</span> <span class="o">=</span> <span class="n">transaction_df</span><span class="p">[</span><span class="n">transaction_df</span><span class="p">[</span><span class="s1">&#39;amount&#39;</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">]</span>
<span class="n">sell_df</span> <span class="o">=</span> <span class="n">transaction_df</span><span class="p">[</span><span class="n">transaction_df</span><span class="p">[</span><span class="s1">&#39;amount&#39;</span><span class="p">]</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">]</span>
<span class="n">ax2</span><span class="o">.</span><span class="n">scatter</span><span class="p">(</span>
<span class="n">buy_df</span><span class="o">.</span><span class="n">index</span><span class="o">.</span><span class="n">to_pydatetime</span><span class="p">(),</span>
<span class="n">perf</span><span class="o">.</span><span class="n">loc</span><span class="p">[</span><span class="n">buy_df</span><span class="o">.</span><span class="n">index</span><span class="p">,</span> <span class="s1">&#39;price&#39;</span><span class="p">],</span>
<span class="n">marker</span><span class="o">=</span><span class="s1">&#39;^&#39;</span><span class="p">,</span>
<span class="n">s</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span>
<span class="n">c</span><span class="o">=</span><span class="s1">&#39;green&#39;</span><span class="p">,</span>
<span class="n">label</span><span class="o">=</span><span class="s1">&#39;&#39;</span>
<span class="p">)</span>
<span class="n">ax2</span><span class="o">.</span><span class="n">scatter</span><span class="p">(</span>
<span class="n">sell_df</span><span class="o">.</span><span class="n">index</span><span class="o">.</span><span class="n">to_pydatetime</span><span class="p">(),</span>
<span class="n">perf</span><span class="o">.</span><span class="n">loc</span><span class="p">[</span><span class="n">sell_df</span><span class="o">.</span><span class="n">index</span><span class="p">,</span> <span class="s1">&#39;price&#39;</span><span class="p">],</span>
<span class="n">marker</span><span class="o">=</span><span class="s1">&#39;v&#39;</span><span class="p">,</span>
<span class="n">s</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span>
<span class="n">c</span><span class="o">=</span><span class="s1">&#39;red&#39;</span><span class="p">,</span>
<span class="n">label</span><span class="o">=</span><span class="s1">&#39;&#39;</span>
<span class="p">)</span>
<span class="c1"># Third chart: Compare percentage change between our portfolio</span>
<span class="c1"># and the price of the asset</span>
<span class="n">ax3</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">413</span><span class="p">,</span> <span class="n">sharex</span><span class="o">=</span><span class="n">ax1</span><span class="p">)</span>
<span class="n">perf</span><span class="o">.</span><span class="n">loc</span><span class="p">[:,</span> <span class="p">[</span><span class="s1">&#39;algorithm_period_return&#39;</span><span class="p">,</span> <span class="s1">&#39;price_change&#39;</span><span class="p">]]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ax</span><span class="o">=</span><span class="n">ax3</span><span class="p">)</span>
<span class="n">ax3</span><span class="o">.</span><span class="n">legend_</span><span class="o">.</span><span class="n">remove</span><span class="p">()</span>
<span class="n">ax3</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">&#39;Percent Change&#39;</span><span class="p">)</span>
<span class="n">start</span><span class="p">,</span> <span class="n">end</span> <span class="o">=</span> <span class="n">ax3</span><span class="o">.</span><span class="n">get_ylim</span><span class="p">()</span>
<span class="n">ax3</span><span class="o">.</span><span class="n">yaxis</span><span class="o">.</span><span class="n">set_ticks</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="p">,</span> <span class="p">(</span><span class="n">end</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">/</span> <span class="mi">5</span><span class="p">))</span>
<span class="c1"># Fourth chart: Plot our cash</span>
<span class="n">ax4</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">414</span><span class="p">,</span> <span class="n">sharex</span><span class="o">=</span><span class="n">ax1</span><span class="p">)</span>
<span class="n">perf</span><span class="o">.</span><span class="n">cash</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ax</span><span class="o">=</span><span class="n">ax4</span><span class="p">)</span>
<span class="n">ax4</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">&#39;Cash</span><span class="se">\n</span><span class="s1">({})&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">base_currency</span><span class="p">))</span>
<span class="n">start</span><span class="p">,</span> <span class="n">end</span> <span class="o">=</span> <span class="n">ax4</span><span class="o">.</span><span class="n">get_ylim</span><span class="p">()</span>
<span class="n">ax4</span><span class="o">.</span><span class="n">yaxis</span><span class="o">.</span><span class="n">set_ticks</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">end</span><span class="p">,</span> <span class="n">end</span> <span class="o">/</span> <span class="mi">5</span><span class="p">))</span>
<span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
<span class="n">run_algorithm</span><span class="p">(</span>
<span class="n">capital_base</span><span class="o">=</span><span class="mi">1000</span><span class="p">,</span>
<span class="n">data_frequency</span><span class="o">=</span><span class="s1">&#39;minute&#39;</span><span class="p">,</span>
<span class="n">initialize</span><span class="o">=</span><span class="n">initialize</span><span class="p">,</span>
<span class="n">handle_data</span><span class="o">=</span><span class="n">handle_data</span><span class="p">,</span>
<span class="n">analyze</span><span class="o">=</span><span class="n">analyze</span><span class="p">,</span>
<span class="n">exchange_name</span><span class="o">=</span><span class="s1">&#39;bitfinex&#39;</span><span class="p">,</span>
<span class="n">algo_namespace</span><span class="o">=</span><span class="n">NAMESPACE</span><span class="p">,</span>
<span class="n">base_currency</span><span class="o">=</span><span class="s1">&#39;usd&#39;</span><span class="p">,</span>
<span class="n">simulate_orders</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
<span class="n">live</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
<span class="p">)</span>
<span class="c1"># run_algorithm(</span>
<span class="c1"># capital_base=1000,</span>
<span class="c1"># data_frequency=&#39;minute&#39;,</span>
<span class="c1"># initialize=initialize,</span>
<span class="c1"># handle_data=handle_data,</span>
<span class="c1"># analyze=analyze,</span>
<span class="c1"># exchange_name=&#39;bitfinex&#39;,</span>
<span class="c1"># algo_namespace=NAMESPACE,</span>
<span class="c1"># base_currency=&#39;usd&#39;,</span>
<span class="c1"># start=pd.to_datetime(&#39;2017-9-22&#39;, utc=True),</span>
<span class="c1"># end=pd.to_datetime(&#39;2017-9-23&#39;, utc=True),</span>
<span class="c1"># )</span>
</pre></div>
</div>
<img alt="https://s3.amazonaws.com/enigmaco-docs/github.io/tutorial_dual_moving_average.png" src="https://s3.amazonaws.com/enigmaco-docs/github.io/tutorial_dual_moving_average.png" />
</div>
<div class="section" id="mean-reversion-algorithm">
<span id="mean-reversion"></span><h2>Mean Reversion Algorithm<a class="headerlink" href="#mean-reversion-algorithm" title="Permalink to this headline"></a></h2>
<p>This algorithm is based on a simple momentum strategy. When the cryptoasset goes
up quickly, were going to buy; when it goes down quickly, were going to sell.
Hopefully, well ride the waves.</p>
<p>We are choosing to backtest this trading algorithm with the <code class="docutils literal"><span class="pre">neo_usd</span></code> currency
pairon the <code class="docutils literal"><span class="pre">Bitfinex</span></code> exchange. Thus, first ingest the historical pricing data
that we need, with minute resolution:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>catalyst ingest-exchange -x bitfinex -f minute -i neo_usd
</pre></div>
</div>
<p>To run this algorithm, we are opting for the Python interpreter, instead of the
command line (CLI). All of the parameters for the simulation are specified in
lines 218-245, so in order to run the algorithm we just type:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>python mean_reversion_simple.py
</pre></div>
</div>
<p>Source code: <a class="reference external" href="https://github.com/enigmampc/catalyst/blob/master/catalyst/examples/mean_reversion_simple.py">examples/mean_reversion_simple.py</a></p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="c1"># For this example, we&#39;re going to write a simple momentum script. When the</span>
<span class="c1"># stock goes up quickly, we&#39;re going to buy; when it goes down quickly, we&#39;re</span>
<span class="c1"># going to sell. Hopefully we&#39;ll ride the waves.</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">tempfile</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="kn">as</span> <span class="nn">np</span>
<span class="kn">import</span> <span class="nn">pandas</span> <span class="kn">as</span> <span class="nn">pd</span>
<span class="kn">import</span> <span class="nn">talib</span>
<span class="kn">from</span> <span class="nn">logbook</span> <span class="kn">import</span> <span class="n">Logger</span>
<span class="kn">from</span> <span class="nn">catalyst</span> <span class="kn">import</span> <span class="n">run_algorithm</span>
<span class="kn">from</span> <span class="nn">catalyst.api</span> <span class="kn">import</span> <span class="n">symbol</span><span class="p">,</span> <span class="n">record</span><span class="p">,</span> <span class="n">order_target_percent</span><span class="p">,</span> <span class="n">get_open_orders</span>
<span class="kn">from</span> <span class="nn">catalyst.exchange.utils.stats_utils</span> <span class="kn">import</span> <span class="n">extract_transactions</span>
<span class="c1"># We give a name to the algorithm which Catalyst will use to persist its state.</span>
<span class="c1"># In this example, Catalyst will create the `.catalyst/data/live_algos`</span>
<span class="c1"># directory. If we stop and start the algorithm, Catalyst will resume its</span>
<span class="c1"># state using the files included in the folder.</span>
<span class="kn">from</span> <span class="nn">catalyst.utils.paths</span> <span class="kn">import</span> <span class="n">ensure_directory</span>
<span class="n">NAMESPACE</span> <span class="o">=</span> <span class="s1">&#39;mean_reversion_simple&#39;</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">Logger</span><span class="p">(</span><span class="n">NAMESPACE</span><span class="p">)</span>
<span class="c1"># To run an algorithm in Catalyst, you need two functions: initialize and</span>
<span class="c1"># handle_data.</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">context</span><span class="p">):</span>
<span class="c1"># This initialize function sets any data or variables that you&#39;ll use in</span>
<span class="c1"># your algorithm. For instance, you&#39;ll want to define the trading pair (or</span>
<span class="c1"># trading pairs) you want to backtest. You&#39;ll also want to define any</span>
<span class="c1"># parameters or values you&#39;re going to use.</span>
<span class="c1"># In our example, we&#39;re looking at Neo in Ether.</span>
<span class="n">context</span><span class="o">.</span><span class="n">market</span> <span class="o">=</span> <span class="n">symbol</span><span class="p">(</span><span class="s1">&#39;bnb_eth&#39;</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">base_price</span> <span class="o">=</span> <span class="bp">None</span>
<span class="n">context</span><span class="o">.</span><span class="n">current_day</span> <span class="o">=</span> <span class="bp">None</span>
<span class="n">context</span><span class="o">.</span><span class="n">RSI_OVERSOLD</span> <span class="o">=</span> <span class="mi">60</span>
<span class="n">context</span><span class="o">.</span><span class="n">RSI_OVERBOUGHT</span> <span class="o">=</span> <span class="mi">70</span>
<span class="n">context</span><span class="o">.</span><span class="n">CANDLE_SIZE</span> <span class="o">=</span> <span class="s1">&#39;15T&#39;</span>
<span class="n">context</span><span class="o">.</span><span class="n">start_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
<span class="n">context</span><span class="o">.</span><span class="n">set_commission</span><span class="p">(</span><span class="n">maker</span><span class="o">=</span><span class="mf">0.001</span><span class="p">,</span> <span class="n">taker</span><span class="o">=</span><span class="mf">0.002</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">set_slippage</span><span class="p">(</span><span class="n">spread</span><span class="o">=</span><span class="mf">0.001</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">handle_data</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="c1"># This handle_data function is where the real work is done. Our data is</span>
<span class="c1"># minute-level tick data, and each minute is called a frame. This function</span>
<span class="c1"># runs on each frame of the data.</span>
<span class="c1"># We flag the first period of each day.</span>
<span class="c1"># Since cryptocurrencies trade 24/7 the `before_trading_starts` handle</span>
<span class="c1"># would only execute once. This method works with minute and daily</span>
<span class="c1"># frequencies.</span>
<span class="n">today</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">current_dt</span><span class="o">.</span><span class="n">floor</span><span class="p">(</span><span class="s1">&#39;1D&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">today</span> <span class="o">!=</span> <span class="n">context</span><span class="o">.</span><span class="n">current_day</span><span class="p">:</span>
<span class="n">context</span><span class="o">.</span><span class="n">traded_today</span> <span class="o">=</span> <span class="bp">False</span>
<span class="n">context</span><span class="o">.</span><span class="n">current_day</span> <span class="o">=</span> <span class="n">today</span>
<span class="c1"># We&#39;re computing the volume-weighted-average-price of the security</span>
<span class="c1"># defined above, in the context.market variable. For this example, we&#39;re</span>
<span class="c1"># using three bars on the 15 min bars.</span>
<span class="c1"># The frequency attribute determine the bar size. We use this convention</span>
<span class="c1"># for the frequency alias:</span>
<span class="c1"># http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases</span>
<span class="n">prices</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">history</span><span class="p">(</span>
<span class="n">context</span><span class="o">.</span><span class="n">market</span><span class="p">,</span>
<span class="n">fields</span><span class="o">=</span><span class="s1">&#39;close&#39;</span><span class="p">,</span>
<span class="n">bar_count</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span>
<span class="n">frequency</span><span class="o">=</span><span class="n">context</span><span class="o">.</span><span class="n">CANDLE_SIZE</span>
<span class="p">)</span>
<span class="c1"># Ta-lib calculates various technical indicator based on price and</span>
<span class="c1"># volume arrays.</span>
<span class="c1"># In this example, we are comp</span>
<span class="n">rsi</span> <span class="o">=</span> <span class="n">talib</span><span class="o">.</span><span class="n">RSI</span><span class="p">(</span><span class="n">prices</span><span class="o">.</span><span class="n">values</span><span class="p">,</span> <span class="n">timeperiod</span><span class="o">=</span><span class="mi">14</span><span class="p">)</span>
<span class="c1"># We need a variable for the current price of the security to compare to</span>
<span class="c1"># the average. Since we are requesting two fields, data.current()</span>
<span class="c1"># returns a DataFrame with</span>
<span class="n">current</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">current</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">market</span><span class="p">,</span> <span class="n">fields</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;close&#39;</span><span class="p">,</span> <span class="s1">&#39;volume&#39;</span><span class="p">])</span>
<span class="n">price</span> <span class="o">=</span> <span class="n">current</span><span class="p">[</span><span class="s1">&#39;close&#39;</span><span class="p">]</span>
<span class="c1"># If base_price is not set, we use the current value. This is the</span>
<span class="c1"># price at the first bar which we reference to calculate price_change.</span>
<span class="k">if</span> <span class="n">context</span><span class="o">.</span><span class="n">base_price</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">context</span><span class="o">.</span><span class="n">base_price</span> <span class="o">=</span> <span class="n">price</span>
<span class="n">price_change</span> <span class="o">=</span> <span class="p">(</span><span class="n">price</span> <span class="o">-</span> <span class="n">context</span><span class="o">.</span><span class="n">base_price</span><span class="p">)</span> <span class="o">/</span> <span class="n">context</span><span class="o">.</span><span class="n">base_price</span>
<span class="n">cash</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">portfolio</span><span class="o">.</span><span class="n">cash</span>
<span class="c1"># Now that we&#39;ve collected all current data for this frame, we use</span>
<span class="c1"># the record() method to save it. This data will be available as</span>
<span class="c1"># a parameter of the analyze() function for further analysis.</span>
<span class="n">record</span><span class="p">(</span>
<span class="n">volume</span><span class="o">=</span><span class="n">current</span><span class="p">[</span><span class="s1">&#39;volume&#39;</span><span class="p">],</span>
<span class="n">price</span><span class="o">=</span><span class="n">price</span><span class="p">,</span>
<span class="n">price_change</span><span class="o">=</span><span class="n">price_change</span><span class="p">,</span>
<span class="n">rsi</span><span class="o">=</span><span class="n">rsi</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span>
<span class="n">cash</span><span class="o">=</span><span class="n">cash</span>
<span class="p">)</span>
<span class="c1"># We are trying to avoid over-trading by limiting our trades to</span>
<span class="c1"># one per day.</span>
<span class="k">if</span> <span class="n">context</span><span class="o">.</span><span class="n">traded_today</span><span class="p">:</span>
<span class="k">return</span>
<span class="c1"># TODO: retest with open orders</span>
<span class="c1"># Since we are using limit orders, some orders may not execute immediately</span>
<span class="c1"># we wait until all orders are executed before considering more trades.</span>
<span class="n">orders</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">blotter</span><span class="o">.</span><span class="n">open_orders</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">orders</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;exiting because orders are open: {}&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">orders</span><span class="p">))</span>
<span class="k">return</span>
<span class="c1"># Exit if we cannot trade</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">data</span><span class="o">.</span><span class="n">can_trade</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">market</span><span class="p">):</span>
<span class="k">return</span>
<span class="c1"># Another powerful built-in feature of the Catalyst backtester is the</span>
<span class="c1"># portfolio object. The portfolio object tracks your positions, cash,</span>
<span class="c1"># cost basis of specific holdings, and more. In this line, we calculate</span>
<span class="c1"># how long or short our position is at this minute.</span>
<span class="n">pos_amount</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">portfolio</span><span class="o">.</span><span class="n">positions</span><span class="p">[</span><span class="n">context</span><span class="o">.</span><span class="n">market</span><span class="p">]</span><span class="o">.</span><span class="n">amount</span>
<span class="k">if</span> <span class="n">rsi</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="n">context</span><span class="o">.</span><span class="n">RSI_OVERSOLD</span> <span class="ow">and</span> <span class="n">pos_amount</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
<span class="s1">&#39;{}: buying - price: {}, rsi: {}&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">data</span><span class="o">.</span><span class="n">current_dt</span><span class="p">,</span> <span class="n">price</span><span class="p">,</span> <span class="n">rsi</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="c1"># Set a style for limit orders,</span>
<span class="n">limit_price</span> <span class="o">=</span> <span class="n">price</span> <span class="o">*</span> <span class="mf">1.005</span>
<span class="n">order_target_percent</span><span class="p">(</span>
<span class="n">context</span><span class="o">.</span><span class="n">market</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">limit_price</span><span class="o">=</span><span class="n">limit_price</span>
<span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">traded_today</span> <span class="o">=</span> <span class="bp">True</span>
<span class="k">elif</span> <span class="n">rsi</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="n">context</span><span class="o">.</span><span class="n">RSI_OVERBOUGHT</span> <span class="ow">and</span> <span class="n">pos_amount</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
<span class="s1">&#39;{}: selling - price: {}, rsi: {}&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">data</span><span class="o">.</span><span class="n">current_dt</span><span class="p">,</span> <span class="n">price</span><span class="p">,</span> <span class="n">rsi</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="n">limit_price</span> <span class="o">=</span> <span class="n">price</span> <span class="o">*</span> <span class="mf">0.995</span>
<span class="n">order_target_percent</span><span class="p">(</span>
<span class="n">context</span><span class="o">.</span><span class="n">market</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">limit_price</span><span class="o">=</span><span class="n">limit_price</span>
<span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">traded_today</span> <span class="o">=</span> <span class="bp">True</span>
<span class="k">def</span> <span class="nf">analyze</span><span class="p">(</span><span class="n">context</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">perf</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="n">end</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;elapsed time: {}&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">end</span> <span class="o">-</span> <span class="n">context</span><span class="o">.</span><span class="n">start_time</span><span class="p">))</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="kn">as</span> <span class="nn">plt</span>
<span class="c1"># The base currency of the algo exchange</span>
<span class="n">base_currency</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">exchanges</span><span class="o">.</span><span class="n">values</span><span class="p">())[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">base_currency</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span>
<span class="c1"># Plot the portfolio value over time.</span>
<span class="n">ax1</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">611</span><span class="p">)</span>
<span class="n">perf</span><span class="o">.</span><span class="n">loc</span><span class="p">[:,</span> <span class="s1">&#39;portfolio_value&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ax</span><span class="o">=</span><span class="n">ax1</span><span class="p">)</span>
<span class="n">ax1</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">&#39;Portfolio</span><span class="se">\n</span><span class="s1">Value</span><span class="se">\n</span><span class="s1">({})&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">base_currency</span><span class="p">))</span>
<span class="c1"># Plot the price increase or decrease over time.</span>
<span class="n">ax2</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">612</span><span class="p">,</span> <span class="n">sharex</span><span class="o">=</span><span class="n">ax1</span><span class="p">)</span>
<span class="n">perf</span><span class="o">.</span><span class="n">loc</span><span class="p">[:,</span> <span class="s1">&#39;price&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ax</span><span class="o">=</span><span class="n">ax2</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s1">&#39;Price&#39;</span><span class="p">)</span>
<span class="n">ax2</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">&#39;{asset}</span><span class="se">\n</span><span class="s1">({base})&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">asset</span><span class="o">=</span><span class="n">context</span><span class="o">.</span><span class="n">market</span><span class="o">.</span><span class="n">symbol</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="n">base_currency</span>
<span class="p">))</span>
<span class="n">transaction_df</span> <span class="o">=</span> <span class="n">extract_transactions</span><span class="p">(</span><span class="n">perf</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">transaction_df</span><span class="o">.</span><span class="n">empty</span><span class="p">:</span>
<span class="n">buy_df</span> <span class="o">=</span> <span class="n">transaction_df</span><span class="p">[</span><span class="n">transaction_df</span><span class="p">[</span><span class="s1">&#39;amount&#39;</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">]</span>
<span class="n">sell_df</span> <span class="o">=</span> <span class="n">transaction_df</span><span class="p">[</span><span class="n">transaction_df</span><span class="p">[</span><span class="s1">&#39;amount&#39;</span><span class="p">]</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">]</span>
<span class="n">ax2</span><span class="o">.</span><span class="n">scatter</span><span class="p">(</span>
<span class="n">buy_df</span><span class="o">.</span><span class="n">index</span><span class="o">.</span><span class="n">to_pydatetime</span><span class="p">(),</span>
<span class="n">perf</span><span class="o">.</span><span class="n">loc</span><span class="p">[</span><span class="n">buy_df</span><span class="o">.</span><span class="n">index</span><span class="o">.</span><span class="n">floor</span><span class="p">(</span><span class="s1">&#39;1 min&#39;</span><span class="p">),</span> <span class="s1">&#39;price&#39;</span><span class="p">],</span>
<span class="n">marker</span><span class="o">=</span><span class="s1">&#39;^&#39;</span><span class="p">,</span>
<span class="n">s</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span>
<span class="n">c</span><span class="o">=</span><span class="s1">&#39;green&#39;</span><span class="p">,</span>
<span class="n">label</span><span class="o">=</span><span class="s1">&#39;&#39;</span>
<span class="p">)</span>
<span class="n">ax2</span><span class="o">.</span><span class="n">scatter</span><span class="p">(</span>
<span class="n">sell_df</span><span class="o">.</span><span class="n">index</span><span class="o">.</span><span class="n">to_pydatetime</span><span class="p">(),</span>
<span class="n">perf</span><span class="o">.</span><span class="n">loc</span><span class="p">[</span><span class="n">sell_df</span><span class="o">.</span><span class="n">index</span><span class="o">.</span><span class="n">floor</span><span class="p">(</span><span class="s1">&#39;1 min&#39;</span><span class="p">),</span> <span class="s1">&#39;price&#39;</span><span class="p">],</span>
<span class="n">marker</span><span class="o">=</span><span class="s1">&#39;v&#39;</span><span class="p">,</span>
<span class="n">s</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span>
<span class="n">c</span><span class="o">=</span><span class="s1">&#39;red&#39;</span><span class="p">,</span>
<span class="n">label</span><span class="o">=</span><span class="s1">&#39;&#39;</span>
<span class="p">)</span>
<span class="n">ax4</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">613</span><span class="p">,</span> <span class="n">sharex</span><span class="o">=</span><span class="n">ax1</span><span class="p">)</span>
<span class="n">perf</span><span class="o">.</span><span class="n">loc</span><span class="p">[:,</span> <span class="s1">&#39;cash&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span>
<span class="n">ax</span><span class="o">=</span><span class="n">ax4</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s1">&#39;Base Currency ({})&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">base_currency</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">ax4</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">&#39;Cash</span><span class="se">\n</span><span class="s1">({})&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">base_currency</span><span class="p">))</span>
<span class="n">perf</span><span class="p">[</span><span class="s1">&#39;algorithm&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">perf</span><span class="o">.</span><span class="n">loc</span><span class="p">[:,</span> <span class="s1">&#39;algorithm_period_return&#39;</span><span class="p">]</span>
<span class="n">ax5</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">614</span><span class="p">,</span> <span class="n">sharex</span><span class="o">=</span><span class="n">ax1</span><span class="p">)</span>
<span class="n">perf</span><span class="o">.</span><span class="n">loc</span><span class="p">[:,</span> <span class="p">[</span><span class="s1">&#39;algorithm&#39;</span><span class="p">,</span> <span class="s1">&#39;price_change&#39;</span><span class="p">]]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ax</span><span class="o">=</span><span class="n">ax5</span><span class="p">)</span>
<span class="n">ax5</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">&#39;Percent</span><span class="se">\n</span><span class="s1">Change&#39;</span><span class="p">)</span>
<span class="n">ax6</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">615</span><span class="p">,</span> <span class="n">sharex</span><span class="o">=</span><span class="n">ax1</span><span class="p">)</span>
<span class="n">perf</span><span class="o">.</span><span class="n">loc</span><span class="p">[:,</span> <span class="s1">&#39;rsi&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ax</span><span class="o">=</span><span class="n">ax6</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s1">&#39;RSI&#39;</span><span class="p">)</span>
<span class="n">ax6</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">&#39;RSI&#39;</span><span class="p">)</span>
<span class="n">ax6</span><span class="o">.</span><span class="n">axhline</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">RSI_OVERBOUGHT</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">&#39;darkgoldenrod&#39;</span><span class="p">)</span>
<span class="n">ax6</span><span class="o">.</span><span class="n">axhline</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">RSI_OVERSOLD</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">&#39;darkgoldenrod&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">transaction_df</span><span class="o">.</span><span class="n">empty</span><span class="p">:</span>
<span class="n">ax6</span><span class="o">.</span><span class="n">scatter</span><span class="p">(</span>
<span class="n">buy_df</span><span class="o">.</span><span class="n">index</span><span class="o">.</span><span class="n">to_pydatetime</span><span class="p">(),</span>
<span class="n">perf</span><span class="o">.</span><span class="n">loc</span><span class="p">[</span><span class="n">buy_df</span><span class="o">.</span><span class="n">index</span><span class="o">.</span><span class="n">floor</span><span class="p">(</span><span class="s1">&#39;1 min&#39;</span><span class="p">),</span> <span class="s1">&#39;rsi&#39;</span><span class="p">],</span>
<span class="n">marker</span><span class="o">=</span><span class="s1">&#39;^&#39;</span><span class="p">,</span>
<span class="n">s</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span>
<span class="n">c</span><span class="o">=</span><span class="s1">&#39;green&#39;</span><span class="p">,</span>
<span class="n">label</span><span class="o">=</span><span class="s1">&#39;&#39;</span>
<span class="p">)</span>
<span class="n">ax6</span><span class="o">.</span><span class="n">scatter</span><span class="p">(</span>
<span class="n">sell_df</span><span class="o">.</span><span class="n">index</span><span class="o">.</span><span class="n">to_pydatetime</span><span class="p">(),</span>
<span class="n">perf</span><span class="o">.</span><span class="n">loc</span><span class="p">[</span><span class="n">sell_df</span><span class="o">.</span><span class="n">index</span><span class="o">.</span><span class="n">floor</span><span class="p">(</span><span class="s1">&#39;1 min&#39;</span><span class="p">),</span> <span class="s1">&#39;rsi&#39;</span><span class="p">],</span>
<span class="n">marker</span><span class="o">=</span><span class="s1">&#39;v&#39;</span><span class="p">,</span>
<span class="n">s</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span>
<span class="n">c</span><span class="o">=</span><span class="s1">&#39;red&#39;</span><span class="p">,</span>
<span class="n">label</span><span class="o">=</span><span class="s1">&#39;&#39;</span>
<span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">legend</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="n">start</span><span class="p">,</span> <span class="n">end</span> <span class="o">=</span> <span class="n">ax6</span><span class="o">.</span><span class="n">get_ylim</span><span class="p">()</span>
<span class="n">ax6</span><span class="o">.</span><span class="n">yaxis</span><span class="o">.</span><span class="n">set_ticks</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">end</span><span class="p">,</span> <span class="n">end</span> <span class="o">/</span> <span class="mi">5</span><span class="p">))</span>
<span class="c1"># Show the plot.</span>
<span class="n">plt</span><span class="o">.</span><span class="n">gcf</span><span class="p">()</span><span class="o">.</span><span class="n">set_size_inches</span><span class="p">(</span><span class="mi">18</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">pass</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
<span class="c1"># The execution mode: backtest or live</span>
<span class="n">live</span> <span class="o">=</span> <span class="bp">True</span>
<span class="k">if</span> <span class="n">live</span><span class="p">:</span>
<span class="n">run_algorithm</span><span class="p">(</span>
<span class="n">capital_base</span><span class="o">=</span><span class="mf">0.1</span><span class="p">,</span>
<span class="n">initialize</span><span class="o">=</span><span class="n">initialize</span><span class="p">,</span>
<span class="n">handle_data</span><span class="o">=</span><span class="n">handle_data</span><span class="p">,</span>
<span class="n">analyze</span><span class="o">=</span><span class="n">analyze</span><span class="p">,</span>
<span class="n">exchange_name</span><span class="o">=</span><span class="s1">&#39;binance&#39;</span><span class="p">,</span>
<span class="n">live</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
<span class="n">algo_namespace</span><span class="o">=</span><span class="n">NAMESPACE</span><span class="p">,</span>
<span class="n">base_currency</span><span class="o">=</span><span class="s1">&#39;eth&#39;</span><span class="p">,</span>
<span class="n">live_graph</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span>
<span class="n">simulate_orders</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span>
<span class="n">stats_output</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="c1"># auth_aliases=dict(poloniex=&#39;auth2&#39;)</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">folder</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
<span class="n">tempfile</span><span class="o">.</span><span class="n">gettempdir</span><span class="p">(),</span> <span class="s1">&#39;catalyst&#39;</span><span class="p">,</span> <span class="n">NAMESPACE</span>
<span class="p">)</span>
<span class="n">ensure_directory</span><span class="p">(</span><span class="n">folder</span><span class="p">)</span>
<span class="n">timestr</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s1">&#39;%Y%m</span><span class="si">%d</span><span class="s1">-%H%M%S&#39;</span><span class="p">)</span>
<span class="n">out</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">folder</span><span class="p">,</span> <span class="s1">&#39;{}.p&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">timestr</span><span class="p">))</span>
<span class="c1"># catalyst run -f catalyst/examples/mean_reversion_simple.py \</span>
<span class="c1"># -x bitfinex -s 2017-10-1 -e 2017-11-10 -c usdt -n mean-reversion \</span>
<span class="c1"># --data-frequency minute --capital-base 10000</span>
<span class="n">run_algorithm</span><span class="p">(</span>
<span class="n">capital_base</span><span class="o">=</span><span class="mf">0.035</span><span class="p">,</span>
<span class="n">data_frequency</span><span class="o">=</span><span class="s1">&#39;minute&#39;</span><span class="p">,</span>
<span class="n">initialize</span><span class="o">=</span><span class="n">initialize</span><span class="p">,</span>
<span class="n">handle_data</span><span class="o">=</span><span class="n">handle_data</span><span class="p">,</span>
<span class="n">analyze</span><span class="o">=</span><span class="n">analyze</span><span class="p">,</span>
<span class="n">exchange_name</span><span class="o">=</span><span class="s1">&#39;bitfinex&#39;</span><span class="p">,</span>
<span class="n">algo_namespace</span><span class="o">=</span><span class="n">NAMESPACE</span><span class="p">,</span>
<span class="n">base_currency</span><span class="o">=</span><span class="s1">&#39;btc&#39;</span><span class="p">,</span>
<span class="n">start</span><span class="o">=</span><span class="n">pd</span><span class="o">.</span><span class="n">to_datetime</span><span class="p">(</span><span class="s1">&#39;2017-10-01&#39;</span><span class="p">,</span> <span class="n">utc</span><span class="o">=</span><span class="bp">True</span><span class="p">),</span>
<span class="n">end</span><span class="o">=</span><span class="n">pd</span><span class="o">.</span><span class="n">to_datetime</span><span class="p">(</span><span class="s1">&#39;2017-11-10&#39;</span><span class="p">,</span> <span class="n">utc</span><span class="o">=</span><span class="bp">True</span><span class="p">),</span>
<span class="n">output</span><span class="o">=</span><span class="n">out</span>
<span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">&#39;saved perf stats: {}&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">out</span><span class="p">))</span>
</pre></div>
</div>
<img alt="https://s3.amazonaws.com/enigmaco-docs/github.io/example_mean_reversion_simple.png" src="https://s3.amazonaws.com/enigmaco-docs/github.io/example_mean_reversion_simple.png" />
<p>Notice the difference in performance between the charts above and those seen on
<a class="reference external" href="https://youtu.be/JOBRwst9jUY">this video tutorial</a> at
minute 8:10. The buy and sell orders are triggered at the same exact times, but
the differences result from a more realistic slippage model
implemented after the video was recorded, which executes the orders at slighlty
different prices, but resulting in significant changes in performance of our
strategy.</p>
</div>
<div class="section" id="simple-universe">
<span id="id1"></span><h2>Simple Universe<a class="headerlink" href="#simple-universe" title="Permalink to this headline"></a></h2>
<p>This example aims to provide an easy way for users to learn how to
collect data from any given exchange and select a subset of the available
currency pairs for trading. You simply need to specify the exchange and
the market (base_currency) that you want to focus on. You will then see
how to create a universe of assets, and filter it based the market you
desire.</p>
<p>The example prints out the closing price of all the pairs for a given
market in a given exchange every 30 minutes. The example also contains
the OHLCV data with minute-resolution for the past seven days which
could be used to create indicators. Use this code as the backbone to
create your own trading strategy.</p>
<p>The lookback_date variable is used to ensure data for a coin existed on
the lookback period specified.</p>
<p>To run, execute the following two commands in a terminal (inside catalyst
environment). The first one retrieves all the pricing data needed for this
script to run (only needs to be run once), and the second one executes this
script with the parameters specified in the run_algorithm() call at the end
of the file:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>catalyst ingest-exchange -x bitfinex -f minute
</pre></div>
</div>
<p>Source code: <a class="reference external" href="https://github.com/enigmampc/catalyst/blob/master/catalyst/examples/simple_universe.py">examples/simple_universe.py</a></p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Requires Catalyst version 0.3.0 or above</span>
<span class="sd">Tested on Catalyst version 0.3.3</span>
<span class="sd">This example aims to provide an easy way for users to learn how to</span>
<span class="sd">collect data from any given exchange and select a subset of the available</span>
<span class="sd">currency pairs for trading. You simply need to specify the exchange and</span>
<span class="sd">the market (base_currency) that you want to focus on. You will then see</span>
<span class="sd">how to create a universe of assets, and filter it based the market you</span>
<span class="sd">desire.</span>
<span class="sd">The example prints out the closing price of all the pairs for a given</span>
<span class="sd">market in a given exchange every 30 minutes. The example also contains</span>
<span class="sd">the OHLCV data with minute-resolution for the past seven days which</span>
<span class="sd">could be used to create indicators. Use this code as the backbone to</span>
<span class="sd">create your own trading strategy.</span>
<span class="sd">The lookback_date variable is used to ensure data for a coin existed on</span>
<span class="sd">the lookback period specified.</span>
<span class="sd">To run, execute the following two commands in a terminal (inside catalyst</span>
<span class="sd">environment). The first one retrieves all the pricing data needed for this</span>
<span class="sd">script to run (only needs to be run once), and the second one executes this</span>
<span class="sd">script with the parameters specified in the run_algorithm() call at the end</span>
<span class="sd">of the file:</span>
<span class="sd">catalyst ingest-exchange -x bitfinex -f minute</span>
<span class="sd">python simple_universe.py</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">timedelta</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="kn">as</span> <span class="nn">np</span>
<span class="kn">import</span> <span class="nn">pandas</span> <span class="kn">as</span> <span class="nn">pd</span>
<span class="kn">from</span> <span class="nn">catalyst</span> <span class="kn">import</span> <span class="n">run_algorithm</span>
<span class="kn">from</span> <span class="nn">catalyst.api</span> <span class="kn">import</span> <span class="p">(</span><span class="n">symbols</span><span class="p">,</span> <span class="p">)</span>
<span class="kn">from</span> <span class="nn">catalyst.exchange.utils.exchange_utils</span> <span class="kn">import</span> <span class="n">get_exchange_symbols</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">context</span><span class="p">):</span>
<span class="n">context</span><span class="o">.</span><span class="n">i</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span> <span class="c1"># minute counter</span>
<span class="n">context</span><span class="o">.</span><span class="n">exchange</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">exchanges</span><span class="o">.</span><span class="n">values</span><span class="p">())[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="n">context</span><span class="o">.</span><span class="n">base_currency</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">exchanges</span><span class="o">.</span><span class="n">values</span><span class="p">())[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">base_currency</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">handle_data</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="n">context</span><span class="o">.</span><span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">lookback_days</span> <span class="o">=</span> <span class="mi">7</span> <span class="c1"># 7 days</span>
<span class="c1"># current date &amp; time in each iteration formatted into a string</span>
<span class="n">now</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">current_dt</span>
<span class="n">date</span><span class="p">,</span> <span class="n">time</span> <span class="o">=</span> <span class="n">now</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s1">&#39;%Y-%m-</span><span class="si">%d</span><span class="s1"> %H:%M:%S&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="n">lookback_date</span> <span class="o">=</span> <span class="n">now</span> <span class="o">-</span> <span class="n">timedelta</span><span class="p">(</span><span class="n">days</span><span class="o">=</span><span class="n">lookback_days</span><span class="p">)</span>
<span class="c1"># keep only the date as a string, discard the time</span>
<span class="n">lookback_date</span> <span class="o">=</span> <span class="n">lookback_date</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s1">&#39;%Y-%m-</span><span class="si">%d</span><span class="s1"> %H:%M:%S&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">one_day_in_minutes</span> <span class="o">=</span> <span class="mi">1440</span> <span class="c1"># 60 * 24 assumes data_frequency=&#39;minute&#39;</span>
<span class="c1"># update universe everyday at midnight</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">context</span><span class="o">.</span><span class="n">i</span> <span class="o">%</span> <span class="n">one_day_in_minutes</span><span class="p">:</span>
<span class="n">context</span><span class="o">.</span><span class="n">universe</span> <span class="o">=</span> <span class="n">universe</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">lookback_date</span><span class="p">,</span> <span class="n">date</span><span class="p">)</span>
<span class="c1"># get data every 30 minutes</span>
<span class="n">minutes</span> <span class="o">=</span> <span class="mi">30</span>
<span class="c1"># get lookback_days of history data: that is &#39;lookback&#39; number of bins</span>
<span class="n">lookback</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">one_day_in_minutes</span> <span class="o">/</span> <span class="n">minutes</span> <span class="o">*</span> <span class="n">lookback_days</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">context</span><span class="o">.</span><span class="n">i</span> <span class="o">%</span> <span class="n">minutes</span> <span class="ow">and</span> <span class="n">context</span><span class="o">.</span><span class="n">universe</span><span class="p">:</span>
<span class="c1"># we iterate for every pair in the current universe</span>
<span class="k">for</span> <span class="n">coin</span> <span class="ow">in</span> <span class="n">context</span><span class="o">.</span><span class="n">coins</span><span class="p">:</span>
<span class="n">pair</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">coin</span><span class="o">.</span><span class="n">symbol</span><span class="p">)</span>
<span class="c1"># Get 30 minute interval OHLCV data. This is the standard data</span>
<span class="c1"># required for candlestick or indicators/signals. Return Pandas</span>
<span class="c1"># DataFrames. 30T means 30-minute re-sampling of one minute data.</span>
<span class="c1"># Adjust it to your desired time interval as needed.</span>
<span class="n">opened</span> <span class="o">=</span> <span class="n">fill</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">history</span><span class="p">(</span><span class="n">coin</span><span class="p">,</span>
<span class="s1">&#39;open&#39;</span><span class="p">,</span>
<span class="n">bar_count</span><span class="o">=</span><span class="n">lookback</span><span class="p">,</span>
<span class="n">frequency</span><span class="o">=</span><span class="s1">&#39;30T&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">values</span>
<span class="n">high</span> <span class="o">=</span> <span class="n">fill</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">history</span><span class="p">(</span><span class="n">coin</span><span class="p">,</span>
<span class="s1">&#39;high&#39;</span><span class="p">,</span>
<span class="n">bar_count</span><span class="o">=</span><span class="n">lookback</span><span class="p">,</span>
<span class="n">frequency</span><span class="o">=</span><span class="s1">&#39;30T&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">values</span>
<span class="n">low</span> <span class="o">=</span> <span class="n">fill</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">history</span><span class="p">(</span><span class="n">coin</span><span class="p">,</span>
<span class="s1">&#39;low&#39;</span><span class="p">,</span>
<span class="n">bar_count</span><span class="o">=</span><span class="n">lookback</span><span class="p">,</span>
<span class="n">frequency</span><span class="o">=</span><span class="s1">&#39;30T&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">values</span>
<span class="n">close</span> <span class="o">=</span> <span class="n">fill</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">history</span><span class="p">(</span><span class="n">coin</span><span class="p">,</span>
<span class="s1">&#39;price&#39;</span><span class="p">,</span>
<span class="n">bar_count</span><span class="o">=</span><span class="n">lookback</span><span class="p">,</span>
<span class="n">frequency</span><span class="o">=</span><span class="s1">&#39;30T&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">values</span>
<span class="n">volume</span> <span class="o">=</span> <span class="n">fill</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">history</span><span class="p">(</span><span class="n">coin</span><span class="p">,</span>
<span class="s1">&#39;volume&#39;</span><span class="p">,</span>
<span class="n">bar_count</span><span class="o">=</span><span class="n">lookback</span><span class="p">,</span>
<span class="n">frequency</span><span class="o">=</span><span class="s1">&#39;30T&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">values</span>
<span class="c1"># close[-1] is the last value in the set, which is the equivalent</span>
<span class="c1"># to current price (as in the most recent value)</span>
<span class="c1"># displays the minute price for each pair every 30 minutes</span>
<span class="k">print</span><span class="p">(</span><span class="s1">&#39;{now}: {pair} -</span><span class="se">\t</span><span class="s1">O:{o},</span><span class="se">\t</span><span class="s1">H:{h},</span><span class="se">\t</span><span class="s1">L:{c},</span><span class="se">\t</span><span class="s1">C{c},&#39;</span>
<span class="s1">&#39;</span><span class="se">\t</span><span class="s1">V:{v}&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">now</span><span class="o">=</span><span class="n">now</span><span class="p">,</span>
<span class="n">pair</span><span class="o">=</span><span class="n">pair</span><span class="p">,</span>
<span class="n">o</span><span class="o">=</span><span class="n">opened</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span>
<span class="n">h</span><span class="o">=</span><span class="n">high</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span>
<span class="n">l</span><span class="o">=</span><span class="n">low</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span>
<span class="n">c</span><span class="o">=</span><span class="n">close</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span>
<span class="n">v</span><span class="o">=</span><span class="n">volume</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span>
<span class="p">))</span>
<span class="c1"># -------------------------------------------------------------</span>
<span class="c1"># --------------- Insert Your Strategy Here -------------------</span>
<span class="c1"># -------------------------------------------------------------</span>
<span class="k">def</span> <span class="nf">analyze</span><span class="p">(</span><span class="n">context</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">results</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="k">pass</span>
<span class="c1"># Get the universe for a given exchange and a given base_currency market</span>
<span class="c1"># Example: Poloniex BTC Market</span>
<span class="k">def</span> <span class="nf">universe</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">lookback_date</span><span class="p">,</span> <span class="n">current_date</span><span class="p">):</span>
<span class="c1"># get all the pairs for the given exchange</span>
<span class="n">json_symbols</span> <span class="o">=</span> <span class="n">get_exchange_symbols</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">exchange</span><span class="p">)</span>
<span class="c1"># convert into a DataFrame for easier processing</span>
<span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="o">.</span><span class="n">from_dict</span><span class="p">(</span><span class="n">json_symbols</span><span class="p">)</span><span class="o">.</span><span class="n">transpose</span><span class="p">()</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="nb">str</span><span class="p">)</span>
<span class="n">df</span><span class="p">[</span><span class="s1">&#39;base_currency&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">apply</span><span class="p">(</span><span class="k">lambda</span> <span class="n">row</span><span class="p">:</span> <span class="n">row</span><span class="o">.</span><span class="n">symbol</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;_&#39;</span><span class="p">)[</span><span class="mi">1</span><span class="p">],</span>
<span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">df</span><span class="p">[</span><span class="s1">&#39;market_currency&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">apply</span><span class="p">(</span><span class="k">lambda</span> <span class="n">row</span><span class="p">:</span> <span class="n">row</span><span class="o">.</span><span class="n">symbol</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;_&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">],</span>
<span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="c1"># Filter all the pairs to get only the ones for a given base_currency</span>
<span class="n">df</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="n">df</span><span class="p">[</span><span class="s1">&#39;base_currency&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="n">context</span><span class="o">.</span><span class="n">base_currency</span><span class="p">]</span>
<span class="c1"># Filter all pairs to ensure that pair existed in the current date range</span>
<span class="n">df</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="n">df</span><span class="o">.</span><span class="n">start_date</span> <span class="o">&lt;</span> <span class="n">lookback_date</span><span class="p">]</span>
<span class="n">df</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="n">df</span><span class="o">.</span><span class="n">end_daily</span> <span class="o">&gt;=</span> <span class="n">current_date</span><span class="p">]</span>
<span class="n">context</span><span class="o">.</span><span class="n">coins</span> <span class="o">=</span> <span class="n">symbols</span><span class="p">(</span><span class="o">*</span><span class="n">df</span><span class="o">.</span><span class="n">symbol</span><span class="p">)</span> <span class="c1"># convert all the pairs to symbols</span>
<span class="k">return</span> <span class="n">df</span><span class="o">.</span><span class="n">symbol</span><span class="o">.</span><span class="n">tolist</span><span class="p">()</span>
<span class="c1"># Replace all NA, NAN or infinite values with its nearest value</span>
<span class="k">def</span> <span class="nf">fill</span><span class="p">(</span><span class="n">series</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">series</span><span class="p">,</span> <span class="n">pd</span><span class="o">.</span><span class="n">Series</span><span class="p">):</span>
<span class="k">return</span> <span class="n">series</span><span class="o">.</span><span class="n">replace</span><span class="p">([</span><span class="n">np</span><span class="o">.</span><span class="n">inf</span><span class="p">,</span> <span class="o">-</span><span class="n">np</span><span class="o">.</span><span class="n">inf</span><span class="p">],</span> <span class="n">np</span><span class="o">.</span><span class="n">nan</span><span class="p">)</span><span class="o">.</span><span class="n">ffill</span><span class="p">()</span><span class="o">.</span><span class="n">bfill</span><span class="p">()</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">series</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">ndarray</span><span class="p">):</span>
<span class="k">return</span> <span class="n">pd</span><span class="o">.</span><span class="n">Series</span><span class="p">(</span><span class="n">series</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span>
<span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">inf</span><span class="p">,</span> <span class="o">-</span><span class="n">np</span><span class="o">.</span><span class="n">inf</span><span class="p">],</span> <span class="n">np</span><span class="o">.</span><span class="n">nan</span>
<span class="p">)</span><span class="o">.</span><span class="n">ffill</span><span class="p">()</span><span class="o">.</span><span class="n">bfill</span><span class="p">()</span><span class="o">.</span><span class="n">values</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">series</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
<span class="n">start_date</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">to_datetime</span><span class="p">(</span><span class="s1">&#39;2017-11-10&#39;</span><span class="p">,</span> <span class="n">utc</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">end_date</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">to_datetime</span><span class="p">(</span><span class="s1">&#39;2017-11-13&#39;</span><span class="p">,</span> <span class="n">utc</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">performance</span> <span class="o">=</span> <span class="n">run_algorithm</span><span class="p">(</span><span class="n">start</span><span class="o">=</span><span class="n">start_date</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="n">end_date</span><span class="p">,</span>
<span class="n">capital_base</span><span class="o">=</span><span class="mf">100.0</span><span class="p">,</span> <span class="c1"># amount of base_currency</span>
<span class="n">initialize</span><span class="o">=</span><span class="n">initialize</span><span class="p">,</span>
<span class="n">handle_data</span><span class="o">=</span><span class="n">handle_data</span><span class="p">,</span>
<span class="n">analyze</span><span class="o">=</span><span class="n">analyze</span><span class="p">,</span>
<span class="n">exchange_name</span><span class="o">=</span><span class="s1">&#39;poloniex&#39;</span><span class="p">,</span>
<span class="n">data_frequency</span><span class="o">=</span><span class="s1">&#39;minute&#39;</span><span class="p">,</span>
<span class="n">base_currency</span><span class="o">=</span><span class="s1">&#39;btc&#39;</span><span class="p">,</span>
<span class="n">live</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span>
<span class="n">live_graph</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span>
<span class="n">algo_namespace</span><span class="o">=</span><span class="s1">&#39;simple_universe&#39;</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="portfolio-optimization">
<span id="id2"></span><h2>Portfolio Optimization<a class="headerlink" href="#portfolio-optimization" title="Permalink to this headline"></a></h2>
<p>Use this code to execute a portfolio optimization model. This strategy will
select the portfolio with the maximum Sharpe Ratio. The parameters are set to
use 180 days of historical data and rebalance every 30 days. This code was used
in writting the following article:
<a class="reference external" href="https://blog.enigma.co/markowitz-portfolio-optimization-for-cryptocurrencies-in-catalyst-b23c38652556">Markowitz Portfolio Optimization for Cryptocurrencies</a>.</p>
<p>Source code: <a class="reference external" href="https://github.com/enigmampc/catalyst/blob/master/catalyst/examples/portfolio_optimization.py">examples/simple_universe.py</a></p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="sd">&#39;&#39;&#39;Use this code to execute a portfolio optimization model. This code</span>
<span class="sd"> will select the portfolio with the maximum Sharpe Ratio. The parameters</span>
<span class="sd"> are set to use 180 days of historical data and rebalance every 30 days.</span>
<span class="sd"> This is the code used in the following article:</span>
<span class="sd"> https://blog.enigma.co/markowitz-portfolio-optimization-for-cryptocurrencies-in-catalyst-b23c38652556</span>
<span class="sd"> You can run this code using the Python interpreter:</span>
<span class="sd"> $ python portfolio_optimization.py</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">division</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">pytz</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="kn">as</span> <span class="nn">np</span>
<span class="kn">import</span> <span class="nn">pandas</span> <span class="kn">as</span> <span class="nn">pd</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="kn">as</span> <span class="nn">plt</span>
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
<span class="kn">from</span> <span class="nn">catalyst.api</span> <span class="kn">import</span> <span class="n">record</span><span class="p">,</span> <span class="n">symbols</span><span class="p">,</span> <span class="n">order_target_percent</span>
<span class="kn">from</span> <span class="nn">catalyst.utils.run_algo</span> <span class="kn">import</span> <span class="n">run_algorithm</span>
<span class="n">np</span><span class="o">.</span><span class="n">set_printoptions</span><span class="p">(</span><span class="n">threshold</span><span class="o">=</span><span class="s1">&#39;nan&#39;</span><span class="p">,</span> <span class="n">suppress</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">context</span><span class="p">):</span>
<span class="c1"># Portfolio assets list</span>
<span class="n">context</span><span class="o">.</span><span class="n">assets</span> <span class="o">=</span> <span class="n">symbols</span><span class="p">(</span><span class="s1">&#39;btc_usdt&#39;</span><span class="p">,</span> <span class="s1">&#39;eth_usdt&#39;</span><span class="p">,</span> <span class="s1">&#39;ltc_usdt&#39;</span><span class="p">,</span> <span class="s1">&#39;dash_usdt&#39;</span><span class="p">,</span>
<span class="s1">&#39;xmr_usdt&#39;</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">nassets</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">assets</span><span class="p">)</span>
<span class="c1"># Set the time window that will be used to compute expected return</span>
<span class="c1"># and asset correlations</span>
<span class="n">context</span><span class="o">.</span><span class="n">window</span> <span class="o">=</span> <span class="mi">180</span>
<span class="c1"># Set the number of days between each portfolio rebalancing</span>
<span class="n">context</span><span class="o">.</span><span class="n">rebalance_period</span> <span class="o">=</span> <span class="mi">30</span>
<span class="n">context</span><span class="o">.</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">def</span> <span class="nf">handle_data</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="c1"># Only rebalance at the beggining of the algorithm execution and</span>
<span class="c1"># every multiple of the rebalance period</span>
<span class="k">if</span> <span class="n">context</span><span class="o">.</span><span class="n">i</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">context</span><span class="o">.</span><span class="n">i</span> <span class="o">%</span> <span class="n">context</span><span class="o">.</span><span class="n">rebalance_period</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">n</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">window</span>
<span class="n">prices</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">history</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">assets</span><span class="p">,</span> <span class="n">fields</span><span class="o">=</span><span class="s1">&#39;price&#39;</span><span class="p">,</span>
<span class="n">bar_count</span><span class="o">=</span><span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">frequency</span><span class="o">=</span><span class="s1">&#39;1d&#39;</span><span class="p">)</span>
<span class="n">pr</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asmatrix</span><span class="p">(</span><span class="n">prices</span><span class="p">)</span>
<span class="n">t_prices</span> <span class="o">=</span> <span class="n">prices</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span>
<span class="n">t_val</span> <span class="o">=</span> <span class="n">t_prices</span><span class="o">.</span><span class="n">values</span>
<span class="n">tminus_prices</span> <span class="o">=</span> <span class="n">prices</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="n">n</span><span class="p">]</span>
<span class="n">tminus_val</span> <span class="o">=</span> <span class="n">tminus_prices</span><span class="o">.</span><span class="n">values</span>
<span class="c1"># Compute daily returns (r)</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asmatrix</span><span class="p">(</span><span class="n">t_val</span> <span class="o">/</span> <span class="n">tminus_val</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<span class="c1"># Compute the expected returns of each asset with the average</span>
<span class="c1"># daily return for the selected time window</span>
<span class="n">m</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asmatrix</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">))</span>
<span class="c1"># ###</span>
<span class="n">stds</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">std</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
<span class="c1"># Compute excess returns matrix (xr)</span>
<span class="n">xr</span> <span class="o">=</span> <span class="n">r</span> <span class="o">-</span> <span class="n">m</span>
<span class="c1"># Matrix algebra to get variance-covariance matrix</span>
<span class="n">cov_m</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">transpose</span><span class="p">(</span><span class="n">xr</span><span class="p">),</span> <span class="n">xr</span><span class="p">)</span> <span class="o">/</span> <span class="n">n</span>
<span class="c1"># Compute asset correlation matrix (informative only)</span>
<span class="n">corr_m</span> <span class="o">=</span> <span class="n">cov_m</span> <span class="o">/</span> <span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">transpose</span><span class="p">(</span><span class="n">stds</span><span class="p">),</span> <span class="n">stds</span><span class="p">)</span>
<span class="c1"># Define portfolio optimization parameters</span>
<span class="n">n_portfolios</span> <span class="o">=</span> <span class="mi">50000</span>
<span class="n">results_array</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="mi">3</span> <span class="o">+</span> <span class="n">context</span><span class="o">.</span><span class="n">nassets</span><span class="p">,</span> <span class="n">n_portfolios</span><span class="p">))</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="n">n_portfolios</span><span class="p">):</span>
<span class="n">weights</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">random</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">nassets</span><span class="p">)</span>
<span class="n">weights</span> <span class="o">/=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">weights</span><span class="p">)</span>
<span class="n">w</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asmatrix</span><span class="p">(</span><span class="n">weights</span><span class="p">)</span>
<span class="n">p_r</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">w</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">transpose</span><span class="p">(</span><span class="n">m</span><span class="p">)))</span> <span class="o">*</span> <span class="mi">365</span>
<span class="n">p_std</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">w</span><span class="p">,</span> <span class="n">cov_m</span><span class="p">),</span>
<span class="n">np</span><span class="o">.</span><span class="n">transpose</span><span class="p">(</span><span class="n">w</span><span class="p">)))</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">365</span><span class="p">)</span>
<span class="c1"># store results in results array</span>
<span class="n">results_array</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="n">p</span><span class="p">]</span> <span class="o">=</span> <span class="n">p_r</span>
<span class="n">results_array</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="n">p</span><span class="p">]</span> <span class="o">=</span> <span class="n">p_std</span>
<span class="c1"># store Sharpe Ratio (return / volatility) - risk free rate element</span>
<span class="c1"># excluded for simplicity</span>
<span class="n">results_array</span><span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="n">p</span><span class="p">]</span> <span class="o">=</span> <span class="n">results_array</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="n">p</span><span class="p">]</span> <span class="o">/</span> <span class="n">results_array</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="n">p</span><span class="p">]</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">iw</span> <span class="ow">in</span> <span class="n">weights</span><span class="p">:</span>
<span class="n">results_array</span><span class="p">[</span><span class="mi">3</span> <span class="o">+</span> <span class="n">i</span><span class="p">,</span> <span class="n">p</span><span class="p">]</span> <span class="o">=</span> <span class="n">weights</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
<span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="c1"># convert results array to Pandas DataFrame</span>
<span class="n">results_frame</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">transpose</span><span class="p">(</span><span class="n">results_array</span><span class="p">),</span>
<span class="n">columns</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;r&#39;</span><span class="p">,</span> <span class="s1">&#39;stdev&#39;</span><span class="p">,</span> <span class="s1">&#39;sharpe&#39;</span><span class="p">]</span>
<span class="o">+</span> <span class="n">context</span><span class="o">.</span><span class="n">assets</span><span class="p">)</span>
<span class="c1"># locate position of portfolio with highest Sharpe Ratio</span>
<span class="n">max_sharpe_port</span> <span class="o">=</span> <span class="n">results_frame</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">results_frame</span><span class="p">[</span><span class="s1">&#39;sharpe&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">idxmax</span><span class="p">()]</span>
<span class="c1"># locate positon of portfolio with minimum standard deviation</span>
<span class="c1"># min_vol_port = results_frame.iloc[results_frame[&#39;stdev&#39;].idxmin()]</span>
<span class="c1"># order optimal weights for each asset</span>
<span class="k">for</span> <span class="n">asset</span> <span class="ow">in</span> <span class="n">context</span><span class="o">.</span><span class="n">assets</span><span class="p">:</span>
<span class="k">if</span> <span class="n">data</span><span class="o">.</span><span class="n">can_trade</span><span class="p">(</span><span class="n">asset</span><span class="p">):</span>
<span class="n">order_target_percent</span><span class="p">(</span><span class="n">asset</span><span class="p">,</span> <span class="n">max_sharpe_port</span><span class="p">[</span><span class="n">asset</span><span class="p">])</span>
<span class="c1"># create scatter plot coloured by Sharpe Ratio</span>
<span class="n">plt</span><span class="o">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">results_frame</span><span class="o">.</span><span class="n">stdev</span><span class="p">,</span>
<span class="n">results_frame</span><span class="o">.</span><span class="n">r</span><span class="p">,</span>
<span class="n">c</span><span class="o">=</span><span class="n">results_frame</span><span class="o">.</span><span class="n">sharpe</span><span class="p">,</span>
<span class="n">cmap</span><span class="o">=</span><span class="s1">&#39;RdYlGn&#39;</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s1">&#39;Volatility&#39;</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s1">&#39;Returns&#39;</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">colorbar</span><span class="p">()</span>
<span class="c1"># plot red star to highlight position of portfolio</span>
<span class="c1"># with highest Sharpe Ratio</span>
<span class="n">plt</span><span class="o">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">max_sharpe_port</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span>
<span class="n">max_sharpe_port</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
<span class="n">marker</span><span class="o">=</span><span class="s1">&#39;o&#39;</span><span class="p">,</span>
<span class="n">color</span><span class="o">=</span><span class="s1">&#39;b&#39;</span><span class="p">,</span>
<span class="n">s</span><span class="o">=</span><span class="mi">200</span><span class="p">)</span>
<span class="c1"># plot green star to highlight position of minimum variance portfolio</span>
<span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">print</span><span class="p">(</span><span class="n">max_sharpe_port</span><span class="p">)</span>
<span class="n">record</span><span class="p">(</span><span class="n">pr</span><span class="o">=</span><span class="n">pr</span><span class="p">,</span>
<span class="n">r</span><span class="o">=</span><span class="n">r</span><span class="p">,</span>
<span class="n">m</span><span class="o">=</span><span class="n">m</span><span class="p">,</span>
<span class="n">stds</span><span class="o">=</span><span class="n">stds</span><span class="p">,</span>
<span class="n">max_sharpe_port</span><span class="o">=</span><span class="n">max_sharpe_port</span><span class="p">,</span>
<span class="n">corr_m</span><span class="o">=</span><span class="n">corr_m</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">def</span> <span class="nf">analyze</span><span class="p">(</span><span class="n">context</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">results</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="c1"># Form DataFrame with selected data</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">results</span><span class="p">[[</span><span class="s1">&#39;pr&#39;</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">,</span> <span class="s1">&#39;m&#39;</span><span class="p">,</span> <span class="s1">&#39;stds&#39;</span><span class="p">,</span> <span class="s1">&#39;max_sharpe_port&#39;</span><span class="p">,</span> <span class="s1">&#39;corr_m&#39;</span><span class="p">,</span>
<span class="s1">&#39;portfolio_value&#39;</span><span class="p">]]</span>
<span class="c1"># Save results in CSV file</span>
<span class="n">filename</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">splitext</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="vm">__file__</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">data</span><span class="o">.</span><span class="n">to_csv</span><span class="p">(</span><span class="n">filename</span> <span class="o">+</span> <span class="s1">&#39;.csv&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
<span class="c1"># Bitcoin data is available from 2015-3-2. Dates vary for other tokens.</span>
<span class="n">start</span> <span class="o">=</span> <span class="n">datetime</span><span class="p">(</span><span class="mi">2017</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">pytz</span><span class="o">.</span><span class="n">utc</span><span class="p">)</span>
<span class="n">end</span> <span class="o">=</span> <span class="n">datetime</span><span class="p">(</span><span class="mi">2017</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">16</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">pytz</span><span class="o">.</span><span class="n">utc</span><span class="p">)</span>
<span class="n">results</span> <span class="o">=</span> <span class="n">run_algorithm</span><span class="p">(</span><span class="n">initialize</span><span class="o">=</span><span class="n">initialize</span><span class="p">,</span>
<span class="n">handle_data</span><span class="o">=</span><span class="n">handle_data</span><span class="p">,</span>
<span class="n">analyze</span><span class="o">=</span><span class="n">analyze</span><span class="p">,</span>
<span class="n">start</span><span class="o">=</span><span class="n">start</span><span class="p">,</span>
<span class="n">end</span><span class="o">=</span><span class="n">end</span><span class="p">,</span>
<span class="n">exchange_name</span><span class="o">=</span><span class="s1">&#39;poloniex&#39;</span><span class="p">,</span>
<span class="n">capital_base</span><span class="o">=</span><span class="mi">100000</span><span class="p">,</span>
<span class="n">base_currency</span><span class="o">=</span><span class="s1">&#39;usdt&#39;</span><span class="p">,</span> <span class="p">)</span>
</pre></div>
</div>
<img alt="https://cdn-images-1.medium.com/max/1600/0*EjjiKZHlYF3sn7yQ." class="align-center" src="https://cdn-images-1.medium.com/max/1600/0*EjjiKZHlYF3sn7yQ." />
</div>
</div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
<a href="utilities.html" class="btn btn-neutral float-right" title="Utilities" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
<a href="features.html" class="btn btn-neutral" title="Features" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
</div>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2018, Enigma MPC, Inc..
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'./',
VERSION:'0.4',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
});
</script>
</body>
</html>