Импорт CSV файлов из Quik в backtrader

К сожалению, в торговой системе QUIK отсутствует тестировщик стратегий, наподобие Metatrader. Поэтому приходится искать отдельную программу. Конечно, платные типа Amibroker, WealthLab очень даже удобны… но цена. Да и месяца триала не хватит для того чтобы понять, стоит продолжать торговать на рынках или найти новое увлечение.

Потому пошел на Гитхаб и стал серфить опенсоурсные и бесплатные аналоги тестеров стратегий. Их вполне хватает там. Некоторые сразу не пошли/не понравились, кое-что решил оставил на будущее ознакомление, а пока решил разобраться с Бэктрейдером на Питоне https://github.com/mementum/backtrader

Завелся сразу, правда из-за новой версии matplotlib отказался выводить графики (импорт warnings), но быстро нашлось решение. Обильная документация на английском языке, большое сообщество — все это убедило в долговечности проекта и что стоит потратить силы на его изучение.

Для ознакомления вполне хватит поставщиков или демо файлов в поставке. Но захотелось быть ближе к реальности и использовать котировки из QUIK.  Оказалось не сложно, если использовать формат csv, который можно получить с помощью QMinEditor. Написал скрипт quikcsv.py, поместил его в каталог \backtrader\feeds. Для теста использовал учебный пример с небольшой модификацией testQuik.py чтобы увидеть что импортируется (в моем случае TQBR_VTBR_15).

Итак, с помощью QMinEditor создаем желаемый архив с котировками (сразу возникает мысль, что со временем придется написать скрипт для «живого» импорта либо с помощью LUA либо сразу с файлов DAT, правда последнее не рекомендуется разработчиками Arqatech).

И результат работы

Не смотрите на разные тикеры, делал скрины в разное время.

Сами скрипты:

quikcsv.py

#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2020 Daniel Rodriguez
# Copyright (C) 2015-2020 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)


from . import GenericCSVData


class QUIKCSVData(GenericCSVData):
    '''
Парсит CSV подготовленный QMinEditor
    '''

    params = (
        ('dtformat', '%Y%m%d'),
        ('tmformat', '%H%M%S'),
        ('datetime', 2),
        ('time',  3),
        ('open',  4),
        ('high',  5),
        ('low',   6),
        ('close', 7),
        ('volume', 8),
        ('openinterest',-1),
    )

 

testQuik.py

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import datetime  # For datetime objects
import os.path  # To manage paths
import sys  # To find out the script name (in argv[0])

# Import the backtrader platform
import backtrader as bt
import backtrader.feeds.quikcsv as quikcsv

# Create a Stratey
class TestStrategy(bt.Strategy):

    def __init__(self):
        # Keep a reference to the "close"... line in the data[0] dataseries
        self.O = self.datas[0].open
        self.H = self.datas[0].high
        self.L = self.datas[0].low
        self.C = self.datas[0].close
        self.V= self.datas[0].volume

    def next(self):
         print('%s O %.6f, H %.6f, L %.6f, C %.6f, V %.6f' % (bt.num2date(self.datas[0].datetime[0]).strftime("%Y-%m-%d %H:%M"),
          self.O[0],self.H[0],self.L[0],self.C[0],self.V[0]))

if __name__ == '__main__':
    # Create a cerebro entity
    cerebro = bt.Cerebro()

    # Add a strategy
    cerebro.addstrategy(TestStrategy)

    # Datas are in a subfolder of the samples. Need to find where the script is
    # because it could have been called from anywhere
    modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
    print (modpath)
    datapath = os.path.join(modpath, 'datas/TQBR_VTBR_15.txt')

    # Create a Data Feed
    data = quikcsv.QUIKCSVData(
        dataname=datapath,
        # Do not pass values before this date
        #fromdate=datetime.datetime(2000, 1, 1),
        # Do not pass values before this date
        #todate=datetime.datetime(2000, 12, 31),
        # Do not pass values after this date
        reverse=False)

    # Add the Data Feed to Cerebro
    cerebro.adddata(data)

    # Set our desired cash start
    cerebro.broker.setcash(100000.0)

    # Print out the starting conditions
    print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())

    # Run over everything
    cerebro.run()

    # Print out the final result
    print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())

 

Комментирование и размещение ссылок запрещено.

Комментарии закрыты.