From a2a90f82c31c9490cb4f9a1cea63ccbc7205522f Mon Sep 17 00:00:00 2001 From: Victor Grau Serrat Date: Sun, 19 Nov 2017 23:53:36 -0700 Subject: [PATCH] DOC: Added Example Algos and Utilities pages --- _sources/example-algos.txt | 172 +++++++++++++ _sources/index.txt | 2 + _sources/utilities.txt | 149 ++++++++++++ appendix.html | 9 + beginner-tutorial.html | 28 ++- bundles.html | 28 ++- development-guidelines.html | 28 ++- example-algos.html | 469 ++++++++++++++++++++++++++++++++++++ genindex.html | 9 + index.html | 11 + install.html | 4 + jupyter.html | 28 ++- live-trading.html | 28 ++- naming-convention.html | 32 ++- release-process.html | 28 ++- releases.html | 28 ++- resources.html | 28 ++- search.html | 9 + searchindex.js | 2 +- utilities.html | 446 ++++++++++++++++++++++++++++++++++ videos.html | 32 ++- welcome.html | 28 ++- 22 files changed, 1472 insertions(+), 126 deletions(-) create mode 100644 _sources/example-algos.txt create mode 100644 _sources/utilities.txt create mode 100644 example-algos.html create mode 100644 utilities.html diff --git a/_sources/example-algos.txt b/_sources/example-algos.txt new file mode 100644 index 00000000..7882208d --- /dev/null +++ b/_sources/example-algos.txt @@ -0,0 +1,172 @@ +| +Example Algorithms +================== + +This section documents a small number of example algorithms to complement the +beginner tutorial, and show how other trading algorithms can be implemented +using Catalyst: + +Buy and Hodl +~~~~~~~~~~~~ + +source: `examples/buy_and_hodl.py `_ + +First ingest the historical pricing data needed to run this algorithm: + +.. code-block:: bash + + catalyst ingest-exchange -x poloniex -f daily -i btc_usdt + +Then, you can run the code below with the following command: + +.. code-block:: bash + + catalyst run -f buy_and_hodl.py --start 2015-3-1 --end 2017-10-31 --capital-base 100000 -x poloniex -c btc -o bah.pickle + +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 ``--start`` and ``--end`` parameters, but bear in mind +that 2015-3-1 is the earliest date that Catalyst supports (if you choose an +earlier date, you'll get an error), and the most recent date you can choose is +one day prior to the current date. + + +.. code-block:: python + + #!/usr/bin/env python + # + # Copyright 2017 Enigma MPC, Inc. + # Copyright 2015 Quantopian, Inc. + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + import pandas as pd + + from catalyst.api import ( + order_target_value, + symbol, + record, + cancel_order, + get_open_orders, + ) + + + def initialize(context): + context.ASSET_NAME = 'btc_usdt' + context.TARGET_HODL_RATIO = 0.8 + context.RESERVE_RATIO = 1.0 - context.TARGET_HODL_RATIO + + context.is_buying = True + context.asset = symbol(context.ASSET_NAME) + + context.i = 0 + + + def handle_data(context, data): + context.i += 1 + + starting_cash = context.portfolio.starting_cash + target_hodl_value = context.TARGET_HODL_RATIO * starting_cash + reserve_value = context.RESERVE_RATIO * starting_cash + + # Cancel any outstanding orders + orders = get_open_orders(context.asset) or [] + for order in orders: + cancel_order(order) + + # Stop buying after passing the reserve threshold + cash = context.portfolio.cash + if cash <= reserve_value: + context.is_buying = False + + # Retrieve current asset price from pricing data + price = data.current(context.asset, 'price') + + # Check if still buying and could (approximately) afford another purchase + if context.is_buying and cash > price: + # Place order to make position in asset equal to target_hodl_value + order_target_value( + context.asset, + target_hodl_value, + limit_price=price * 1.1, + stop_price=price * 0.9, + ) + + record( + price=price, + volume=data.current(context.asset, 'volume'), + cash=cash, + starting_cash=context.portfolio.starting_cash, + leverage=context.account.leverage, + ) + + + def analyze(context=None, results=None): + import matplotlib.pyplot as plt + + # Plot the portfolio and asset data. + ax1 = plt.subplot(611) + results[['portfolio_value']].plot(ax=ax1) + ax1.set_ylabel('Portfolio Value (USD)') + + ax2 = plt.subplot(612, sharex=ax1) + ax2.set_ylabel('{asset} (USD)'.format(asset=context.ASSET_NAME)) + results[['price']].plot(ax=ax2) + + trans = results.ix[[t != [] for t in results.transactions]] + buys = trans.ix[ + [t[0]['amount'] > 0 for t in trans.transactions] + ] + ax2.plot( + buys.index, + results.price[buys.index], + '^', + markersize=10, + color='g', + ) + + ax3 = plt.subplot(613, sharex=ax1) + results[['leverage', 'alpha', 'beta']].plot(ax=ax3) + ax3.set_ylabel('Leverage ') + + ax4 = plt.subplot(614, sharex=ax1) + results[['starting_cash', 'cash']].plot(ax=ax4) + ax4.set_ylabel('Cash (USD)') + + results[[ + 'treasury', + 'algorithm', + 'benchmark', + ]] = results[[ + 'treasury_period_return', + 'algorithm_period_return', + 'benchmark_period_return', + ]] + + ax5 = plt.subplot(615, sharex=ax1) + results[[ + 'treasury', + 'algorithm', + 'benchmark', + ]].plot(ax=ax5) + ax5.set_ylabel('Percent Change') + + ax6 = plt.subplot(616, sharex=ax1) + results[['volume']].plot(ax=ax6) + ax6.set_ylabel('Volume (mCoins/5min)') + + plt.legend(loc=3) + + # Show the plot. + plt.gcf().set_size_inches(18, 8) + plt.show() + diff --git a/_sources/index.txt b/_sources/index.txt index 82bbbd37..a0e8f097 100644 --- a/_sources/index.txt +++ b/_sources/index.txt @@ -12,6 +12,8 @@ Table of Contents jupyter live-trading naming-convention + example-algos + utilities videos resources development-guidelines diff --git a/_sources/utilities.txt b/_sources/utilities.txt new file mode 100644 index 00000000..8c89aa52 --- /dev/null +++ b/_sources/utilities.txt @@ -0,0 +1,149 @@ +Utilities +========= + +This section covers a variety of utilites that provide complimentary +functionality to your trading algorithms. These are code snippets that you can +add to any algorithm to add the desired functionality. + +If you are looking for example trading algorithms, see the corresponding section. + +Output to CSV file +~~~~~~~~~~~~~~~~~~ + +Add this script to the analyze method to create and save a CSV file with the +results from the trading algorithm. This file will include the default +parameters of the results DataFrame plus any recorded variables and will be +saved in the same location where your trading algorithm is saved. The exact +script that you need to use depends on the interface that you are using to run +your trading algorithm, which could be the CLI or a Python Interpreter. + +1. Script to use with CLI: + + .. code-block:: python + + def analyze(context=None, results=None): + import sys + import os + from os.path import basename + + # Save results in CSV file + filename = os.path.splitext(basename(sys.argv[3]))[0] + results.to_csv(filename + '.csv') + +2. Script to use with Python Interpreter: + + .. code-block:: python + + def analyze(context=None, results=None): + import os + from os.path import basename + + # Save results in CSV file + filename = os.path.splitext(os.path.basename(__file__))[0] + results.to_csv(filename + '.csv') + +Extracting market data +~~~~~~~~~~~~~~~~~~~~~~ + +Use this script to save the price and volume data of one cryptoasset in a CSV +file, which will be saved in the same location and with the same name as your +Python file. To get custom data, simply modify the asset's symbol and the dates. +Run this script directly from your development environment: python scriptname.py, +where the contents of 'scriptname.py' are as follows. Two different version are +provided as an example for daily- and minute-resolution data respectively: + +Simpler case for daily data + +.. code-block:: python + + import os + import pytz + from datetime import datetime + + from catalyst.api import record, symbol, symbols + from catalyst.utils.run_algo import run_algorithm + + def initialize(context): + # Portfolio assets list + context.asset = symbol('btc_usdt') # Bitcoin on Poloniex + + def handle_data(context, data): + # Variables to record for a given asset: price and volume + price = data.current(context.asset, 'price') + volume = data.current(context.asset, 'volume') + record(price=price, volume=volume) + + def analyze(context=None, results=None): + + # Generate DataFrame with Price and Volume only + data = results[['price','volume']] + + # Save results in CSV file + filename = os.path.splitext(os.path.basename(__file__))[0] + data.to_csv(filename + '.csv') + + ''' Bitcoin data is available on Poloniex since 2015-3-1. + Dates vary for other tokens. In the example below, we choose the + full month of July of 2017. + ''' + start = datetime(2017, 1, 1, 0, 0, 0, 0, pytz.utc) + end = datetime(2017, 7, 31, 0, 0, 0, 0, pytz.utc) + results = run_algorithm(initialize=initialize, + handle_data=handle_data, + analyze=analyze, + start=start, + end=end, + exchange_name='poloniex', + capital_base=10000, + base_currency = 'usdt') + +More versatile case for minute data + +.. code-block:: python + + import os + import csv + import pytz + from datetime import datetime + + from catalyst.api import record, symbol, symbols + from catalyst.utils.run_algo import run_algorithm + + + def initialize(context): + # Portfolio assets list + context.asset = symbol('btc_usdt') # Bitcoin on Poloniex + + # Creates a .CSV file with the same name as this script to store results + context.csvfile = open(os.path.splitext( + os.path.basename(__file__))[0]+'.csv', 'w+') + context.csvwriter = csv.writer(context.csvfile) + + def handle_data(context, data): + # Variables to record for a given asset: price and volume + # Other options include 'open', 'high', 'open', 'close' + # Please note that 'price' equals 'close' + date = context.blotter.current_dt # current time in each iteration + price = data.current(context.asset, 'price') + volume = data.current(context.asset, 'volume') + + # Writes one line to CSV on each iteration with the chosen variables + context.csvwriter.writerow([date,price,volume]) + + def analyze(context=None, results=None): + # Close open file properly at the end + context.csvfile.close() + + + # Bitcoin data is available from 2015-3-2. Dates vary for other tokens. + start = datetime(2017, 7, 30, 0, 0, 0, 0, pytz.utc) + end = datetime(2017, 7, 31, 0, 0, 0, 0, pytz.utc) + results = run_algorithm(initialize=initialize, + handle_data=handle_data, + analyze=analyze, + start=start, + end=end, + exchange_name='poloniex', + data_frequency='minute', + base_currency ='usdt', + capital_base=10000 ) \ No newline at end of file diff --git a/appendix.html b/appendix.html index 05550ad4..2d65e21e 100644 --- a/appendix.html +++ b/appendix.html @@ -119,6 +119,15 @@
  • Naming Convention
  • +
  • Example Algorithms +
  • +
  • Utilities +
  • Videos
    • Installation: MacOS
    • Installation: Windows
    • diff --git a/beginner-tutorial.html b/beginner-tutorial.html index dcb61f4c..76660c21 100644 --- a/beginner-tutorial.html +++ b/beginner-tutorial.html @@ -73,21 +73,23 @@
    • Naming Convention
    • +
    • Example Algorithms +
    • Videos
      • Installation: MacOS
      • Installation: Windows
      • diff --git a/bundles.html b/bundles.html index 85d6c04f..1ff7bc11 100644 --- a/bundles.html +++ b/bundles.html @@ -71,21 +71,23 @@
      • Naming Convention
      • +
      • Example Algorithms +
      • Videos
        • Installation: MacOS
        • Installation: Windows
        • diff --git a/development-guidelines.html b/development-guidelines.html index fd968c61..a600071e 100644 --- a/development-guidelines.html +++ b/development-guidelines.html @@ -73,21 +73,23 @@
        • Naming Convention
        • +
        • Example Algorithms +
        • Videos
          • Installation: MacOS
          • Installation: Windows
          • diff --git a/example-algos.html b/example-algos.html new file mode 100644 index 00000000..f94a8dde --- /dev/null +++ b/example-algos.html @@ -0,0 +1,469 @@ + + + + + + + + + + + Example Algorithms — Catalyst 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + + +
            + + + + + + +
            +
            +
            + +
            +
            +
            + +
            +

            +
            +
            +

            Example Algorithms

            +

            This section documents a small number of example algorithms to complement the +beginner tutorial, and show how other trading algorithms can be implemented +using Catalyst:

            +
            +

            Buy and Hodl

            +

            source: examples/buy_and_hodl.py

            +

            First ingest the historical pricing data needed to run this algorithm:

            +
            catalyst ingest-exchange -x poloniex -f daily -i btc_usdt
            +
            +
            +

            Then, you can run the code below with the following command:

            +
            catalyst run -f buy_and_hodl.py --start 2015-3-1 --end 2017-10-31 --capital-base 100000 -x poloniex -c btc -o bah.pickle
            +
            +
            +

            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 --start and --end parameters, but bear in mind +that 2015-3-1 is the earliest date that Catalyst supports (if you choose an +earlier date, you’ll get an error), and the most recent date you can choose is +one day prior to the current date.

            +
            #!/usr/bin/env python
            +#
            +# Copyright 2017 Enigma MPC, Inc.
            +# Copyright 2015 Quantopian, Inc.
            +#
            +# Licensed under the Apache License, Version 2.0 (the "License");
            +# you may not use this file except in compliance with the License.
            +# You may obtain a copy of the License at
            +#
            +#     http://www.apache.org/licenses/LICENSE-2.0
            +#
            +# Unless required by applicable law or agreed to in writing, software
            +# distributed under the License is distributed on an "AS IS" BASIS,
            +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            +# See the License for the specific language governing permissions and
            +# limitations under the License.
            +import pandas as pd
            +
            +from catalyst.api import (
            +    order_target_value,
            +    symbol,
            +    record,
            +    cancel_order,
            +    get_open_orders,
            +)
            +
            +
            +def initialize(context):
            +    context.ASSET_NAME = 'btc_usdt'
            +    context.TARGET_HODL_RATIO = 0.8
            +    context.RESERVE_RATIO = 1.0 - context.TARGET_HODL_RATIO
            +
            +    context.is_buying = True
            +    context.asset = symbol(context.ASSET_NAME)
            +
            +    context.i = 0
            +
            +
            +def handle_data(context, data):
            +    context.i += 1
            +
            +    starting_cash = context.portfolio.starting_cash
            +    target_hodl_value = context.TARGET_HODL_RATIO * starting_cash
            +    reserve_value = context.RESERVE_RATIO * starting_cash
            +
            +    # Cancel any outstanding orders
            +    orders = get_open_orders(context.asset) or []
            +    for order in orders:
            +        cancel_order(order)
            +
            +    # Stop buying after passing the reserve threshold
            +    cash = context.portfolio.cash
            +    if cash <= reserve_value:
            +        context.is_buying = False
            +
            +    # Retrieve current asset price from pricing data
            +    price = data.current(context.asset, 'price')
            +
            +    # Check if still buying and could (approximately) afford another purchase
            +    if context.is_buying and cash > price:
            +        # Place order to make position in asset equal to target_hodl_value
            +        order_target_value(
            +            context.asset,
            +            target_hodl_value,
            +            limit_price=price * 1.1,
            +            stop_price=price * 0.9,
            +        )
            +
            +    record(
            +        price=price,
            +        volume=data.current(context.asset, 'volume'),
            +        cash=cash,
            +        starting_cash=context.portfolio.starting_cash,
            +        leverage=context.account.leverage,
            +    )
            +
            +
            +def analyze(context=None, results=None):
            +    import matplotlib.pyplot as plt
            +
            +    # Plot the portfolio and asset data.
            +    ax1 = plt.subplot(611)
            +    results[['portfolio_value']].plot(ax=ax1)
            +    ax1.set_ylabel('Portfolio Value (USD)')
            +
            +    ax2 = plt.subplot(612, sharex=ax1)
            +    ax2.set_ylabel('{asset} (USD)'.format(asset=context.ASSET_NAME))
            +    results[['price']].plot(ax=ax2)
            +
            +    trans = results.ix[[t != [] for t in results.transactions]]
            +    buys = trans.ix[
            +        [t[0]['amount'] > 0 for t in trans.transactions]
            +    ]
            +    ax2.plot(
            +        buys.index,
            +        results.price[buys.index],
            +        '^',
            +        markersize=10,
            +        color='g',
            +    )
            +
            +    ax3 = plt.subplot(613, sharex=ax1)
            +    results[['leverage', 'alpha', 'beta']].plot(ax=ax3)
            +    ax3.set_ylabel('Leverage ')
            +
            +    ax4 = plt.subplot(614, sharex=ax1)
            +    results[['starting_cash', 'cash']].plot(ax=ax4)
            +    ax4.set_ylabel('Cash (USD)')
            +
            +    results[[
            +        'treasury',
            +        'algorithm',
            +        'benchmark',
            +    ]] = results[[
            +        'treasury_period_return',
            +        'algorithm_period_return',
            +        'benchmark_period_return',
            +    ]]
            +
            +    ax5 = plt.subplot(615, sharex=ax1)
            +    results[[
            +        'treasury',
            +        'algorithm',
            +        'benchmark',
            +    ]].plot(ax=ax5)
            +    ax5.set_ylabel('Percent Change')
            +
            +    ax6 = plt.subplot(616, sharex=ax1)
            +    results[['volume']].plot(ax=ax6)
            +    ax6.set_ylabel('Volume (mCoins/5min)')
            +
            +    plt.legend(loc=3)
            +
            +    # Show the plot.
            +    plt.gcf().set_size_inches(18, 8)
            +    plt.show()
            +
            +
            +
            +
            + + +
            + + +
            +
            + +
            + +
            + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/genindex.html b/genindex.html index 06f014cf..9d946af5 100644 --- a/genindex.html +++ b/genindex.html @@ -120,6 +120,15 @@
        • Naming Convention
        • +
        • Example Algorithms +
        • +
        • Utilities +
        • Videos
        • Naming Convention
        • +
        • Example Algorithms +
        • +
        • Utilities +
        • Videos
        • Naming Convention
        • +
        • Example Algorithms +
        • Videos
          • Installation: MacOS
          • Installation: Windows
          • diff --git a/jupyter.html b/jupyter.html index 695d678e..24c75699 100644 --- a/jupyter.html +++ b/jupyter.html @@ -73,21 +73,23 @@
          • Naming Convention
          • +
          • Example Algorithms +
          • Videos
            • Installation: MacOS
            • Installation: Windows
            • diff --git a/live-trading.html b/live-trading.html index 3b5baeeb..3e1c012d 100644 --- a/live-trading.html +++ b/live-trading.html @@ -73,21 +73,23 @@
            • Naming Convention
            • +
            • Example Algorithms +
            • Videos
              • Installation: MacOS
              • Installation: Windows
              • diff --git a/naming-convention.html b/naming-convention.html index e1a91828..24fa1e98 100644 --- a/naming-convention.html +++ b/naming-convention.html @@ -31,7 +31,7 @@ - + @@ -73,21 +73,23 @@
              • Naming Convention
              • +
              • Example Algorithms +
              • Videos
                • Installation: MacOS
                • Installation: Windows
                • @@ -285,7 +291,7 @@ or any other cryptocurrency. Given its 1:1 mapping to the USD, is a viable alter diff --git a/welcome.html b/welcome.html index fc19b406..fb51bd3e 100644 --- a/welcome.html +++ b/welcome.html @@ -71,21 +71,23 @@
                • Naming Convention
                • +
                • Example Algorithms +
                • Videos