#
# Python Module with Class
# for Vectorized Backtesting
# of Momentum-based Strategies
#
# Python for Algorithmic Trading
# (c) Dr. Yves J. Hilpisch
# The Python Quants GmbH
#
from MomVectorBacktester import *


class MRVectorBacktester(MomVectorBacktester):
    ''' Class for the vectorized backtesting of
    Mean Reversion-based trading strategies.

    Attributes
    ==========
    symbol: str
        Google Finance symbol with which to work with
    start: str
        start date for data retrieval
    end: str
        end date for data retrieval
    amount: int, float
        amount to be invested at the beginning
    tc: float
        proportional transaction costs (e.g. 0.5% = 0.005) per trade

    Methods
    =======
    get_data:
        retrieves and prepares the base data set
    run_strategy:
        runs the backtest for the mean reversion-based strategy
    plot_results:
        plots the performance of the strategy compared to the symbol
    '''

    def run_strategy(self, SMA, threshold):
        ''' Backtests the trading strategy.
        '''
        data = self.data.copy()
        data['sma'] = data['price'].rolling(SMA).mean()
        data['distance'] = data['price'] - data['sma']
        # sell signals
        data['position'] = np.where(data['distance'] > threshold, -1, np.nan)
        # buy signals
        data['position'] = np.where(data['distance'] < -threshold,
                                    1, data['position'])
        # crossing of current price and SMA (zero distance)
        data['position'] = np.where(data['distance'] *
                                    data['distance'].shift(1) < 0,
                                    0, data['position'])
        data['position'] = data['position'].ffill().fillna(0)
        data['strategy'] = data['position'].shift(1) * data['return']
        # determine when a trade takes place
        trades = data['position'].diff().fillna(0) != 0
        # subtract transaction costs from return when trade takes place
        data['strategy'][trades] -= self.tc
        data['creturns'] = self.amount * data['return'].cumsum().apply(np.exp)
        data['cstrategy'] = self.amount * \
            data['strategy'].cumsum().apply(np.exp)
        self.results = data
        # absolute performance of the strategy
        aperf = self.results['cstrategy'].ix[-1]
        # out-/underperformance of strategy
        operf = aperf - self.results['creturns'].ix[-1]
        return round(aperf, 2), round(operf, 2)


if __name__ == '__main__':
    mrbt = MRVectorBacktester('GLD', '2010-1-1', '2016-10-31', 10000, 0.0)
    print(mrbt.run_strategy(SMA=50, threshold=10))
    mrbt = MRVectorBacktester('GLD', '2010-1-1', '2016-10-31', 10000, 0.0025)
    print(mrbt.run_strategy(SMA=50, threshold=10))
    mrbt = MRVectorBacktester('GDX', '2010-1-1', '2016-10-31', 10000, 0.0025)
    print(mrbt.run_strategy(SMA=50, threshold=5))

56d7bc93cbc8f440b546361885c413cfcd8090a4
<mask token>


class MRVectorBacktester(MomVectorBacktester):
    <mask token>

    def run_strategy(self, SMA, threshold):
        """ Backtests the trading strategy.
        """
        data = self.data.copy()
        data['sma'] = data['price'].rolling(SMA).mean()
        data['distance'] = data['price'] - data['sma']
        data['position'] = np.where(data['distance'] > threshold, -1, np.nan)
        data['position'] = np.where(data['distance'] < -threshold, 1, data[
            'position'])
        data['position'] = np.where(data['distance'] * data['distance'].
            shift(1) < 0, 0, data['position'])
        data['position'] = data['position'].ffill().fillna(0)
        data['strategy'] = data['position'].shift(1) * data['return']
        trades = data['position'].diff().fillna(0) != 0
        data['strategy'][trades] -= self.tc
        data['creturns'] = self.amount * data['return'].cumsum().apply(np.exp)
        data['cstrategy'] = self.amount * data['strategy'].cumsum().apply(np
            .exp)
        self.results = data
        aperf = self.results['cstrategy'].ix[-1]
        operf = aperf - self.results['creturns'].ix[-1]
        return round(aperf, 2), round(operf, 2)


<mask token>

<mask token>


