オープンソースの定量的フレームワークバックトレーダーFAQ:sqliteデータフィードの開発

ここで完全な技術チュートリアルを参照してください

多くの人々は、戦略的な使用のためにローカルデータベースからバックトレーダーにデータを送信することを望んで、独自のローカルマーケットデータベースを確立しています。一般的な方法は、データベースの市場データをパンダのデータフレームに読み込み、このデータフレームのデータをバックトレーダーのパンダのフィードデータオブジェクトに渡して、戦略を使用できるようにすることです。

ただし、一部の学生はパンダのデータフレームを介して転送することを望まず、データベースからバックトレーダーのデータフィードオブジェクトにデータを直接フィードしたいため、データベース用の特別なデータフィードクラスを開発する必要があります。

前回の記事では、MySQLデータベースのデータフィードを開発する方法を紹介しました。この記事では、sqliteデータベースのデータフィードの開発を紹介します。

以下は、sqliteデータベースからデータを読み取るためにバックトレーダーコミュニティによって提供されるフィードクラスSQLiteDataです。試してみることができます。

import datetime as dt
from backtrader import TimeFrame
from backtrader.feed import DataBase
from backtrader import date2num


class SQLiteData(DataBase):
    '''
    Fetches data from SQLite, and wraps it into a Feed consumable by cerebro
    takes url connection string in form of :
        sqlite://{database}

    this implementation assumes a single table (historical_data) with all prices,
    conforming to a schema similar to the following:

            symbol        TEXT,
            date          TEXT (YYYY-mm-dd HH:mm),
            open          REAL,
            high          REAL,
            low           REAL,
            close         REAL,
            volume        INTEGER,
            unique (symbol, date)

    if your databases are set up differently, you can override the
    start() method.
    '''

    params = (
        ('database', None),
        ('symbol', 'XBTUSD'),
        ('tick_value', 0.01),
        ('timeframe ', TimeFrame.Minutes),
        ('compression', 1),
        ('fromdate', dt.datetime(1900, 1, 1)),
        ('todate', dt.datetime.max),

        # parameterized column indices for ease of overwriting/re-implementing
        ('datetime', 0),
        ('open', 1),
        ('high', 2),
        ('low', 3),
        ('close', 4),
        ('volume', 5),
        ('openinterest', -1),
    )

    def __init__(self):
        self._timeframe = self.p.timeframe
        self._compression = self.p.compression
        self._dataname = '{0}-{1:.2f}'.format(self.p.symbol, self.p.tick_value)

    def start(self):
        super(SQLiteData, self).start()
        self.biter = None
        self.preloaded = False

    def _preload(self):
        engine = self._connect_db()

        sql_query = "SELECT `date`,`open`,`high`,`low`,`close`,`volume` FROM `historical_data` WHERE `symbol` = '" + self.p.symbol + "' AND `date` between '" + self.p.fromdate.strftime(
            "%Y-%m-%d %H:%M:%S") + "' and '" + self.p.todate.strftime("%Y-%m-%d %H:%M:%S") + "' ORDER BY `date` ASC"

        result = engine.execute(sql_query)
        dbars = result.fetchall()
        result.close()

        self.biter = iter(dbars)

    def preload(self):
        if not self.biter:
            self._preload()

        while self.load():
            pass

        self._last()
        self.home()

        self.biter = None
        self.preloaded = True

    def _load(self):
        if self.preloaded:
            return False

        if not self.biter:
            self._preload()

        try:
            bar = next(self.biter)
        except StopIteration:
            return False

        for field in self.getlinealiases():
            if field == 'datetime':
                self.lines.datetime[0] = date2num(dt.datetime.strptime(bar[self.p.datetime], '%Y-%m-%d %H:%M:%S'))
            elif field == 'volume':
                self.lines.volume[0] = bar[self.p.volume]
            else:
                # get the column index
                colidx = getattr(self.params, field)
                if colidx < 0:
                # column not present -- skip
                    continue

                # get the line to be set
                line = getattr(self.lines, field)
                line[0] = float(bar[colidx])

        return True


    def _connect_db(self):
        from sqlalchemy import create_engine
        url = 'sqlite:///{0}'.format(self.p.database)
        engine = create_engine(url, echo=False)
        return engine

 

3時間前に投稿

おすすめ

転載: blog.csdn.net/qtbgo/article/details/111354587