【StudyQuant| Python量化投資課堂系列1】Catalyst 快速搭建 數字貨幣Python量化投資回測及實盤交易平臺 -


之前就聽說過Catalyst這個項目,Github,1.2k star, 今天來寫個搭建教程,希望能幫到大家。

Enigma- Catalyst

量化交易龍頭

Enigma是數字貨幣量化交易的龍頭,但Enigma是一個保護數據隱私的分佈式計算平臺,而在其之上建立的第一個應用Catalyst纔是龍頭級的量化投資平臺,它是用Python編寫的加密資產的算法交易市場。我們可以把Enigma理解爲就是Catalyst底層的一個計算協議,通過Enigma來獲取數據源和對數據的加密計算,而Catalyst是一個應用平臺,開放給量化投資者進行數據預測和測試。因爲面向投資者,Catalyst提供了豐富的API接口和交易策略的SDK供開發者使用,開發者們可以快速簡單的使用這些接口來對交易策略進行開發,並通過Enigma提供的計算來驗證其可行性。

其代幣一個作用是是可以作爲節點的保證金**,由於Enigma是公鏈,其**提出的類POS共識機制引入了懲罰機制,保證節點提供有效的數據。**此外,其代幣可以作爲計算費用,儲存、檢索、計算數據都需要一定的消耗(類似Gas)。

Enigma代幣去年10月上交易所,隨後持續了大概兩個月的破發橫盤,投資者怨聲載道,而在今年一月開始有了爆發性的增長,高點接近20倍的漲幅,隨後跟隨大盤一路持續下跌,後續的發展還要看其具體的應用效果了。

Catalyst是一個用Python編寫的加密資產的算法交易庫。它允許交易策略易於表達,並根據歷史數據(每日和分鐘的分辨率)進行反向測試,提供有關特定策略性能的分析和見解。 Catalyst還支持加密資產的實時交易,從四個交易所(Binance,Bitfinex,Bittrex和Poloniex)開始,隨着時間的推移會增加更多。 Catalyst使用戶能夠共享和策劃數據,並構建有利可圖的數據驅動型投資策略。請訪問catalystcrypto.io以瞭解有關Catalyst的更多信息。

Catalyst建立在完善的Zipline項目之上。我們盡最大努力減少對通用API的結構更改,以最大限度地兼容現有的交易算法,開發人員知識和教程。

概觀
易於使用:Catalyst試圖擺脫你的方式,以便你可以專注於算法開發。查看提供的交易策略示例。
通過交易量支持幾個頂級加密交易:Bitfinex,Bittrex,Poloniex和Binance。
安全:您和您只有權訪問您帳戶的每個交換API密鑰。
通過交換輸入所有加密資產的歷史定價數據,具有每日和分鐘的分辨率。請參閱Catalyst市場覆蓋率概述。
回測和實時交易功能,兩種模式之間的無縫過渡。
性能統計數據的輸出基於Pandas DataFrames,可以很好地集成到現有的PyData生態系統中。
像matplotlib,scipy,statsmodels和sklearn這樣的統計和機器學習庫支持最先進的交易系統的開發,分析和可視化。
增加比特幣價格(btc_usdt)作爲比較交易算法性能的基準。

環境安裝

Windows要求

在Windows中,您首先需要安裝Microsoft Visual C ++編譯器,這取決於您計劃使用的Python版本:

Python 3.5,3.6:Visual C ++ 2015 Build Tools,安裝Visual C ++版本14.0。 這是推薦的版本
Python 2.7:用於Python 2.7的Microsoft Visual C ++編譯器,安裝Visual C ++版本9.0
該軟件包包含編譯器和爲Python軟件包生成二進制輪所需的系統頭集。 如果它尚未在您的系統中,請下載並安裝它,然後再繼續下一步。 如果您需要其他幫助,或者正在尋找其他版本的Visual C ++ for Windows(僅限高級用戶),請單擊此鏈接。

Installing with pip

$ pip install enigma-catalyst matplotlib

交易所數據導入

導入數據

在您可以回溯測試算法之前,首先需要加載Catalyst通過稱爲攝取的過程運行模擬所需的歷史定價數據。當您提取數據時,Catalyst會從Enigma服務器(最終將遷移到Enigma Data Marketplace)以壓縮形式下載該數據,並將其存儲在本地以使其在運行時可用。

要獲取數據,您需要運行如下命令:

catalyst ingest-exchange -x bitfinex -i btc_usd

