如何在自定义zipline捆绑包中使用自定义日历? [英] How to use a custom calendar in a custom zipline bundle?

查看:110
本文介绍了如何在自定义zipline捆绑包中使用自定义日历?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的viacsv.py文件中包含以下代码,旨在允许摄取自定义捆绑包:

I have the following code in my viacsv.py file that aims to allow a custom bundle to be ingested:

#
# Ingest stock csv files to create a zipline data bundle

import os

import numpy  as np
import pandas as pd
import datetime

boDebug=True # Set True to get trace messages

from zipline.utils.cli import maybe_show_progress

def viacsv(symbols,start=None,end=None):

    # strict this in memory so that we can reiterate over it.
    # (Because it could be a generator and they live only once)
    tuSymbols = tuple(symbols)

    if boDebug:
        print "entering viacsv.  tuSymbols=",tuSymbols

    # Define our custom ingest function
    def ingest(environ,
               asset_db_writer,
               minute_bar_writer,  # unused
               daily_bar_writer,
               adjustment_writer,
               calendar,
               cache,
               show_progress,
               output_dir,
               # pass these as defaults to make them 'nonlocal' in py2
               start=start,
               end=end):

        if boDebug:
            print "entering ingest and creating blank dfMetadata"

        dfMetadata = pd.DataFrame(np.empty(len(tuSymbols), dtype=[
            ('start_date', 'datetime64[ns]'),
            ('end_date', 'datetime64[ns]'),
            ('auto_close_date', 'datetime64[ns]'),
            ('symbol', 'object'),
        ]))

        if boDebug:
            print "dfMetadata",type(dfMetadata)
            print dfMetadata.describe
            print

        # We need to feed something that is iterable - like a list or a generator -
        # that is a tuple with an integer for sid and a DataFrame for the data to
        # daily_bar_writer

        liData=[]
        iSid=0
        for S in tuSymbols:
            IFIL="~/notebooks/csv/"+S+".csv"
            if boDebug:
               print "S=",S,"IFIL=",IFIL
            dfData=pd.read_csv(IFIL,index_col='Date',parse_dates=True).sort_index()
            if boDebug:
               print "read_csv dfData",type(dfData),"length",len(dfData)
               print
            dfData.rename(
                columns={
                    'Open': 'open',
                    'High': 'high',
                    'Low': 'low',
                    'Close': 'close',
                    'Volume': 'volume',
                    'Adj Close': 'price',
                },
                inplace=True,
            )
            dfData['volume']=dfData['volume']/1000
            liData.append((iSid,dfData))

            # the start date is the date of the first trade and
            start_date = dfData.index[0]
            if boDebug:
                print "start_date",type(start_date),start_date

            # the end date is the date of the last trade
            end_date = dfData.index[-1]
            if boDebug:
                print "end_date",type(end_date),end_date

            # The auto_close date is the day after the last trade.
            ac_date = end_date + pd.Timedelta(days=1)
            if boDebug:
                print "ac_date",type(ac_date),ac_date

            # Update our meta data
            dfMetadata.iloc[iSid] = start_date, end_date, ac_date, S

            iSid += 1

        if boDebug:
            print "liData",type(liData),"length",len(liData)
            print liData
            print
            print "Now calling daily_bar_writer"

        daily_bar_writer.write(liData, show_progress=False)

        # Hardcode the exchange to "YAHOO" for all assets and (elsewhere)
        # register "YAHOO" to resolve to the NYSE calendar, because these are
        # all equities and thus can use the NYSE calendar.
        dfMetadata['exchange'] = "YAHOO"

        if boDebug:
            print "returned from daily_bar_writer"
            print "calling asset_db_writer"
            print "dfMetadata",type(dfMetadata)
            print dfMetadata
            print

        # Not sure why symbol_map is needed
        symbol_map = pd.Series(dfMetadata.symbol.index, dfMetadata.symbol)
        if boDebug:
            print "symbol_map",type(symbol_map)
            print symbol_map
            print

        asset_db_writer.write(equities=dfMetadata)

        if boDebug:
            print "returned from asset_db_writer"
            print "calling adjustment_writer"

        adjustment_writer.write()

        if boDebug:
            print "returned from adjustment_writer"
            print "now leaving ingest function"

    if boDebug:
       print "about to return ingest function"
    return ingest

