コード例 #1
0
class CryptoBacktest:
    """
    Attributes:
        data: the full dataframe to backtest
        strategies: list of `Strategy` instances to test
        broker: `Broker` instance to trade on the data
    """

    def __init__(self, data):
        """
        TODO: Abstract this from USD and BTC specific accounts

        :param data: dataframe to run backtest on
        """

        self.data = data
        self.strategies = []

        usd_account = Account('USD', 1000)
        btc_account = Account('BTC', 0, 'Close')
        self.broker = Broker(data, [usd_account, btc_account])


    def add_strategy(self, strategy):
        """
        :param strategy: strategy to add to the backtest
        """

        strategy.add_broker(self.broker)
        strategy.add_data(self.data)
        strategy.initialize()

        self.strategies.append(strategy)


    def run(self):
        """
        """

        logger.info('Running strategies...')

        # Run strategies on data
        for index, row in self.data.iterrows():
            self.broker.handle_data(index)

            for strategy in self.strategies:
                strategy.handle_data_wrapper(index)

        logger.info('Calculating metrics...')

        self.broker.calculate_metrics()


    def plot(self):
        """
        TODO: Share X axis with Candlesticks and account data
        """

        account_subplots = self.broker.accounts_df.shape[1]
        data_subplots = 2

        total_rows = account_subplots + data_subplots

        data_ratio = total_rows * 5 / 8
        volume_ratio = total_rows / 8
        account_ratio = total_rows / (4 * account_subplots)
        height_ratios = [data_ratio, volume_ratio] + [account_ratio] * account_subplots

        fig, axes = plt.subplots(
            nrows=total_rows,
            #sharex=True,
            gridspec_kw = {'height_ratios': height_ratios}
        )

        candlestick_ohlc(axes[0], list(zip(
            self.data.index.astype(np.int64) // 10**9,
            self.data['Open'].values,
            self.data['High'].values,
            self.data['Low'].values,
            self.data['Close'].values,
        )), width=32, colorup='g')

        axes[0].xaxis.set_major_locator(MinuteLocator())
        axes[0].xaxis.set_major_formatter(DateFormatter('%Y-%m-%d %H:%i'))

        try:
            self.data['Volume'].plot(ax=axes[1], legend=True)
        except KeyError:
            pass

        self.broker.plot(axes, data_subplots)

        plt.show()