這指示Catalyst從Bitfinex交易所下載btc_usd貨幣對的定價數據(這來自我們想要交易的簡單算法btc_usd),我們選擇使用Bitfinex交易所的歷史定價數據來測試我們的算法。默認情況下,Catalyst假定您需要具有每日頻率的數據(每天一個燭臺)。如果您想要小頻率(每分鐘一個蠟燭條),您需要指定如下:

catalyst ingest-exchange -x bitfinex -i btc_usd -f minute

[====================================]攝取bitfinex的每日價格數據:100%
我們認爲,對數據的管理方式有一個高層次的理解非常重要,因此需要進行以下概述:

定價數據被拆分並打包成捆綁:按時間序列組織的數據塊每天在Enigma的服務器上保持最新。 Catalyst下載請求的包並重建硬盤中的完整數據集。
定價數據以每日和分鐘的分辨率提供。這些是不同的捆綁數據集,並單獨管理。
捆綁包是特定於交易所的,因爲定價數據特定於每個交易所發生的交易。因此,您必須在攝取數據時指定要從中獲取定價數據的交換。
Catalyst會跟蹤所有下載的軟件包,因此只需下載一次,並根據需要進行增量更新。
在實時交易模式下運行時,Catalyst將首先在本地存儲的捆綁包中查找歷史定價數據。如果缺少任何內容,Catalyst將在交換機上查找最新數據,並將其與本地捆綁包合併,以優化其需要對交換機發出的請求數。

image.png

運行策略

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from logbook import Logger

from catalyst import run_algorithm
from catalyst.api import (record, symbol, order_target_percent,)
from catalyst.exchange.utils.stats_utils import extract_transactions

NAMESPACE = 'dual_moving_average'
log = Logger(NAMESPACE)


def initialize(context):
    context.i = 0
    context.asset = symbol('ltc_usd')
    context.base_price = None


def handle_data(context, data):
    # define the windows for the moving averages
    short_window = 50
    long_window = 200

    # Skip as many bars as long_window to properly compute the average
    context.i += 1
    if context.i < long_window:
        return

    # Compute moving averages calling data.history() for each
    # moving average with the appropriate parameters. We choose to use
    # minute bars for this simulation -> freq="1m"
    # Returns a pandas dataframe.
    short_data = data.history(context.asset,
                              'price',
                              bar_count=short_window,
                              frequency="1T",
                              )
    short_mavg = short_data.mean()
    long_data = data.history(context.asset,
                             'price',
                             bar_count=long_window,
                             frequency="1T",
                             )
    long_mavg = long_data.mean()

    # Let's keep the price of our asset in a more handy variable
    price = data.current(context.asset, 'price')

    # If base_price is not set, we use the current value. This is the
    # price at the first bar which we reference to calculate price_change.
    if context.base_price is None:
        context.base_price = price
    price_change = (price - context.base_price) / context.base_price

    # Save values for later inspection
    record(price=price,
           cash=context.portfolio.cash,
           price_change=price_change,
           short_mavg=short_mavg,
           long_mavg=long_mavg)

    # Since we are using limit orders, some orders may not execute immediately
    # we wait until all orders are executed before considering more trades.
    orders = context.blotter.open_orders
    if len(orders) > 0:
        return

    # Exit if we cannot trade
    if not data.can_trade(context.asset):
        return

    # We check what's our position on our portfolio and trade accordingly
    pos_amount = context.portfolio.positions[context.asset].amount

    # Trading logic
    if short_mavg > long_mavg and pos_amount == 0:
        # we buy 100% of our portfolio for this asset
        order_target_percent(context.asset, 1)
    elif short_mavg < long_mavg and pos_amount > 0:
        # we sell all our positions for this asset
        order_target_percent(context.asset, 0)