class MRVectorBacktester(MomVectorBacktester):
    """ Class for the vectorized backtesting of
    Mean Reversion-based trading strategies.

    Attributes
    ==========
    symbol: str
        Google Finance symbol with which to work with
    start: str
        start date for data retrieval
    end: str
        end date for data retrieval
    amount: int, float
        amount to be invested at the beginning
    tc: float
        proportional transaction costs (e.g. 0.5% = 0.005) per trade

    Methods
    =======
    get_data:
        retrieves and prepares the base data set
    run_strategy:
        runs the backtest for the mean reversion-based strategy
    plot_results:
        plots the performance of the strategy compared to the symbol
    """

    def run_strategy(self, SMA, threshold):
        """ Backtests the trading strategy.
        """
        data = self.data.copy()
        data['sma'] = data['price'].rolling(SMA).mean()
        data['distance'] = data['price'] - data['sma']
        data['position'] = np.where(data['distance'] > threshold, -1, np.nan)
        data['position'] = np.where(data['distance'] < -threshold, 1, data[
            'position'])
        data['position'] = np.where(data['distance'] * data['distance'].
            shift(1) < 0, 0, data['position'])
        data['position'] = data['position'].ffill().fillna(0)
        data['strategy'] = data['position'].shift(1) * data['return']
        trades = data['position'].diff().fillna(0) != 0
        data['strategy'][trades] -= self.tc
        data['creturns'] = self.amount * data['return'].cumsum().apply(np.exp)
        data['cstrategy'] = self.amount * data['strategy'].cumsum().apply(np
            .exp)
        self.results = data
        aperf = self.results['cstrategy'].ix[-1]
        operf = aperf - self.results['creturns'].ix[-1]
        return round(aperf, 2), round(operf, 2)


<mask token>

<mask token>


class MRVectorBacktester(MomVectorBacktester):
    """ Class for the vectorized backtesting of
    Mean Reversion-based trading strategies.

    Attributes
    ==========
    symbol: str
        Google Finance symbol with which to work with
    start: str
        start date for data retrieval
    end: str
        end date for data retrieval
    amount: int, float
        amount to be invested at the beginning
    tc: float
        proportional transaction costs (e.g. 0.5% = 0.005) per trade

    Methods
    =======
    get_data:
        retrieves and prepares the base data set
    run_strategy:
        runs the backtest for the mean reversion-based strategy
    plot_results:
        plots the performance of the strategy compared to the symbol
    """

    def run_strategy(self, SMA, threshold):
        """ Backtests the trading strategy.
        """
        data = self.data.copy()
        data['sma'] = data['price'].rolling(SMA).mean()
        data['distance'] = data['price'] - data['sma']
        data['position'] = np.where(data['distance'] > threshold, -1, np.nan)
        data['position'] = np.where(data['distance'] < -threshold, 1, data[
            'position'])
        data['position'] = np.where(data['distance'] * data['distance'].
            shift(1) < 0, 0, data['position'])
        data['position'] = data['position'].ffill().fillna(0)
        data['strategy'] = data['position'].shift(1) * data['return']
        trades = data['position'].diff().fillna(0) != 0
        data['strategy'][trades] -= self.tc
        data['creturns'] = self.amount * data['return'].cumsum().apply(np.exp)
        data['cstrategy'] = self.amount * data['strategy'].cumsum().apply(np
            .exp)
        self.results = data
        aperf = self.results['cstrategy'].ix[-1]
        operf = aperf - self.results['creturns'].ix[-1]
        return round(aperf, 2), round(operf, 2)


if __name__ == '__main__':
    mrbt = MRVectorBacktester('GLD', '2010-1-1', '2016-10-31', 10000, 0.0)
    print(mrbt.run_strategy(SMA=50, threshold=10))
    mrbt = MRVectorBacktester('GLD', '2010-1-1', '2016-10-31', 10000, 0.0025)
    print(mrbt.run_strategy(SMA=50, threshold=10))
    mrbt = MRVectorBacktester('GDX', '2010-1-1', '2016-10-31', 10000, 0.0025)
    print(mrbt.run_strategy(SMA=50, threshold=5))

from MomVectorBacktester import *