我的问题是我输入的数据不是美国数据,而是澳大利亚股票数据。因此,它遵守澳大利亚假期,而不是美国假期。似乎下面的代码以某种方式默认使用美国交易日历,并告诉我,几天之内我无法传递数据,意味着美国市场将被关闭,反之亦然。如何调整以上代码以使用自定义日历?要提取捆绑包,我在终端上运行以下命令:

My problem is that the data I am feed in is not US data but instead Australian equity data. As such, it abides by australian holidays, not US holidays. It seems somehow the code below is defaulting to using a US trading calendar and telling me I cannot pass in data for days that US markets are meant to be closed and vice versa. How can i tweak the above code to take in a custom calendar? To ingest the bundle I run the following command at my terminal:

zipline ingest -b CBA.csv

有什么想法?

推荐答案

您需要在 zipline / utils / calendars 中定义自己的日历:只需创建一个现有文件的副本(例如 exchange_calendar_nyse.py ),然后根据需要的假期进行编辑。假设您将此文件称为 my_own_calendar.py 和类 MyOwnCalendar

Youn need to define your own calendar in zipline/utils/calendars: just create a copy one of the existing files (say, exchange_calendar_nyse.py) and edit with the required holidays. Let's say that you call this file my_own_calendar.py and the class MyOwnCalendar.

请注意还有其他2个(或3个)您需要执行的步骤:

Please note there are other 2 (or 3) steps you need to take:

1)在 zipline / util / calendars / calendar_utils.py 中注册日历:您可以在 _default_calendar_factories 中添加一个条目,如果需要别名,还可以添加 _default_calendar_aliases 。例如,将 my_own_calendar.py 映射到 OWN并使用别名 MY_CALENDAR:

1) Register your calendar in zipline/util/calendars/calendar_utils.py: you can do it adding an entry to _default_calendar_factories and, if you need an alias, _default_calendar_aliases. For example, to map my_own_calendar.py to 'OWN' and with an alias 'MY_CALENDAR':

_default_calendar_factories = {
    'NYSE': NYSEExchangeCalendar,
    'CME': CMEExchangeCalendar,
    ...
    'OWN': MyOwnCalendar
}

_default_calendar_aliases = {
    'NASDAQ': 'NYSE',
    ...
    'MY_CALENDAR': 'OWN'
 }

2),您需要编辑 .zipline / extension.py (您会在主目录中找到.zipline-要在Windows下查看您的家,请打开dos外壳并键入 echo%USERPROFILE%

2) you need to edit .zipline/extension.py (you will find .zipline in your home directory - to see your home under Windows, open a dos shell and type echo %USERPROFILE%

# List the tickers of the market you defined
tickers_of_interest = {'TICKER1', 'TICKER2', ...}

register('my_market', viacsv(tickers_of_interest), calendar_name="OWN")

通过这些步骤,您只需输入 zipline ingest -b就应该能够提取捆绑包my_market

with those steps you should be able to ingest your bundle simply typing zipline ingest -b my_market.

3)我遇到的问题唯一的原因是,鉴于超级类TradingCalendar假设周六/周日为非交易日,因此我需要对交易日历进行更多控制,而并非每种市场/资产类别都如此。日历定义错误将导致提取时发生异常。
例如,要有一个交易日为7/7 24/24的市场日历,我按如下方式修改了日历:

3) The problem I personally had was that I needed to have even more control of the trading calendar, given that the super class TradingCalendar assumes that Saturdays/Sundays are non trading days, and this is not true for every market/asset class. Having a wrong calendar definition will cause exception at ingestion time. For example, to have calendar for a market which trades 7/7 24/24, I hacked the calendar as follows:

from datetime import time
from pytz import timezone
from pandas import date_range
from .trading_calendar import TradingCalendar, HolidayCalendar

from zipline.utils.memoize import lazyval

from pandas.tseries.offsets import CustomBusinessDay

class MyOwnCalendar(TradingCalendar):
    """
    Round the clock calendar: 7/7, 24/24
    """

    @property
    def name(self):
        return "OWN"

    @property
    def tz(self):
        return timezone("Europe/London")

    @property
    def open_time(self):
        return time(0)

    @property
    def close_time(self):
        return time(23, 59)

    @property
    def regular_holidays(self):
        return []

    @property
    def special_opens(self):
        return []

    def sessions_in_range(self, start_session, last_session):
        return date_range(start_session, last_session)

    @lazyval
    def day(self):
        return CustomBusinessDay(holidays=self.adhoc_holidays,
        calendar=self.regular_holidays,weekmask="Mon Tue Wed Thu Fri Sat Sun")

这篇关于如何在自定义zipline捆绑包中使用自定义日历?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