def analyze(context, perf):
    # Get the quote_currency that was passed as a parameter to the simulation
    exchange = list(context.exchanges.values())[0]
    quote_currency = exchange.quote_currency.upper()

    # First chart: Plot portfolio value using quote_currency
    ax1 = plt.subplot(411)
    perf.loc[:, ['portfolio_value']].plot(ax=ax1)
    ax1.legend_.remove()
    ax1.set_ylabel('Portfolio Value\n({})'.format(quote_currency))
    start, end = ax1.get_ylim()
    ax1.yaxis.set_ticks(np.arange(start, end, (end - start) / 5))

    # Second chart: Plot asset price, moving averages and buys/sells
    ax2 = plt.subplot(412, sharex=ax1)
    perf.loc[:, ['price', 'short_mavg', 'long_mavg']].plot(
        ax=ax2,
        label='Price')
    ax2.legend_.remove()
    ax2.set_ylabel('{asset}\n({quote})'.format(
        asset=context.asset.symbol,
        quote=quote_currency
    ))
    start, end = ax2.get_ylim()
    ax2.yaxis.set_ticks(np.arange(start, end, (end - start) / 5))

    transaction_df = extract_transactions(perf)
    if not transaction_df.empty:
        buy_df = transaction_df[transaction_df['amount'] > 0]
        sell_df = transaction_df[transaction_df['amount'] < 0]
        ax2.scatter(
            buy_df.index.to_pydatetime(),
            perf.loc[buy_df.index, 'price'],
            marker='^',
            s=100,
            c='green',
            label=''
        )
        ax2.scatter(
            sell_df.index.to_pydatetime(),
            perf.loc[sell_df.index, 'price'],
            marker='v',
            s=100,
            c='red',
            label=''
        )

    # Third chart: Compare percentage change between our portfolio
    # and the price of the asset
    ax3 = plt.subplot(413, sharex=ax1)
    perf.loc[:, ['algorithm_period_return', 'price_change']].plot(ax=ax3)
    ax3.legend_.remove()
    ax3.set_ylabel('Percent Change')
    start, end = ax3.get_ylim()
    ax3.yaxis.set_ticks(np.arange(start, end, (end - start) / 5))

    # Fourth chart: Plot our cash
    ax4 = plt.subplot(414, sharex=ax1)
    perf.cash.plot(ax=ax4)
    ax4.set_ylabel('Cash\n({})'.format(quote_currency))
    start, end = ax4.get_ylim()
    ax4.yaxis.set_ticks(np.arange(0, end, end / 5))

    plt.show()


if __name__ == '__main__':

    run_algorithm(
            capital_base=1000,
            data_frequency='minute',
            initialize=initialize,
            handle_data=handle_data,
            analyze=analyze,
            exchange_name='bitfinex',
            algo_namespace=NAMESPACE,
            quote_currency='usd',
            start=pd.to_datetime('2018-02-07', utc=True),
            end=pd.to_datetime('2018-05-09', utc=True),
        )
   

回測結果

image.png

其他

如果還有什麼不懂的,歡迎添加 微信 82789754 諮詢
另外課程有詳細的教CATALYST搭建和策略分享
量化投資與數字貨幣實戰

更多量化學習資源

介紹.png
掃上方二維碼,關注公衆賬號 量化投資學院 ,獲取下列免費資源

  • 回覆**“熱點研報”**,獲取近年熱點券商金融工程研究報告
  • 回覆**“Python3”**,獲取Python免費學習教程

關注StudyQuant

Enigma- Catalyst

量化交易龍頭

Enigma是數字貨幣量化交易的龍頭,但Enigma是一個保護數據隱私的分佈式計算平臺,而在其之上建立的第一個應用Catalyst纔是龍頭級的量化投資平臺,它是用Python編寫的加密資產的算法交易市場。我們可以把Enigma理解爲就是Catalyst底層的一個計算協議,通過Enigma來獲取數據源和對數據的加密計算,而Catalyst是一個應用平臺,開放給量化投資者進行數據預測和測試。因爲面向投資者,Catalyst提供了豐富的API接口和交易策略的SDK供開發者使用,開發者們可以快速簡單的使用這些接口來對交易策略進行開發,並通過Enigma提供的計算來驗證其可行性。

其代幣一個作用是是可以作爲節點的保證金**,由於Enigma是公鏈,其**提出的類POS共識機制引入了懲罰機制,保證節點提供有效的數據。**此外,其代幣可以作爲計算費用,儲存、檢索、計算數據都需要一定的消耗(類似Gas)。

Enigma代幣去年10月上交易所,隨後持續了大概兩個月的破發橫盤,投資者怨聲載道,而在今年一月開始有了爆發性的增長,高點接近20倍的漲幅,隨後跟隨大盤一路持續下跌,後續的發展還要看其具體的應用效果了。

Catalyst是一個用Python編寫的加密資產的算法交易庫。它允許交易策略易於表達,並根據歷史數據(每日和分鐘的分辨率)進行反向測試,提供有關特定策略性能的分析和見解。 Catalyst還支持加密資產的實時交易,從四個交易所(Binance,Bitfinex,Bittrex和Poloniex)開始,隨着時間的推移會增加更多。 Catalyst使用戶能夠共享和策劃數據,並構建有利可圖的數據驅動型投資策略。請訪問catalystcrypto.io以瞭解有關Catalyst的更多信息。

Catalyst建立在完善的Zipline項目之上。我們盡最大努力減少對通用API的結構更改,以最大限度地兼容現有的交易算法,開發人員知識和教程。