class MRVectorBacktester(MomVectorBacktester):
    """ Class for the vectorized backtesting of
    Mean Reversion-based trading strategies.

    Attributes
    ==========
    symbol: str
        Google Finance symbol with which to work with
    start: str
        start date for data retrieval
    end: str
        end date for data retrieval
    amount: int, float
        amount to be invested at the beginning
    tc: float
        proportional transaction costs (e.g. 0.5% = 0.005) per trade

    Methods
    =======
    get_data:
        retrieves and prepares the base data set
    run_strategy:
        runs the backtest for the mean reversion-based strategy
    plot_results:
        plots the performance of the strategy compared to the symbol
    """

    def run_strategy(self, SMA, threshold):
        """ Backtests the trading strategy.
        """
        data = self.data.copy()
        data['sma'] = data['price'].rolling(SMA).mean()
        data['distance'] = data['price'] - data['sma']
        data['position'] = np.where(data['distance'] > threshold, -1, np.nan)
        data['position'] = np.where(data['distance'] < -threshold, 1, data[
            'position'])
        data['position'] = np.where(data['distance'] * data['distance'].
            shift(1) < 0, 0, data['position'])
        data['position'] = data['position'].ffill().fillna(0)
        data['strategy'] = data['position'].shift(1) * data['return']
        trades = data['position'].diff().fillna(0) != 0
        data['strategy'][trades] -= self.tc
        data['creturns'] = self.amount * data['return'].cumsum().apply(np.exp)
        data['cstrategy'] = self.amount * data['strategy'].cumsum().apply(np
            .exp)
        self.results = data
        aperf = self.results['cstrategy'].ix[-1]
        operf = aperf - self.results['creturns'].ix[-1]
        return round(aperf, 2), round(operf, 2)


if __name__ == '__main__':
    mrbt = MRVectorBacktester('GLD', '2010-1-1', '2016-10-31', 10000, 0.0)
    print(mrbt.run_strategy(SMA=50, threshold=10))
    mrbt = MRVectorBacktester('GLD', '2010-1-1', '2016-10-31', 10000, 0.0025)
    print(mrbt.run_strategy(SMA=50, threshold=10))
    mrbt = MRVectorBacktester('GDX', '2010-1-1', '2016-10-31', 10000, 0.0025)
    print(mrbt.run_strategy(SMA=50, threshold=5))

#
# Python Module with Class
# for Vectorized Backtesting
# of Momentum-based Strategies
#
# Python for Algorithmic Trading
# (c) Dr. Yves J. Hilpisch
# The Python Quants GmbH
#
from MomVectorBacktester import *


class MRVectorBacktester(MomVectorBacktester):
    ''' Class for the vectorized backtesting of
    Mean Reversion-based trading strategies.

    Attributes
    ==========
    symbol: str
        Google Finance symbol with which to work with
    start: str
        start date for data retrieval
    end: str
        end date for data retrieval
    amount: int, float
        amount to be invested at the beginning
    tc: float
        proportional transaction costs (e.g. 0.5% = 0.005) per trade

    Methods
    =======
    get_data:
        retrieves and prepares the base data set
    run_strategy:
        runs the backtest for the mean reversion-based strategy
    plot_results:
        plots the performance of the strategy compared to the symbol
    '''

    def run_strategy(self, SMA, threshold):
        ''' Backtests the trading strategy.
        '''
        data = self.data.copy()
        data['sma'] = data['price'].rolling(SMA).mean()
        data['distance'] = data['price'] - data['sma']
        # sell signals
        data['position'] = np.where(data['distance'] > threshold, -1, np.nan)
        # buy signals
        data['position'] = np.where(data['distance'] < -threshold,
                                    1, data['position'])
        # crossing of current price and SMA (zero distance)
        data['position'] = np.where(data['distance'] *
                                    data['distance'].shift(1) < 0,
                                    0, data['position'])
        data['position'] = data['position'].ffill().fillna(0)
        data['strategy'] = data['position'].shift(1) * data['return']
        # determine when a trade takes place
        trades = data['position'].diff().fillna(0) != 0
        # subtract transaction costs from return when trade takes place
        data['strategy'][trades] -= self.tc
        data['creturns'] = self.amount * data['return'].cumsum().apply(np.exp)
        data['cstrategy'] = self.amount * \
            data['strategy'].cumsum().apply(np.exp)
        self.results = data
        # absolute performance of the strategy
        aperf = self.results['cstrategy'].ix[-1]
        # out-/underperformance of strategy
        operf = aperf - self.results['creturns'].ix[-1]
        return round(aperf, 2), round(operf, 2)


if __name__ == '__main__':
    mrbt = MRVectorBacktester('GLD', '2010-1-1', '2016-10-31', 10000, 0.0)
    print(mrbt.run_strategy(SMA=50, threshold=10))
    mrbt = MRVectorBacktester('GLD', '2010-1-1', '2016-10-31', 10000, 0.0025)
    print(mrbt.run_strategy(SMA=50, threshold=10))
    mrbt = MRVectorBacktester('GDX', '2010-1-1', '2016-10-31', 10000, 0.0025)
    print(mrbt.run_strategy(SMA=50, threshold=5))
