# -*- coding: utf-8 -*-

import logging
import backtrader as bt
import pandas as pd
import utils
import collections
import talib
import sys


def get_ts_stock_period_hq_df(stock, begin_date_str, end_date_str, cycle='日'):
    begin_date = utils.str_to_ts_date(begin_date_str)
    end_date = utils.str_to_ts_date(end_date_str)
    # 交易所算法，前复权
    stock_daily_data = utils.ts_remote_call_func('Stock_PeriodHq', [begin_date, end_date, cycle, 2, 0], {
        'StockID': stock
    })
    row_size = len(stock_daily_data)
    if row_size == 0:
        return None
    stock_daily_data.reverse()  # 天软查询接口是倒序，转换成按照时间先后排序，日期小的排前面
    return utils.ts_list_to_dataframe(
        ts_list=stock_daily_data,
        columns=[('datetime', '日期'), ('open', '开盘'), ('close', '收盘'), ('high', '最高'), ('low', '最低'),
                 ('p_change', '涨幅(%)'), ('volume', '成交量(手)'), ('turnover', '换手率(%)')],
        index_type=pd.DatetimeIndex
    )



class OHLCSecondData(bt.feeds.PandasData):
    """
    通常包含OCHL，根据需要追加
    """
    lines = ('open', 'close', 'high', 'low', 'CCI')
    params = (
        ('datetime', None),
        ('open', -1),
        ('high', -1),
        ('close', -1),
        ('low', -1),
        ('CCI', -1)
    )
    datafields = [x[0] for x in params]

    def __init__(self):
        super(OHLCSecondData, self).__init__()


class DailyCCIStrategy(bt.Strategy):

    def __init__(self, max_t_per_day=4):
        self.max_t_per_day = max_t_per_day
        self.cci = bt.talib.CCI(self.data.high, self.data.low, self.data.close, timeperiod=7)

    def start(self):
        pass

    def next(self):
        pass

    def end(self):
        pass


if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)

    # 为确保后期的扩展性，本次运行的全部参数，请在此声明
    params = dict(
        start_date_str='2012-01-01',
        end_date_str='2017-06-01',
        cash=100000.0,
        commission=0.0016,  # 手续费，买入、卖出单次一般0.0003，卖出还有印花税0.001，加起来估算0.0016
    )
    stock = 'SZ002415'
    df = get_ts_stock_period_hq_df(stock, params['start_date_str'], params['end_date_str'])

    cerebro = bt.Cerebro()
    cerebro.adddata(OHLCSecondData(dataname=df))    # 添加数据，用DataFrame替换None
    cerebro.addstrategy(DailyCCIStrategy)
    cerebro.broker.setcash(params['cash'])
    cerebro.broker.setcommission(commission=params['commission'])
    cerebro.run()
    cerebro.plot(style='candle')
