Esempio n. 1
0
def construct_backtest(ticker, vendor_ticker, sma_period, data_source, start_date, quandl_api_key):
    backtest = Backtest()
    br = BacktestRequest()

    # Set all the parameters for the backtest
    br.start_date = start_date
    br.finish_date = datetime.datetime.utcnow()
    br.spot_tc_bp = 2.5  # 2.5 bps bid/ask spread
    br.ann_factor = 252

    tech_params = TechParams()
    tech_params.sma_period = sma_period
    indicator = 'SMA'

    md_request = MarketDataRequest(
        start_date=start_date,
        finish_date=datetime.date.today(),
        freq='daily',
        data_source=data_source,
        tickers=ticker,
        fields=['close'],
        vendor_tickers=vendor_ticker,
        quandl_api_key=quandl_api_key)

    market = Market(market_data_generator=MarketDataGenerator())

    # Download the market data (the asset we are trading is also
    # being used to generate the signal)
    asset_df = market.fetch_market(md_request)
    spot_df = asset_df

    # Use technical indicator to create signals
    # (we could obviously create whatever function we wanted for generating the signal dataframe)
    # However, finmarketpy has some technical indicators built in (and some signals too)
    tech_ind = TechIndicator()
    tech_ind.create_tech_ind(spot_df, indicator, tech_params);
    signal_df = tech_ind.get_signal()

    # use the same data for generating signals
    backtest.calculate_trading_PnL(br, asset_df, signal_df, None, False)

    # Get the returns and signals for the portfolio
    port = backtest.portfolio_cum()
    port.columns = [indicator + ' = ' + str(tech_params.sma_period) + ' ' + str(backtest.portfolio_pnl_desc()[0])]
    signals = backtest.portfolio_signal()
    # returns = backtest.pnl()

    return port, signals
    def __init__(self):
        super(MarketDataRequest, self).__init__()
        self.logger = LoggerManager().getLogger(__name__)

        self.__signal_name = None

        # output parameters for backtest (should we add returns statistics on legends, write CSVs with returns etc.)
        self.__plot_start = None
        self.__calc_stats = True
        self.__write_csv = False
        self.__write_csv_pnl = False
        self.__plot_interim = False
        self.__include_benchmark = False

        self.__tech_params = TechParams()

        # default parameters for portfolio level vol adjustment
        self.__portfolio_vol_adjust = False
        self.__portfolio_vol_period_shift = 0
        self.__portfolio_vol_rebalance_freq = None
        self.__portfolio_vol_resample_freq = None
        self.__portfolio_vol_resample_type = 'mean'
        self.__portfolio_vol_target = 0.1           # 10% vol target
        self.__portfolio_vol_max_leverage = None
        self.__portfolio_vol_periods = 20
        self.__portfolio_vol_obs_in_year = 252

        # default parameters for signal level vol adjustment
        self.__signal_vol_adjust = False
        self.__signal_vol_period_shift = 0
        self.__signal_vol_rebalance_freq = None
        self.__signal_vol_resample_freq = None      
        self.__signal_vol_resample_type = 'mean'
        self.__signal_vol_target = 0.1              # 10% vol target
        self.__signal_vol_max_leverage = None
        self.__signal_vol_periods = 20
        self.__signal_vol_obs_in_year = 252

        # portfolio notional size
        self.__portfolio_notional_size = None
        self.__portfolio_combination = None
        self.__portfolio_combination_weights = None
        
        # parameters for maximum position limits (expressed as whole portfolio)
        self.__max_net_exposure = None
        self.__max_abs_exposure = None

        self.__position_clip_rebalance_freq = None
        self.__position_clip_resample_freq = None  # by default apply max position criterion on last business day of month
        self.__position_clip_resample_type = 'mean'
        self.__position_clip_period_shift = 0

        # take profit and stop loss parameters
        self.__take_profit = None
        self.__stop_loss = None

        # should we delay the signal?
        self.__signal_delay = 0
