• Backtrader中文笔记之CSV Data Feed Development


    CSV Data Feed Development

    backtrader already offers a Generic CSV Data feed and some specific CSV Data Feeds. Summarizing:

    backtrader已经提供了一个通用的CSV数据源和一些特定的CSV数据源。总结:

    • GenericCSVData

    • VisualChartCSVData

    • YahooFinanceData (for online downloads)

    • YahooFinanceCSVData (for already downloaded data)

    • BacktraderCSVData (in-house … for testing purposed, but can be used)

    But even with that, the end user may wish to develop support for a specific CSV Data Feed.

    但即便如此,最终用户还是希望开发对特定CSV数据源的支持。

    The usual motto would be: “It’s easier said than done”. Actually the structure is meant to make it easy.

    通常的座右铭是:“说起来容易做起来难”。实际上,这种结构是为了让它更简单。

    Steps:

    • Inherit from backtrader.CSVDataBase

    • 继承backtrader.CSVDataBase
    • Define any params if needed

    • 如果需要,定义任何参数
    • Do any initialization in the start method

    • 在start方法中做任何初始化
    • Do any clean-up in the stop method

    • 在停止方法中做清理
    • Define a _loadline method where the actual work happens

    • 定义实际工作发生的地方的_loadline方法

      This method receives a single argument: linetokens.

    • 此方法接收一个参数:linetokens。
    • As the name suggests this contains the tokens after the current line has been splitten according to the separator parameter (inherited from the base class)

    • 顾名思义,它包含根据separator参数拆分当前行之后的标记(从基类继承)
    • If after doing its work there is new data … fill up the corresponding lines and return True

    • 如果在完成它的工作后有新的数据…填充相应的行并返回True

      If nothing is available and therefore the parsing has come to an end: return False

    • 如果没有可用的内容,因此解析已经结束:return False

      Returning False may not even be needed if the behind the scenes code which is reading the file lines finds out there are no more lines to parse.

    • 如果读取文件行的后台代码发现没有更多的行可供解析,则甚至不需要返回False。

    Things which are already taken into account:

    已经考虑的事项:

    • Opening the file (or receiving a file-like object)

    • 打开文件(或接收类似文件的对象)
    • Skipping the headers row if indicated as present

    • 如果标题行存在跳过
    • Reading the lines

    • 读取行
    • Tokenizing the lines

    • 标记化行
    • Preloading support (to load the entire data feed at once in memory)

    • 预加载支持(在内存中一次加载整个数据源)

    Usually an example is worth a thousand requirement descriptions. Let’s use a simplified version of the in-house defined CSV parsing code from BacktraderCSVData. This one needs no initialization or clean-up (this could be opening a socket and closing it later, for example).

    通常一个示例胜过一千个需求。让我们使用BacktraderCSVData内部定义的CSV解析代码,做一个简化的版本。这个不需要初始化或清理(例如,这可能是打开一个套接字,稍后再关闭它)。

    Note

    backtrader data feeds contain the usual industry standard feeds, which are the ones to be filled.

    backtrader数据源包含通常的行业标准feed,这是需要填充的。即

    • datetime

    • open

    • high

    • low

    • close

    • volume

    • openinterest

    If your strategy/algorithm or simple data perusal only needs, for example the closing prices you can leave the others untouched (each iteration fills them automatically with a float(‘NaN’) value before the end user code has a chance to do anything.

    如果您的策略/算法或简单的数据搜索只需要,例如收盘价,那么您可以不动其他人(每次迭代都会自动用float('NaN')值填充它们,最终用户代码才有机会做任何事情。

    In this example only a daily format is supported:

    在此示例中,仅支持每日格式:

    import itertools
    ...
    import backtrader as bt
    
    class MyCSVData(bt.CSVDataBase):
    
        def start(self):
            # Nothing to do for this data feed type
            pass
    
        def stop(self):
            # Nothing to do for this data feed type
            pass
    
        def _loadline(self, linetokens):
            i = itertools.count(0)
    
            dttxt = linetokens[next(i)]
            # Format is YYYY-MM-DD
            y = int(dttxt[0:4])
            m = int(dttxt[5:7])
            d = int(dttxt[8:10])
    
            dt = datetime.datetime(y, m, d)
            dtnum = date2num(dt)
    
            self.lines.datetime[0] = dtnum
            self.lines.open[0] = float(linetokens[next(i)])
            self.lines.high[0] = float(linetokens[next(i)])
            self.lines.low[0] = float(linetokens[next(i)])
            self.lines.close[0] = float(linetokens[next(i)])
            self.lines.volume[0] = float(linetokens[next(i)])
            self.lines.openinterest[0] = float(linetokens[next(i)])
    
            return True
    

     注意上面的代码,如果继承了重写了start与stop记得要调用父类该方法

    The code expects all fields to be in place and be convertible to floats, except for the datetime which has a fixed YYYY-MM-DD format and can be parsed without using datetime.datetime.strptime.

    代码要求所有字段都在适当的位置,并且可以转换为浮点,除了datetime,它具有固定的YYYY-MM-DD格式,可以不使用datetime.datetime.strptime.

    More complex needs can be covered by adding just a few lines of code to account for null values, date format parsing. The GenericCSVData does that.

    通过添加几行代码来解释空值、日期格式解析,可以满足更复杂的需求。GenericCSVData就是这样做的。

    Caveat Emptor

    Using the GenericCSVData existing feed and inheritance a lot can be acomplished in order to support formats.

    使用GenericCSVData现有的feed和继承,可以提供大量的格式支持。

    Let’s add support for Sierra Chart daily format (which is always stored in CSV format).

    Definition (by looking into one of the ‘.dly’ data files:

    • Fields: Date, Open, High, Low, Close, Volume, OpenInterest

      The industry standard ones and the ones already supported by GenericCSVData in the same order (which is also industry standard)

    • Separator: ,

    • Date Format: YYYY/MM/DD

    A parser for those files:

    解析这些文件:

    class SierraChartCSVData(backtrader.feeds.GenericCSVData):
    
        params = (('dtformat', '%Y/%m/%d'),)
    

    The params definition simply redefines one of the existing parameters in the base class. In this case just the formatting string for dates needs a change.

    params定义只是重新定义基类中的一个现有参数。在这种情况下,只需要更改日期的格式字符串

    Et voilá … the parser for Sierra Chart is finished.

    Sierra Chart的分析就完成了

    Here below the parameters definition of GenericCSVData as a reminder:

     下面是genericsvdata的参数定义,作为参考:
    class GenericCSVData(feed.CSVDataBase):
        params = (
            ('nullvalue', float('NaN')),
            ('dtformat', '%Y-%m-%d %H:%M:%S'),
            ('tmformat', '%H:%M:%S'),
    
            ('datetime', 0),
            ('time', -1),
            ('open', 1),
            ('high', 2),
            ('low', 3),
            ('close', 4),
            ('volume', 5),
            ('openinterest', 6),
        )
    
     
     
     

     

  • 相关阅读:
    c++单例模式为什么不在析构函数中释放静态的单例对象(转)
    Ubuntu 树莓派2b交叉编译环境
    多线程std::cout 深入研究
    c++11的 move并没有实际move
    RTC时间设置
    QT 第三方串口库COM10以上无法读取问题
    ubuntu gcc-5 安装
    STM32正交编码器驱动电机
    (转)layoutSubviews总结
    自定义视图控制器切换(iOS)
  • 原文地址:https://www.cnblogs.com/sidianok/p/13476570.html
Copyright © 2020-2023  润新知