### Install qf-lib from source Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/installation.rst Installs the qf-lib library directly from its source code. This method requires downloading the project repository and running the setup script. ```console $ python setup.py install ``` -------------------------------- ### Install Bloomberg Data Provider Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/installation.rst Installs the Bloomberg Data Provider using pip. Requires pip version 19.0 or higher on Linux and specifies a particular version of the blpapi. ```console $ pip install --index-url=https://bcms.bloomberg.com/pip/simple/ blpapi==3.20.1 ``` -------------------------------- ### Install Quandl Data Provider Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/installation.rst Installs the Quandl Data Provider using pip. Specifies a particular version of the quandl package. ```console $ pip install quandl==3.6.1 ``` -------------------------------- ### Sample Settings JSON Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/configuration.rst Provides an example structure for the main settings JSON file. This file holds general configuration parameters for QF-Lib applications. ```json { "some_setting": "value of that setting", "another_setting": "value of another setting", "some_connection_settings": { "username": "john.smith" } } ``` -------------------------------- ### Install qf-lib using pip Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/installation.rst Installs the qf-lib library using the pip package installer. This is the primary method for adding the library to your Python environment. ```console $ pip install qf-lib ``` -------------------------------- ### Start Trading and Subscribe to Strategy in QF-Lib Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_alpha_model.rst Demonstrates how to start the trading system and subscribe to a regular calculation and order placement event within the QF-Lib framework. This is a fundamental step for executing trading strategies. ```Python strategy.subscribe(CalculateAndPlaceOrdersRegularEvent) ts.start_trading() ``` -------------------------------- ### Install QF-Lib from source Source: https://github.com/quarkfin/qf-lib/blob/master/README.md Installs the qf-lib Python library directly from its source code. This method is useful for development or when installing a specific version not yet released on PyPI. It requires cloning the repository first. ```sh python setup.py install ``` -------------------------------- ### Backtest Setup and Execution (Python) Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_strategy_backtest.rst Configures and runs a backtest for the Intraday MA strategy. This includes setting backtest parameters like dates and tickers, configuring logging, defining event frequencies and timings, and building the backtesting session. ```python def main(): # settings backtest_name = 'Intraday MA Strategy Demo' start_date = str_to_date("2019-06-04") end_date = str_to_date("2019-10-17") ticker = DummyTicker("AAA") setup_logging(logging.INFO, console_logging=True) CalculateAndPlaceOrdersPeriodicEvent.set_frequency(Frequency.MIN_1) CalculateAndPlaceOrdersPeriodicEvent.set_start_and_end_time( {"hour": 10, "minute": 0}, {"hour": 13, "minute": 0}) # configuration settings = get_demo_settings() pdf_exporter = PDFExporter(settings) excel_exporter = ExcelExporter(settings) session_builder = BacktestTradingSessionBuilder(settings, pdf_exporter, excel_exporter) session_builder.set_frequency(Frequency.MIN_1) session_builder.set_market_open_and_close_time({"hour": 9, "minute": 15}, {"hour": 13, "minute": 15}) session_builder.set_backtest_name(backtest_name) session_builder.set_data_provider(intraday_data_provider) ts = session_builder.build(start_date, end_date) strategy = IntradayMAStrategy(ts, ticker) strategy.subscribe(CalculateAndPlaceOrdersPeriodicEvent) ts.start_trading() ``` -------------------------------- ### Install QF-Lib using pip Source: https://github.com/quarkfin/qf-lib/blob/master/README.md Installs the qf-lib Python package from the Python Package Index (PyPI) using the pip package installer. This is the standard method for installing Python libraries. ```sh pip install qf-lib ``` -------------------------------- ### Set Starting Directory (Absolute Path) Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/configuration.rst Sets the absolute path for the starting directory, which is used to resolve relative paths within the project. This is a fundamental step for many QF-Lib components. ```python set_starting_dir_abs_path("C:\\abs\\path\\to\\starting\\directory") ``` -------------------------------- ### Daily Backtesting Session Setup in Python Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_strategy_backtest.rst Sets up a daily backtesting trading session using BacktestTradingSessionBuilder. It configures the frequency to daily, sets a backtest name, and specifies a data provider. It also initializes PDF and Excel exporters. The session is then built for a specified date range, and a SimpleMAStrategy is subscribed to daily calculation events. ```python from qf_lib.backtesting.trading_session.backtest_trading_session_builder import BacktestTradingSessionBuilder from qf_lib.common.enums.frequency import Frequency from qf_lib.common.utils.dateutils.string_to_date import str_to_date from demo_scripts.common.utils.dummy_ticker import DummyTicker from demo_scripts.demo_configuration.demo_data_provider import daily_data_provider from demo_scripts.demo_configuration.demo_settings import get_demo_settings from qf_lib.documents_utils.document_exporting.pdf_exporter import PDFExporter from qf_lib.documents_utils.excel.excel_exporter import ExcelExporter from qf_lib.backtesting.events.quantfolio.calculate_and_place_orders_regular_event import CalculateAndPlaceOrdersRegularEvent def main(): # settings backtest_name = 'Simple MA Strategy Demo' start_date = str_to_date("2010-01-01") end_date = str_to_date("2015-03-01") ticker = DummyTicker("AAA") # configuration settings = get_demo_settings() pdf_exporter = PDFExporter(settings) excel_exporter = ExcelExporter(settings) session_builder = BacktestTradingSessionBuilder(settings, pdf_exporter, excel_exporter) session_builder.set_frequency(Frequency.DAILY) session_builder.set_backtest_name(backtest_name) session_builder.set_data_provider(daily_data_provider) ts = session_builder.build(start_date, end_date) strategy = SimpleMAStrategy(ts, ticker) CalculateAndPlaceOrdersRegularEvent.set_daily_default_trigger_time() CalculateAndPlaceOrdersRegularEvent.exclude_weekends() strategy.subscribe(CalculateAndPlaceOrdersRegularEvent) ts.start_trading() ``` -------------------------------- ### Configure and Run Backtest with Slippage in QF-Lib Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/customize_your_backtest.rst This Python code configures a trading session in QF-Lib by setting a daily data provider and applying price-based slippage with a maximum volume share limit. It then builds the session, initializes a SimpleMAStrategy, sets up order placement events, and starts the trading simulation. The backtest results are then displayed, showing performance metrics. ```python session_builder.set_data_provider(daily_data_provider) session_builder.set_slippage_model(PriceBasedSlippage, slippage_rate=0.001, max_volume_share_limit=0.15) ts = session_builder.build(start_date, end_date) strategy = SimpleMAStrategy(ts, ticker) CalculateAndPlaceOrdersRegularEvent.set_daily_default_trigger_time() CalculateAndPlaceOrdersRegularEvent.exclude_weekends() strategy.subscribe(CalculateAndPlaceOrdersRegularEvent) ts.start_trading() # Backtest results are displayed textually below, not in code. ``` -------------------------------- ### Add fixed basis points commission to daily backtest using qf-lib Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/customize_your_backtest.rst Applies a commission based on a fixed basis points (bps) rate of the trade's value. This example utilizes the `BpsTradeValueCommissionModel` and configures a daily backtest session with specific dates, ticker, and a commission rate of 2 bps. ```python from qf_lib.backtesting.execution_handler.commission_models.bps_trade_value_commission_model import \ BpsTradeValueCommissionModel def main(): # settings backtest_name = 'Simple MA Strategy Demo' start_date = str_to_date("2010-01-01") end_date = str_to_date("2015-03-01") ticker = DummyTicker("AAA") # configuration settings = get_demo_settings() pdf_exporter = PDFExporter(settings) excel_exporter = ExcelExporter(settings) session_builder = BacktestTradingSessionBuilder(settings, pdf_exporter, excel_exporter) session_builder.set_frequency(Frequency.DAILY) session_builder.set_backtest_name(backtest_name) session_builder.set_data_provider(daily_data_provider) session_builder.set_commission_model(BpsTradeValueCommissionModel, commission=2.0) ts = session_builder.build(start_date, end_date) strategy = SimpleMAStrategy(ts, ticker) CalculateAndPlaceOrdersRegularEvent.set_daily_default_trigger_time() CalculateAndPlaceOrdersRegularEvent.exclude_weekends() strategy.subscribe(CalculateAndPlaceOrdersRegularEvent) ts.start_trading() ``` -------------------------------- ### Build Backtest Trading Session with Default Position Sizer Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_alpha_model.rst This Python code demonstrates how to build a backtest trading session using default settings. It initializes a trading session with specified start and end dates, configures an alpha model, and subscribes to trading events. The default position sizer is used, which typically allocates a full portfolio value to trades based on signals. ```python from qf_lib.common.utils.dateutils.string_to_date import str_to_date def main(): start_date = str_to_date("2010-01-01") end_date = str_to_date("2015-03-01") settings = get_demo_settings() pdf_exporter = PDFExporter(settings) excel_exporter = ExcelExporter(settings) session_builder = BacktestTradingSessionBuilder(settings, pdf_exporter, excel_exporter) session_builder.set_frequency(Frequency.DAILY) session_builder.set_data_provider(daily_data_provider) ts = session_builder.build(start_date, end_date) model = MovingAverageAlphaModel(fast_time_period=5, slow_time_period=20, risk_estimation_factor=1.25, data_provider=ts.data_handler) model_tickers = [DummyTicker('AAA')] model_tickers_dict = {model: model_tickers} strategy = AlphaModelStrategy(ts, model_tickers_dict) CalculateAndPlaceOrdersRegularEvent.set_daily_default_trigger_time() CalculateAndPlaceOrdersRegularEvent.exclude_weekends() strategy.subscribe(CalculateAndPlaceOrdersRegularEvent) ts.start_trading() if __name__ == "__main__": main() ``` -------------------------------- ### Configure Backtest Session with Fixed Percentage Position Sizer Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_alpha_model.rst This Python code example shows how to set up a backtest trading session with a custom position sizer that allocates a fixed percentage of the portfolio value to each trade. It customizes the `BacktestTradingSessionBuilder` to use `FixedPortfolioPercentagePositionSizer` with a specified percentage. ```python def main(): start_date = str_to_date("2010-01-01") end_date = str_to_date("2015-03-01") settings = get_demo_settings() pdf_exporter = PDFExporter(settings) excel_exporter = ExcelExporter(settings) session_builder = BacktestTradingSessionBuilder(settings, pdf_exporter, excel_exporter) session_builder.set_frequency(Frequency.DAILY) session_builder.set_data_provider(daily_data_provider) session_builder.set_position_sizer(FixedPortfolioPercentagePositionSizer, fixed_percentage=0.2) ts = session_builder.build(start_date, end_date) model = MovingAverageAlphaModel(fast_time_period=5, slow_time_period=20, risk_estimation_factor=1.25, data_provider=ts.data_handler) model_tickers = [DummyTicker('AAA')] model_tickers_dict = {model: model_tickers} strategy = AlphaModelStrategy(ts, model_tickers_dict) CalculateAndPlaceOrdersRegularEvent.set_daily_default_trigger_time() CalculateAndPlaceOrdersRegularEvent.exclude_weekends() strategy.subscribe(CalculateAndPlaceOrdersRegularEvent) ts.start_trading() ``` -------------------------------- ### Configure Backtest Session with Initial Risk Position Sizer Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_alpha_model.rst This Python code snippet demonstrates configuring a backtest trading session to use the `InitialRiskPositionSizer`. This sizer determines order size based on a specified initial risk, which is often derived from a Signal's fraction at risk (e.g., ATR). The example sets an initial risk of 5%. ```python def main(): start_date = str_to_date("2010-01-01") end_date = str_to_date("2015-03-01") settings = get_demo_settings() pdf_exporter = PDFExporter(settings) excel_exporter = ExcelExporter(settings) session_builder = BacktestTradingSessionBuilder(settings, pdf_exporter, excel_exporter) session_builder.set_frequency(Frequency.DAILY) session_builder.set_data_provider(daily_data_provider) session_builder.set_position_sizer(InitialRiskPositionSizer, initial_risk=0.05) ts = session_builder.build(start_date, end_date) model = MovingAverageAlphaModel(fast_time_period=5, slow_time_period=20, risk_estimation_factor=1.25, data_provider=ts.data_handler) model_tickers = [DummyTicker('AAA'), DummyTicker('BBB')] model_tickers_dict = {model: model_tickers} strategy = AlphaModelStrategy(ts, model_tickers_dict) CalculateAndPlaceOrdersRegularEvent.set_daily_default_trigger_time() CalculateAndPlaceOrdersRegularEvent.exclude_weekends() strategy.subscribe(CalculateAndPlaceOrdersRegularEvent) ts.start_trading() ``` -------------------------------- ### Custom RegularTimeEvent with Daily Schedule - Python Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/reference/backtest_flow.rst An example of a custom RegularTimeEvent scheduled for every Monday at 8:15 a.m. It utilizes RegularDateTimeRule for time computations and defines methods for trigger time and next trigger time. ```python class CustomRegularTimeEvent(RegularTimeEvent): """ Rule which is triggered every Monday at 8:15 a.m. The listeners for this event should implement the on_monday_morning() method. """ _trigger_time_dictionary = { "weekday": 0, "hour": 8, "minute": 15, "second": 0, "microsecond": 0 } _time_rule = RegularDateTimeRule(**trigger_time_dict) @classmethod def trigger_time(cls) -> RelativeDelta: return RelativeDelta(**cls.trigger_time_dict) def next_trigger_time(self, now: datetime) -> datetime: next_trigger_time = self._time_rule.next_trigger_time(now) return next_trigger_time ``` -------------------------------- ### Custom TimeEvent Implementation - Python Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/reference/backtest_flow.rst Provides an example of a custom TimeEvent that defines its own notification logic. It inherits from TimeEvent and implements the notify method to call a specific listener method. ```python class CustomTimeEvent (TimeEvent): def notify(self, listener) -> None: listener.on_custom_event() ``` -------------------------------- ### Define Periodic Event Trigger Times (Python) Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/reference/backtest_flow.rst This Python code snippet demonstrates how to define the start time, end time, and frequency for a PeriodicEvent. The event is triggered within the specified time range at the given frequency, excluding the end time. ```python start_time = { "hour": 13, "minute": 20, "second": 0, "microsecond": 0 } end_time = { "hour": 16, "minute": 0, "second": 0, "microsecond": 0 } frequency = Frequency.MIN_30 ``` -------------------------------- ### Create Daily Backtest Trading Session Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_strategy_backtest.rst Sets up a daily backtest session for a specified ticker and date range using predefined demo settings. It configures the frequency, data provider, and builds the trading session. ```python def main(): ticker = DummyTicker("AAA") start_date = str_to_date("2010-01-01") end_date = str_to_date("2015-03-01") settings = get_demo_settings() pdf_exporter = PDFExporter(settings) excel_exporter = ExcelExporter(settings) session_builder = BacktestTradingSessionBuilder(settings, pdf_exporter, excel_exporter) session_builder.set_frequency(Frequency.DAILY) session_builder.set_data_provider(daily_data_provider) ts = session_builder.build(start_date, end_date) ``` -------------------------------- ### Running an Alpha Model Strategy with Backtesting in Python Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_alpha_model.rst Demonstrates how to set up and run an Alpha Model strategy using qf-lib's backtesting framework. It involves configuring the trading session, providing necessary data, and initializing the AlphaModelStrategy with a specific Alpha Model. ```python import matplotlib.pyplot as plt plt.ion() # required for dynamic chart from demo_scripts.common.utils.dummy_ticker import DummyTicker from demo_scripts.demo_configuration.demo_data_provider import daily_data_provider from demo_scripts.backtester.moving_average_alpha_model import MovingAverageAlphaModel from demo_scripts.demo_configuration.demo_settings import get_demo_settings from qf_lib.documents_utils.document_exporting.pdf_exporter import PDFExporter from qf_lib.documents_utils.excel.excel_exporter import ExcelExporter from qf_lib.backtesting.strategies.alpha_model_strategy import AlphaModelStrategy from qf_lib.backtesting.trading_session.backtest_trading_session_builder import BacktestTradingSessionBuilder from qf_lib.common.enums.frequency import Frequency ``` -------------------------------- ### Create Intraday Backtest Trading Session Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_strategy_backtest.rst Sets up an intraday backtest session for a specified ticker and date range, configuring market open/close times and an intraday data provider. ```python def main(): ticker = DummyTicker("AAA") start_date = str_to_date("2019-07-01") end_date = str_to_date("2019-08-31") settings = get_demo_settings() pdf_exporter = PDFExporter(settings) excel_exporter = ExcelExporter(settings) session_builder = BacktestTradingSessionBuilder(settings, pdf_exporter, excel_exporter) session_builder.set_frequency(Frequency.MIN_1) session_builder.set_data_provider(intraday_data_provider) session_builder.set_market_open_and_close_time( {"hour": 0, "minute": 0}, {"hour": 23, "minute": 59}) ts = session_builder.build(start_date, end_date) ``` -------------------------------- ### Create Target Percent Orders (Python) Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_strategy_backtest.rst Generates orders based on desired portfolio percentages for specified tickers using the OrderFactory. This function takes a dictionary mapping tickers to percentages. ```python target_percent_orders(ticker_dict) ``` -------------------------------- ### Configure Backtest with Price Slippage and Volume Limit Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/customize_your_backtest.rst Demonstrates setting up a backtest with both a Price-Based Slippage model and a `max_volume_share_limit` to constrain order volumes based on daily asset volume. ```python from qf_lib.backtesting.execution_handler.slippage.price_based_slippage import \ PriceBasedSlippage def main(): # settings backtest_name = 'Simple MA Strategy Demo' start_date = str_to_date("2010-01-01") end_date = str_to_date("2015-03-01") ticker = DummyTicker("AAA") # configuration settings = get_demo_settings() pdf_exporter = PDFExporter(settings) excel_exporter = ExcelExporter(settings) session_builder = BacktestTradingSessionBuilder(settings, pdf_exporter, excel_exporter) session_builder.set_frequency(Frequency.DAILY) session_builder.set_backtest_name(backtest_name) session_builder.set_data_provider(daily_data_provider) # Assuming max_volume_share_limit would be set here, similar to other parameters # session_builder.set_slippage_model(PriceBasedSlippage, slippage_rate=0.001, max_volume_share_limit=0.15) ``` -------------------------------- ### Place Market Orders with Time-in-Force Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_strategy_backtest.rst Demonstrates placing a Market Order with a DAY time-in-force, targeting a specific percentage of the portfolio. If the asset is not held, a Market Order is created. If the target percentage is already met, no order is generated. Fractional contracts are supported for CRYPTO tickers. ```python self.order_factory.target_percent_orders({DummyTicker("AAA"): 0.75}, MarketOrder(), TimeInForce.DAY) ``` -------------------------------- ### Create Settings Object in Python Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/configuration.rst Demonstrates how to initialize the Settings object in Python, which is a dependency for many QF-Lib components. It takes paths to the main settings file and a secret settings file. ```python from qf_lib.settings import Settings settings_path = ... secret_settings_path = ... settings = Settings(settings_path, secret_settings_path) ``` -------------------------------- ### Configure Backtest with Price-Based Slippage Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/customize_your_backtest.rst Sets up a backtest session using a Price-Based Slippage model with a specified slippage rate. It configures the trading session, strategy, and event handling for daily trading. ```python ticker = DummyTicker("AAA") # configuration settings = get_demo_settings() pdf_exporter = PDFExporter(settings) excel_exporter = ExcelExporter(settings) session_builder = BacktestTradingSessionBuilder(settings, pdf_exporter, excel_exporter) session_builder.set_frequency(Frequency.DAILY) session_builder.set_backtest_name(backtest_name) session_builder.set_data_provider(daily_data_provider) session_builder.set_slippage_model(PriceBasedSlippage, slippage_rate=0.001) ts = session_builder.build(start_date, end_date) strategy = SimpleMAStrategy(ts, ticker) CalculateAndPlaceOrdersRegularEvent.set_daily_default_trigger_time() CalculateAndPlaceOrdersRegularEvent.exclude_weekends() strategy.subscribe(CalculateAndPlaceOrdersRegularEvent) ts.start_trading() ``` -------------------------------- ### Simple Moving Average Strategy Implementation Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_strategy_backtest.rst Implements a trading strategy that calculates two simple moving averages (20-day and 5-day) and places buy orders if the short MA is greater than or equal to the long MA, targeting 100% of the portfolio. Otherwise, it targets 0%. It also includes logic for cancelling previous orders and placing new ones. ```python class SimpleMAStrategy(AbstractStrategy): """ strategy, which computes every day, before the market open time, two simple moving averages (long - 20 days, short - 5 days) and creates a buy order in case if the short moving average is greater or equal to the long moving average. """ def __init__(self, ts: BacktestTradingSession, ticker: Ticker): super().__init__(ts) self.broker = ts.broker self.order_factory = ts.order_factory self.data_provider = ts.data_provider self.ticker = ticker def calculate_and_place_orders(self): # Compute the moving averages long_ma_len = 20 short_ma_len = 5 # Use data handler to download last 20 daily close prices and use them to compute the moving averages long_ma_series = self.data_provider.historical_price(self.ticker, PriceField.Close, long_ma_len) long_ma_price = long_ma_series.mean() short_ma_series = long_ma_series.tail(short_ma_len) short_ma_price = short_ma_series.mean() if short_ma_price >= long_ma_price: # Place a buy Market Order, adjusting the position to a value equal to 100% of the portfolio orders = self.order_factory.target_percent_orders({self.ticker: 1.0}, MarketOrder(), TimeInForce.DAY) else: orders = self.order_factory.target_percent_orders({self.ticker: 0.0}, MarketOrder(), TimeInForce.DAY) # Cancel any open orders and place the newly created ones self.broker.cancel_all_open_orders() self.broker.place_orders(orders) ``` -------------------------------- ### QF-Lib Setting: Bloomberg Connection Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/configuration.rst Configuration for the BloombergDataProvider, including 'host' and 'port'. This requires a Bloomberg subscription and a running BLPAPI. ```json "bloomberg": { "host": "localhost", "port": 8194 } ``` -------------------------------- ### Sample Secret Settings JSON Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/configuration.rst Illustrates the format for the secret settings JSON file, which contains sensitive information like passwords. This file should not be committed to version control. ```json { "some_connection_settings": { "password": "my_secret_pass" } } ``` -------------------------------- ### Download Historical Prices (Python) Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_strategy_backtest.rst Retrieves the latest 10 closing prices for a given ticker using the DataHandler. This function returns a pandas-compatible QFSeries. ```python series = self.data_handler.historical_price(DummyTicker("AAA"), PriceField.Close, 10) ``` -------------------------------- ### Adjusting Signal Generation Frequency (Python) Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_strategy_backtest.rst Shows how to change the frequency at which the strategy generates signals. This allows for testing different trading frequencies, such as generating signals once per hour using 60-minute intervals. ```python CalculateAndPlaceOrdersPeriodicEvent.set_frequency(Frequency.MIN_60) ``` -------------------------------- ### Daily SMA Strategy Implementation in Python Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_strategy_backtest.rst Implements a daily Simple Moving Average (SMA) strategy. It calculates a 20-day and a 5-day moving average of closing prices. A buy order is placed if the short SMA is greater than or equal to the long SMA, targeting 100% of the portfolio for the ticker. Otherwise, it targets 0%. Dependencies include AbstractStrategy, BacktestTradingSession, Ticker, and various order and data handling components from qf_lib. ```python from qf_lib.backtesting.strategies.abstract_strategy import AbstractStrategy from qf_lib.backtesting.order.execution_style import MarketOrder from qf_lib.backtesting.order.time_in_force import TimeInForce from qf_lib.backtesting.trading_session.backtest_trading_session import BacktestTradingSession from qf_lib.common.enums.price_field import PriceField from qf_lib.common.tickers.tickers import Ticker class SimpleMAStrategy(AbstractStrategy): """ strategy, which computes every day, before the market open time, two simple moving averages (long - 20 days, short - 5 days) and creates a buy order in case if the short moving average is greater or equal to the long moving average. """ def __init__(self, ts: BacktestTradingSession, ticker: Ticker): super().__init__(ts) self.broker = ts.broker self.order_factory = ts.order_factory self.data_handler = ts.data_handler self.ticker = ticker def calculate_and_place_orders(self): # Compute the moving averages long_ma_len = 20 short_ma_len = 5 # Use data handler to download last 20 daily close prices and use them to compute the moving averages long_ma_series = self.data_handler.historical_price(self.ticker, PriceField.Close, long_ma_len) long_ma_price = long_ma_series.mean() short_ma_series = long_ma_series.tail(short_ma_len) short_ma_price = short_ma_series.mean() if short_ma_price >= long_ma_price: # Place a buy Market Order, adjusting the position to a value equal to 100% of the portfolio orders = self.order_factory.target_percent_orders({self.ticker: 1.0}, MarketOrder(), TimeInForce.DAY) else: orders = self.order_factory.target_percent_orders({self.ticker: 0.0}, MarketOrder(), TimeInForce.DAY) # Cancel any open orders and place the newly created ones self.broker.cancel_all_open_orders() self.broker.place_orders(orders) ``` -------------------------------- ### Add Interactive Brokers Commission to Backtest Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/customize_your_backtest.rst This snippet shows how to integrate the IBCommissionModel into a backtest session builder. It sets up a daily backtest and configures the session to use the specified commission model. Dependencies include qf_lib.backtesting.execution_handler.commission_models.ib_commission_model. ```python from qf_lib.backtesting.execution_handler.commission_models.ib_commission_model import \ IBCommissionModel def main(): # settings backtest_name = 'Simple MA Strategy Demo' start_date = str_to_date("2010-01-01") end_date = str_to_date("2015-03-01") ticker = DummyTicker("AAA") # configuration settings = get_demo_settings() pdf_exporter = PDFExporter(settings) excel_exporter = ExcelExporter(settings) session_builder = BacktestTradingSessionBuilder(settings, pdf_exporter, excel_exporter) session_builder.set_frequency(Frequency.DAILY) session_builder.set_backtest_name(backtest_name) session_builder.set_data_provider(daily_data_provider) session_builder.set_commission_model(IBCommissionModel) ts = session_builder.build(start_date, end_date) strategy = SimpleMAStrategy(ts, ticker) CalculateAndPlaceOrdersRegularEvent.set_daily_default_trigger_time() CalculateAndPlaceOrdersRegularEvent.exclude_weekends() strategy.subscribe(CalculateAndPlaceOrdersRegularEvent) ts.start_trading() ``` -------------------------------- ### Cancel Open Orders and Place New Orders Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_strategy_backtest.rst This snippet shows how to cancel all currently open orders before placing new ones using the Broker object. This ensures that only the latest set of orders are active. ```python self.broker.cancel_all_open_orders() self.broker.place_orders(orders) ``` -------------------------------- ### Intraday MA Strategy Implementation (Python) Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_strategy_backtest.rst Defines the core logic for an intraday moving average strategy. It calculates short and long moving averages based on historical price data and generates buy or sell orders when the short MA crosses the long MA. It also handles order placement and cancellation. ```python self.position_sizer = ts.position_sizer self.timer = ts.timer self.ticker = ticker self.logger = qf_logger.getChild(self.__class__.__name__) def calculate_and_place_orders(self): self.logger.info("{} - Computing signals".format(self.timer.now())) # Compute the moving averages long_ma_len = 20 short_ma_len = 5 # Use data handler to download last 20 daily close prices and use them to compute the moving averages long_ma_series = self.data_handler.historical_price(self.ticker, PriceField.Close, long_ma_len, frequency=Frequency.MIN_1) long_ma_price = long_ma_series.mean() short_ma_series = long_ma_series.tail(short_ma_len) short_ma_price = short_ma_series.mean() specific_ticker = self.ticker.get_current_specific_ticker() if isinstance(self.ticker, FutureTicker) \ else self.ticker if short_ma_price >= long_ma_price: # Place a buy Market Order, adjusting the position to a value equal to 100% of the portfolio orders = self.order_factory.target_percent_orders({specific_ticker: 1.0}, MarketOrder(), TimeInForce.DAY) else: orders = self.order_factory.target_percent_orders({specific_ticker: 0.0}, MarketOrder(), TimeInForce.DAY) # Cancel any open orders and place the newly created ones self.broker.cancel_all_open_orders() self.broker.place_orders(orders) ``` -------------------------------- ### Adjusting Data Frequency for Strategy (Python) Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_strategy_backtest.rst Demonstrates how to modify the data frequency used for calculating moving averages within the strategy. This is useful for simulating trading scenarios with different bar intervals, like using 30-minute data instead of 1-minute data. ```python long_ma_series = self.data_handler.historical_price(self.ticker, PriceField.Close, long_ma_len, frequency=Frequency.MIN_30) ``` -------------------------------- ### Subscribe Strategy to Regular Order Calculation Event Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_strategy_backtest.rst Configures and subscribes a strategy to a regular event that triggers order calculation and placement. This includes setting the default trigger time for daily execution and excluding weekends. ```python strategy = ExampleStrategy(trading_session) CalculateAndPlaceOrdersRegularEvent.set_daily_default_trigger_time() CalculateAndPlaceOrdersRegularEvent.exclude_weekends() strategy.subscribe(CalculateAndPlaceOrdersRegularEvent) ``` -------------------------------- ### QF-Lib Signals Plotter Demo Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_alpha_model.rst This Python code demonstrates how to use the SignalsPlotter to create and save a document with trading signals plotted on a candlestick chart. It involves setting up dates, data handlers, models, and exporters. ```Python from demo_scripts.backtester.moving_average_alpha_model import MovingAverageAlphaModel from demo_scripts.common.utils.dummy_ticker import DummyTicker from demo_scripts.demo_configuration.demo_data_provider import daily_data_provider from demo_scripts.demo_configuration.demo_settings import get_demo_settings from qf_lib.documents_utils.document_exporting.pdf_exporter import PDFExporter from qf_lib.analysis.signals_analysis.signals_plotter import SignalsPlotter from qf_lib.backtesting.data_handler.daily_data_handler import DailyDataHandler from qf_lib.backtesting.events.time_event.regular_time_event.market_close_event import MarketCloseEvent from qf_lib.backtesting.events.time_event.regular_time_event.market_open_event import MarketOpenEvent from qf_lib.common.enums.frequency import Frequency from qf_lib.common.utils.dateutils.string_to_date import str_to_date from qf_lib.common.utils.dateutils.timer import SettableTimer from qf_lib.documents_utils.document_exporting.pdf_exporter import PDFExporter from qf_lib.settings import Settings def main(): start_date = str_to_date("2010-01-01") end_date = str_to_date("2010-03-01") signal_frequency = Frequency.DAILY title = "Signals Plotter Demo" # set market open and close time. Does not matter much for a backtest # signals will be calculated at midnight for daily frequency MarketOpenEvent.set_trigger_time({"hour": 8, "minute": 30, "second": 0, "microsecond": 0}) MarketCloseEvent.set_trigger_time({"hour": 13, "minute": 0, "second": 0, "microsecond": 0}) data_handler = DailyDataHandler(daily_data_provider, SettableTimer(start_date)) model = MovingAverageAlphaModel(fast_time_period=5, slow_time_period=20, risk_estimation_factor=1.25, data_provider=data_handler) settings = get_demo_settings() pdf_exporter = PDFExporter(settings) plotter = SignalsPlotter([DummyTicker("AAA")], start_date, end_date, data_handler, model, settings, pdf_exporter, title, signal_frequency, data_frequency=signal_frequency) plotter.build_document() plotter.save() ``` -------------------------------- ### QF-Lib Setting: Company Name and Logo Path Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/configuration.rst Defines optional settings for 'company_name' and 'logo_path' used in generating PDF tearsheets. These appear in the header of the generated documents. ```json "company_name": "Sample Org Name", "logo_path": "path/to/logo.jpg" ``` -------------------------------- ### QF-Lib Setting: Output Directory Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/configuration.rst Defines the 'output_directory' where various QF-Lib components will save their generated output, such as PDF tearsheets. ```json "output_directory": "output" ``` -------------------------------- ### Plotting with QF-Lib Charts Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/reference/structure.rst Illustrates the process of creating and displaying charts using QF-Lib's plotting utilities. Charts are implemented as classes with a 'plot()' method, and can be enhanced with decorators before display. Requires matplotlib for showing the plot. ```python import matplotlib.pyplot as plt from qf_lib.plotting.decorators import DataElementDecorator from qf_lib.plotting.charts.some_chart_type import SomeChartType # Replace with an actual chart type # Assuming 'my_data_element' is a data object compatible with the chart chart = SomeChartType(data_element=my_data_element) chart = DataElementDecorator(chart, data_element=my_data_element) # Example decorator chart.plot() plt.show(block=True) ``` -------------------------------- ### Add Price-Based Slippage to Backtest Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/customize_your_backtest.rst This snippet illustrates configuring a backtest to use the PriceBasedSlippage model, which applies slippage as a percentage of the security's price. This is useful for backtests with wide price ranges. Requires qf_lib.backtesting.execution_handler.slippage.price_based_slippage. ```python from qf_lib.backtesting.execution_handler.slippage.price_based_slippage import \ PriceBasedSlippage def main(): # settings backtest_name = 'Simple MA Strategy Demo' start_date = str_to_date("2010-01-01") end_date = str_to_date("2015-03-01") ``` -------------------------------- ### Subscribe Listener to TimeEvent - Python Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/reference/backtest_flow.rst Demonstrates how to subscribe a listener to a specific type of TimeEvent using the Scheduler. The listener must implement a corresponding callback method. ```python Scheduler.subscribe(TypeOfEvent, listener) ``` -------------------------------- ### Handle Market Open Event Notification (Python) Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/reference/backtest_flow.rst This Python code snippet illustrates how a listener object's 'on_monday_morning' method is called when a 'notify' method is invoked with the listener as an argument. This pattern is used for event notifications. ```python def notify(self, listener) -> None: listener.on_monday_morning(self) ``` -------------------------------- ### Configure Backtest with Square Root Market Impact Slippage Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/customize_your_backtest.rst Configures a backtest session using the Square Root Market Impact Slippage model, incorporating a price impact factor. This model adjusts slippage based on volatility and trading volume. ```python from qf_lib.backtesting.execution_handler.slippage.square_root_market_impact_slippage import \ SquareRootMarketImpactSlippage def main(): # settings backtest_name = 'Simple MA Strategy Demo' start_date = str_to_date("2010-01-01") end_date = str_to_date("2015-03-01") ticker = DummyTicker("AAA") # configuration settings = get_demo_settings() pdf_exporter = PDFExporter(settings) excel_exporter = ExcelExporter(settings) session_builder = BacktestTradingSessionBuilder(settings, pdf_exporter, excel_exporter) session_builder.set_frequency(Frequency.DAILY) session_builder.set_backtest_name(backtest_name) session_builder.set_data_provider(daily_data_provider) session_builder.set_slippage_model(SquareRootMarketImpactSlippage, price_impact=0.05) ts = session_builder.build(start_date, end_date) strategy = SimpleMAStrategy(ts, ticker) CalculateAndPlaceOrdersRegularEvent.set_daily_default_trigger_time() CalculateAndPlaceOrdersRegularEvent.exclude_weekends() strategy.subscribe(CalculateAndPlaceOrdersRegularEvent) ts.start_trading() ``` -------------------------------- ### Add fixed commission to daily backtest using qf-lib Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/customize_your_backtest.rst Adds a fixed commission amount to each transaction in a daily backtest. It uses the `FixedCommissionModel` from `qf_lib.backtesting.execution_handler.commission_models` and requires setting up a `BacktestTradingSessionBuilder` with necessary parameters like dates, ticker, and data provider. ```python from qf_lib.backtesting.execution_handler.commission_models.fixed_commission_model import \ FixedCommissionModel def main(): ticker = DummyTicker("AAA") start_date = str_to_date("2010-01-01") end_date = str_to_date("2015-03-01") settings = get_demo_settings() pdf_exporter = PDFExporter(settings) excel_exporter = ExcelExporter(settings) session_builder = BacktestTradingSessionBuilder(settings, pdf_exporter, excel_exporter) session_builder.set_frequency(Frequency.DAILY) session_builder.set_data_provider(daily_data_provider) session_builder.set_commission_model(FixedCommissionModel, commission=2.75) ts = session_builder.build(start_date, end_date) ``` -------------------------------- ### Intraday SMA Strategy Placeholder in Python Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_strategy_backtest.rst A placeholder for an intraday Simple Moving Average (SMA) strategy. This strategy would compute two SMAs (e.g., 20-minute and 5-minute) between specific trading hours (10:00-13:00). A buy order is triggered if the short SMA meets or exceeds the long SMA. This strategy assumes one-minute data bars are available for backtesting. ```python from qf_lib.backtesting.strategies.abstract_strategy import AbstractStrategy from qf_lib.backtesting.trading_session.backtest_trading_session import BacktestTradingSession from qf_lib.common.tickers.tickers import Ticker class IntradayMAStrategy(AbstractStrategy): """ Strategy which computes two simple moving averages (long - 20 minutes, short - 5 minutes) between 10:00 and 13:00, and creates a buy order in case if the short moving average is greater or equal to the long moving average. """ def __init__(self, ts: BacktestTradingSession, ticker: Ticker): super().__init__(ts) self.broker = ts.broker self.order_factory = ts.order_factory self.data_handler = ts.data_handler ``` -------------------------------- ### QF-Lib Setting: Document CSS Directory Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/configuration.rst Specifies the 'document_css_directory' setting, which is used by the PDFExporter to apply custom styling to elements within generated PDFs. If not provided, default styles are used. ```json "document_css_directory": "input/elements_css" ``` -------------------------------- ### Schedule a New Single Time Event (Python) Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/reference/backtest_flow.rst This Python code shows how to schedule a new SingleTimeEvent using the schedule_new_event function. It takes a datetime object and associated data as arguments, which can be later retrieved using the get_data function. ```python SingleTimeEvent.schedule_new_event(datetime, data) ``` -------------------------------- ### Create QFDataArray from xr.DataArray Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/reference/structure.rst Demonstrates how to convert a regular xarray DataArray into a QFDataArray, which is the primary 3-D container in the QF-Lib system. This conversion facilitates easier slicing and interoperability with other QF-Lib containers. ```python from qf_lib.containers.data_array import QFDataArray # Assuming 'xr_data_array' is a pre-existing xarray.DataArray quant_data_array = QFDataArray.from_xr_data_array(xr_data_array) ``` -------------------------------- ### Add Fixed Slippage to Backtest Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/customize_your_backtest.rst This code demonstrates how to apply a fixed slippage amount to a backtest using the FixedSlippage model. It configures the backtest session to add a specific slippage per share, impacting transaction fill prices. Requires qf_lib.backtesting.execution_handler.slippage.fixed_slippage. ```python from qf_lib.backtesting.execution_handler.slippage.fixed_slippage import \ FixedSlippage def main(): # settings backtest_name = 'Simple MA Strategy Demo' start_date = str_to_date("2010-01-01") end_date = str_to_date("2015-03-01") ticker = DummyTicker("AAA") # configuration settings = get_demo_settings() pdf_exporter = PDFExporter(settings) excel_exporter = ExcelExporter(settings) session_builder = BacktestTradingSessionBuilder(settings, pdf_exporter, excel_exporter) session_builder.set_frequency(Frequency.DAILY) session_builder.set_backtest_name(backtest_name) session_builder.set_data_provider(daily_data_provider) session_builder.set_slippage_model(FixedSlippage, slippage_per_share=0.25) ts = session_builder.build(start_date, end_date) strategy = SimpleMAStrategy(ts, ticker) CalculateAndPlaceOrdersRegularEvent.set_daily_default_trigger_time() CalculateAndPlaceOrdersRegularEvent.exclude_weekends() strategy.subscribe(CalculateAndPlaceOrdersRegularEvent) ts.start_trading() ``` -------------------------------- ### Dispatch Next Event Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/reference/backtest_flow.rst Dispatches the next event from the event queue. This function is central to the event-driven architecture, triggering subsequent actions and notifications. ```python EventManager.dispatch_next_event() ``` -------------------------------- ### Moving Average Alpha Model Implementation in Python Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/tutorials/first_alpha_model.rst Implements a Simple Moving Average Alpha Model strategy. It calculates two Exponential Moving Averages (EMAs) and suggests LONG or SHORT exposure based on their comparison. Requires qf-lib components for data provision and exposure calculation. ```python from qf_lib.backtesting.alpha_model.alpha_model import AlphaModel from qf_lib.backtesting.alpha_model.exposure_enum import Exposure from qf_lib.common.enums.price_field import PriceField from qf_lib.common.tickers.tickers import Ticker from qf_lib.data_providers.data_provider import DataProvider class MovingAverageAlphaModel(AlphaModel): def __init__(self, fast_time_period: int, slow_time_period: int, risk_estimation_factor: float, data_provider: DataProvider): super().__init__(risk_estimation_factor, data_provider) self.fast_time_period = fast_time_period self.slow_time_period = slow_time_period def calculate_exposure(self, ticker: Ticker, current_exposure: Exposure) -> Exposure: num_of_bars_needed = self.slow_time_period close_tms = self.data_provider.historical_price(ticker, PriceField.Close, num_of_bars_needed) fast_ma = close_tms.ewm(span=self.fast_time_period, adjust=False).mean() slow_ma = close_tms.ewm(span=self.slow_time_period, adjust=False).mean() if fast_ma[-1] > slow_ma[-1]: return Exposure.LONG else: return Exposure.SHORT ``` -------------------------------- ### Custom TimeEventListener Implementation - Python Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/reference/backtest_flow.rst Illustrates the implementation of a listener for custom time events. This class must define the callback method that the custom event's notify method will call. ```python class CustomTimeEventListener: def on_custom_event(self): ... ``` -------------------------------- ### Update Portfolio Positions Source: https://github.com/quarkfin/qf-lib/blob/master/docs/source/reference/backtest_flow.rst Updates open positions in the Portfolio with their most recent prices. This is crucial for reflecting the current market value of holdings after order executions. ```python Portfolio.update() ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.