Esempio n. 3
0
    def __init__(self):
        super(MarketDataRequest, self).__init__()

        self.__signal_name = None

        # output parameters for backtest (should we add returns statistics on legends, write CSVs with returns etc.)
        self.__plot_start = None
        self.__calc_stats = True
        self.__write_csv = False
        self.__write_csv_pnl = False
        self.__plot_interim = False
        self.__include_benchmark = False

        self.__tech_params = TechParams()

        # default parameters for portfolio level vol adjustment
        self.__portfolio_vol_adjust = False
        self.__portfolio_vol_period_shift = 0
        self.__portfolio_vol_rebalance_freq = None
        self.__portfolio_vol_resample_freq = None
        self.__portfolio_vol_resample_type = 'mean'
        self.__portfolio_vol_target = 0.1  # 10% vol target
        self.__portfolio_vol_max_leverage = None
        self.__portfolio_vol_periods = 20
        self.__portfolio_vol_obs_in_year = 252

        # default parameters for signal level vol adjustment
        self.__signal_vol_adjust = False
        self.__signal_vol_period_shift = 0
        self.__signal_vol_rebalance_freq = None
        self.__signal_vol_resample_freq = None
        self.__signal_vol_resample_type = 'mean'
        self.__signal_vol_target = 0.1  # 10% vol target
        self.__signal_vol_max_leverage = None
        self.__signal_vol_periods = 20
        self.__signal_vol_obs_in_year = 252

        # portfolio notional size
        self.__portfolio_notional_size = None
        self.__portfolio_combination = None
        self.__portfolio_combination_weights = None

        # parameters for maximum position limits (expressed as whole portfolio)
        self.__max_net_exposure = None
        self.__max_abs_exposure = None

        self.__position_clip_rebalance_freq = None
        self.__position_clip_resample_freq = None  # by default apply max position criterion on last business day of month
        self.__position_clip_resample_type = 'mean'
        self.__position_clip_period_shift = 0

        # take profit and stop loss parameters
        self.__take_profit = None
        self.__stop_loss = None

        # should we delay the signal?
        self.__signal_delay = 0

        # annualization factor for return stats (and should we resample data first before calculating it?)
        self.__ann_factor = 252
        self.__resample_ann_factor = None

        # how do we create a cumulative index of strategy returns
        # either multiplicative starting a 100
        # or additive starting at 0
        self.__cum_index = 'mult'  # 'mult' or 'add'
Esempio n. 4
0
    def construct_strategy(self, br=None):
        """
        construct_strategy - Constructs the returns for all the strategies which have been specified.

        - gets parameters form fill_backtest_request
        - market data from fill_assets

        """

        calculations = Calculations()

        # get the parameters for backtesting
        if hasattr(self, 'br'):
            br = self.br
        elif br is None:
            br = self.load_parameters()

        # get market data for backtest
        asset_df, spot_df, spot_df2, basket_dict = self.load_assets()

        if hasattr(br, 'tech_params'):
            tech_params = br.tech_params
        else:
            tech_params = TechParams()

        cumresults = pandas.DataFrame(index=asset_df.index)
        portleverage = pandas.DataFrame(index=asset_df.index)

        from collections import OrderedDict
        ret_statsresults = OrderedDict()

        # each portfolio key calculate returns - can put parts of the portfolio in the key
        for key in basket_dict.keys():
            asset_cut_df = asset_df[[x + '.close' for x in basket_dict[key]]]
            spot_cut_df = spot_df[[x + '.close' for x in basket_dict[key]]]

            self.logger.info("Calculating " + key)

            results, backtest = self.construct_individual_strategy(
                br, spot_cut_df, spot_df2, asset_cut_df, tech_params, key)

            cumresults[results.columns[0]] = results
            portleverage[results.columns[0]] = backtest.get_porfolio_leverage()
            ret_statsresults[key] = backtest.get_portfolio_pnl_ret_stats()

            # for a key, designated as the final strategy save that as the "strategy"
            if key == self.FINAL_STRATEGY:
                self._strategy_pnl = results
                self._strategy_pnl_ret_stats = backtest.get_portfolio_pnl_ret_stats(
                )
                self._strategy_leverage = backtest.get_porfolio_leverage()
                self._strategy_signal = backtest.get_porfolio_signal()
                self._strategy_pnl_trades = backtest.get_pnl_trades()

        # get benchmark for comparison
        benchmark = self.construct_strategy_benchmark()

        cumresults_benchmark = self.compare_strategy_vs_benchmark(
            br, cumresults, benchmark)

        self._strategy_group_benchmark_ret_stats = ret_statsresults

        if hasattr(self, '_benchmark_ret_stats'):
            ret_statslist = ret_statsresults
            ret_statslist['Benchmark'] = (self._benchmark_ret_stats)
            self._strategy_group_benchmark_ret_stats = ret_statslist

        # calculate annualised returns
        years = calculations.average_by_annualised_year(
            calculations.calculate_returns(cumresults_benchmark))

        self._strategy_group_pnl = cumresults
        self._strategy_group_pnl_ret_stats = ret_statsresults
        self._strategy_group_benchmark_pnl = cumresults_benchmark
        self._strategy_group_leverage = portleverage
        self._strategy_group_benchmark_annualised_pnl = years