概觀
易於使用:Catalyst試圖擺脫你的方式,以便你可以專注於算法開發。查看提供的交易策略示例。
通過交易量支持幾個頂級加密交易:Bitfinex,Bittrex,Poloniex和Binance。
安全:您和您只有權訪問您帳戶的每個交換API密鑰。
通過交換輸入所有加密資產的歷史定價數據,具有每日和分鐘的分辨率。請參閱Catalyst市場覆蓋率概述。
回測和實時交易功能,兩種模式之間的無縫過渡。
性能統計數據的輸出基於Pandas DataFrames,可以很好地集成到現有的PyData生態系統中。
像matplotlib,scipy,statsmodels和sklearn這樣的統計和機器學習庫支持最先進的交易系統的開發,分析和可視化。
增加比特幣價格(btc_usdt)作爲比較交易算法性能的基準。

環境安裝

Windows要求

在Windows中,您首先需要安裝Microsoft Visual C ++編譯器,這取決於您計劃使用的Python版本:

Python 3.5,3.6:Visual C ++ 2015 Build Tools,安裝Visual C ++版本14.0。 這是推薦的版本
Python 2.7:用於Python 2.7的Microsoft Visual C ++編譯器,安裝Visual C ++版本9.0
該軟件包包含編譯器和爲Python軟件包生成二進制輪所需的系統頭集。 如果它尚未在您的系統中,請下載並安裝它,然後再繼續下一步。 如果您需要其他幫助,或者正在尋找其他版本的Visual C ++ for Windows(僅限高級用戶),請單擊此鏈接。

Installing with pip

$ pip install enigma-catalyst matplotlib

交易所數據導入

導入數據

在您可以回溯測試算法之前,首先需要加載Catalyst通過稱爲攝取的過程運行模擬所需的歷史定價數據。當您提取數據時,Catalyst會從Enigma服務器(最終將遷移到Enigma Data Marketplace)以壓縮形式下載該數據,並將其存儲在本地以使其在運行時可用。

要獲取數據,您需要運行如下命令:

catalyst ingest-exchange -x bitfinex -i btc_usd

這指示Catalyst從Bitfinex交易所下載btc_usd貨幣對的定價數據(這來自我們想要交易的簡單算法btc_usd),我們選擇使用Bitfinex交易所的歷史定價數據來測試我們的算法。默認情況下,Catalyst假定您需要具有每日頻率的數據(每天一個燭臺)。如果您想要小頻率(每分鐘一個蠟燭條),您需要指定如下:

catalyst ingest-exchange -x bitfinex -i btc_usd -f minute

[====================================]攝取bitfinex的每日價格數據:100%
我們認爲,對數據的管理方式有一個高層次的理解非常重要,因此需要進行以下概述:

定價數據被拆分並打包成捆綁:按時間序列組織的數據塊每天在Enigma的服務器上保持最新。 Catalyst下載請求的包並重建硬盤中的完整數據集。
定價數據以每日和分鐘的分辨率提供。這些是不同的捆綁數據集,並單獨管理。
捆綁包是特定於交易所的,因爲定價數據特定於每個交易所發生的交易。因此,您必須在攝取數據時指定要從中獲取定價數據的交換。
Catalyst會跟蹤所有下載的軟件包,因此只需下載一次,並根據需要進行增量更新。
在實時交易模式下運行時,Catalyst將首先在本地存儲的捆綁包中查找歷史定價數據。如果缺少任何內容,Catalyst將在交換機上查找最新數據,並將其與本地捆綁包合併,以優化其需要對交換機發出的請求數。

image.png

運行策略

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from logbook import Logger

from catalyst import run_algorithm
from catalyst.api import (record, symbol, order_target_percent,)
from catalyst.exchange.utils.stats_utils import extract_transactions

NAMESPACE = 'dual_moving_average'
log = Logger(NAMESPACE)


def initialize(context):
    context.i = 0
    context.asset = symbol('ltc_usd')
    context.base_price = None


def handle_data(context, data):
    # define the windows for the moving averages
    short_window = 50
    long_window = 200

    # Skip as many bars as long_window to properly compute the average
    context.i += 1
    if context.i < long_window:
        return

    # Compute moving averages calling data.history() for each
    # moving average with the appropriate parameters. We choose to use
    # minute bars for this simulation -> freq="1m"
    # Returns a pandas dataframe.
    short_data = data.history(context.asset,
                              'price',
                              bar_count=short_window,
                              frequency="1T",
                              )
    short_mavg = short_data.mean()
    long_data = data.history(context.asset,
                             'price',
                             bar_count=long_window,
                             frequency="1T",
                             )
    long_mavg = long_data.mean()

    # Let's keep the price of our asset in a more handy variable
    price = data.current(context.asset, 'price')

    # If base_price is not set, we use the current value. This is the
    # price at the first bar which we reference to calculate price_change.
    if context.base_price is None:
        context.base_price = price
    price_change = (price - context.base_price) / context.base_price

    # Save values for later inspection
    record(price=price,
           cash=context.portfolio.cash,
           price_change=price_change,
           short_mavg=short_mavg,
           long_mavg=long_mavg)

    # Since we are using limit orders, some orders may not execute immediately
    # we wait until all orders are executed before considering more trades.
    orders = context.blotter.open_orders
    if len(orders) > 0:
        return

    # Exit if we cannot trade
    if not data.can_trade(context.asset):
        return

    # We check what's our position on our portfolio and trade accordingly
    pos_amount = context.portfolio.positions[context.asset].amount

    # Trading logic
    if short_mavg > long_mavg and pos_amount == 0:
        # we buy 100% of our portfolio for this asset
        order_target_percent(context.asset, 1)
    elif short_mavg < long_mavg and pos_amount > 0:
        # we sell all our positions for this asset
        order_target_percent(context.asset, 0)


def analyze(context, perf):
    # Get the quote_currency that was passed as a parameter to the simulation
    exchange = list(context.exchanges.values())[0]
    quote_currency = exchange.quote_currency.upper()

    # First chart: Plot portfolio value using quote_currency
    ax1 = plt.subplot(411)
    perf.loc[:, ['portfolio_value']].plot(ax=ax1)
    ax1.legend_.remove()
    ax1.set_ylabel('Portfolio Value\n({})'.format(quote_currency))
    start, end = ax1.get_ylim()
    ax1.yaxis.set_ticks(np.arange(start, end, (end - start) / 5))

    # Second chart: Plot asset price, moving averages and buys/sells
    ax2 = plt.subplot(412, sharex=ax1)
    perf.loc[:, ['price', 'short_mavg', 'long_mavg']].plot(
        ax=ax2,
        label='Price')
    ax2.legend_.remove()
    ax2.set_ylabel('{asset}\n({quote})'.format(
        asset=context.asset.symbol,
        quote=quote_currency
    ))
    start, end = ax2.get_ylim()
    ax2.yaxis.set_ticks(np.arange(start, end, (end - start) / 5))

    transaction_df = extract_transactions(perf)
    if not transaction_df.empty:
        buy_df = transaction_df[transaction_df['amount'] > 0]
        sell_df = transaction_df[transaction_df['amount'] < 0]
        ax2.scatter(
            buy_df.index.to_pydatetime(),
            perf.loc[buy_df.index, 'price'],
            marker='^',
            s=100,
            c='green',
            label=''
        )
        ax2.scatter(
            sell_df.index.to_pydatetime(),
            perf.loc[sell_df.index, 'price'],
            marker='v',
            s=100,
            c='red',
            label=''
        )

    # Third chart: Compare percentage change between our portfolio
    # and the price of the asset
    ax3 = plt.subplot(413, sharex=ax1)
    perf.loc[:, ['algorithm_period_return', 'price_change']].plot(ax=ax3)
    ax3.legend_.remove()
    ax3.set_ylabel('Percent Change')
    start, end = ax3.get_ylim()
    ax3.yaxis.set_ticks(np.arange(start, end, (end - start) / 5))

    # Fourth chart: Plot our cash
    ax4 = plt.subplot(414, sharex=ax1)
    perf.cash.plot(ax=ax4)
    ax4.set_ylabel('Cash\n({})'.format(quote_currency))
    start, end = ax4.get_ylim()
    ax4.yaxis.set_ticks(np.arange(0, end, end / 5))

    plt.show()


if __name__ == '__main__':

    run_algorithm(
            capital_base=1000,
            data_frequency='minute',
            initialize=initialize,
            handle_data=handle_data,
            analyze=analyze,
            exchange_name='bitfinex',
            algo_namespace=NAMESPACE,
            quote_currency='usd',
            start=pd.to_datetime('2018-02-07', utc=True),
            end=pd.to_datetime('2018-05-09', utc=True),
        )
   

回測結果

image.png

其他

如果還有什麼不懂的,歡迎添加 微信 82789754 諮詢
另外課程有詳細的教CATALYST搭建和策略分享
量化投資與數字貨幣實戰

更多量化學習資源

介紹.png
掃上方二維碼,關注公衆賬號 量化投資學院 ,獲取下列免費資源

  • 回覆**“熱點研報”**,獲取近年熱點券商金融工程研究報告
  • 回覆**“Python3”**,獲取Python免費學習教程

關注StudyQuant

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章