Esempio n. 5
0
    # get all asset data
    br.start_date = "02 Jan 1990"
    br.finish_date = datetime.datetime.utcnow()
    br.spot_tc_bp = 2.5                             # 2.5 bps bid/ask spread
    br.ann_factor = 252

    # have vol target for each signal
    br.signal_vol_adjust = True
    br.signal_vol_target = 0.05
    br.signal_vol_max_leverage = 3
    br.signal_vol_periods = 60
    br.signal_vol_obs_in_year = 252
    br.signal_vol_rebalance_freq = 'BM'
    br.signal_vol_resample_freq = None

    tech_params = TechParams(); tech_params.sma_period = 200; indicator = 'SMA'

    # pick USD crosses in G10 FX
    # note: we are calculating returns from spot (it is much better to use to total return
    # indices for FX, which include carry)
    logger.info("Loading asset data...")

    tickers = ['EURUSD', 'USDJPY', 'GBPUSD', 'AUDUSD', 'USDCAD',
               'NZDUSD', 'USDCHF', 'USDNOK', 'USDSEK']

    vendor_tickers = ['FRED/DEXUSEU', 'FRED/DEXJPUS', 'FRED/DEXUSUK', 'FRED/DEXUSAL', 'FRED/DEXCAUS',
                      'FRED/DEXUSNZ', 'FRED/DEXSZUS', 'FRED/DEXNOUS', 'FRED/DEXSDUS']

    md_request = MarketDataRequest(
                start_date = "01 Jan 1989",                     # start date
                finish_date = datetime.date.today(),            # finish date
Esempio n. 6
0
    # get all asset data
    br.start_date = "02 Jan 1990"
    br.finish_date = datetime.datetime.utcnow()
    br.spot_tc_bp = 2.5  # 2.5 bps bid/ask spread
    br.ann_factor = 252

    # have vol target for each signal
    br.signal_vol_adjust = True
    br.signal_vol_target = 0.05
    br.signal_vol_max_leverage = 3
    br.signal_vol_periods = 60
    br.signal_vol_obs_in_year = 252
    br.signal_vol_rebalance_freq = 'BM'
    br.signal_vol_resample_freq = None

    tech_params = TechParams()
    tech_params.sma_period = 200
    indicator = 'SMA'

    # pick USD crosses in G10 FX
    # note: we are calculating returns from spot (it is much better to use to total return
    # indices for FX, which include carry)
    logger.info("Loading asset data...")

    tickers = [
        'EURUSD', 'USDJPY', 'GBPUSD', 'AUDUSD', 'USDCAD', 'NZDUSD', 'USDCHF',
        'USDNOK', 'USDSEK'
    ]

    vendor_tickers = [
        'FRED/DEXUSEU', 'FRED/DEXJPUS', 'FRED/DEXUSUK', 'FRED/DEXUSAL',
Esempio n. 7
0
    def __init__(self):
        super(MarketDataRequest, self).__init__()
        self.logger = LoggerManager().getLogger(__name__)

        self.__signal_name = None
        self.__tech_params = TechParams()
Esempio n. 8
0
from finmarketpy.economics import TechIndicator, TechParams

from findatapy.util.loggermanager import LoggerManager


logger = LoggerManager().getLogger(__name__)

chart = Chart(engine='bokeh')

tech_ind = TechIndicator()
###### Simple example loading local data and using finmarketpy engine
# Load data from local file
df = pd.read_csv("/Volumes/Data/s&p500.csv", index_col=0, parse_dates=['Date'],
                 date_parser=lambda x: pd.datetime.strptime(x, '%Y-%m-%d'))

# Calculate Volume Weighted Average Price (VWAP)
tech_params = TechParams()
tech_ind.create_tech_ind(df, 'VWAP', tech_params)

df = tech_ind.get_techind()

print(df)

style = Style()
style.title = 'S&P500 VWAP'
style.scale_factor = 2

df = tech_ind.get_techind()

chart.plot(df, style=style)
Esempio n. 9
0
if run_example == 1 or run_example == 0:

    # Downloaded S&P500
    md_request = MarketDataRequest(
        start_date="01 Jan 2000",  # start date
        data_source='quandl',  # use Quandl as data source
        tickers=['S&P500'],
        fields=['close', 'open', 'high', 'low'],  # which fields to download
        vendor_tickers=['YAHOO/INDEX_GSPC'],  # ticker (Bloomberg)
        vendor_fields=['close', 'open', 'high',
                       'low'],  # which Bloomberg fields to download
        cache_algo='internet_load_return')  # how to return data

    df = market.fetch_market(md_request)

    print(df)

    tech_params = TechParams()
    tech_params.atr_period = 14
    tech_ind.create_tech_ind(df, 'ATR', tech_params)

    style = Style()

    style.title = 'S&P500 ATR'
    style.scale_factor = 2
    style.file_output = "sp500.png"
    style.source = 'Quandl/Yahoo'

    df = tech_ind.get_techind()

    chart.plot(df, style=style)
Esempio n. 10
0
###### fetch data from Quandl for BoE rate (using Bloomberg data)
if run_example == 1 or run_example == 0:

    # downloaded S&P500
    md_request = MarketDataRequest(
                start_date = "01 Jan 2000",                         # start date
                data_source = 'quandl',                             # use Quandl as data source
                tickers = ['S&P500'],
                fields = ['close', 'open', 'high', 'low'],          # which fields to download
                vendor_tickers = ['YAHOO/INDEX_GSPC'],              # ticker (Bloomberg)
                vendor_fields = ['close', 'open', 'high', 'low'],   # which Bloomberg fields to download
                cache_algo = 'internet_load_return')                # how to return data

    df = market.fetch_market(md_request)

    print(df)

    tech_params = TechParams()
    tech_params.atr_period = 14
    tech_ind.create_tech_ind(df, 'ATR', tech_params)

    style = Style()

    style.title = 'S&P500 ATR'
    style.scale_factor = 2
    style.file_output = "sp500.png"
    style.source = 'Quandl/Yahoo'

    df = tech_ind.get_techind()

    chart.plot(df, style=style)