2503 words
13 minutes
Combining Fundamental and Technical Analysis via Qlib Quant

Combining Fundamental and Technical Analysis via Qlib Quant#

Introduction#

Quantitative investing has grown significantly in recent years, becoming increasingly accessible to retail traders, hobbyists, and professionals alike. While fundamental analysis focuses on a company’s intrinsic value, technical analysis examines price patterns and market behavior. By combining these two approaches, you can develop a well-rounded strategy that captures both the qualitative aspects of a company’s financial health and the quantitative insight derived from price trends and momentum.

Qlib, a powerful open-source quant research platform developed by Microsoft, allows you to seamlessly integrate multiple data sources and strategies in Python. From handling massive amounts of historical price data and computing technical indicators to managing and analyzing fundamental datasets, Qlib provides a structured workflow for end-to-end quantitative research. In this post, we’ll walk through how to start combining fundamental and technical analysis in Qlib, beginning with the basics and progressing to more advanced concepts.

This guide covers:

  1. Basics of Fundamental Analysis
  2. Basics of Technical Analysis
  3. Introduction to Qlib
  4. Setting up the Qlib Environment
  5. Data Acquisition and Management
  6. Combining Fundamental and Technical Factors
  7. Case Study: Building a Simple Hybrid Strategy
  8. Advanced Concepts and Expansions
  9. Summary

Whether you are a new quant or an experienced professional seeking a unified solution for multi-factor modeling, this guide will help you master the art of merging fundamental and technical analysis with Qlib.


1. Basics of Fundamental Analysis#

Fundamental analysis is the study of a company’s intrinsic value, focusing on financial statements, industry trends, and macroeconomic factors. By examining factors such as revenue, earnings, and margins, investors aim to forecast the long-term performance of a stock. Key areas within fundamental analysis include:

1.1 Financial Statements#

  1. Income Statement: Outlines revenue, expenses, and net income. Useful for understanding profitability and operational efficiency.
  2. Balance Sheet: Summarizes assets, liabilities, and shareholders’ equity. Offers insight into a company’s financial stability and leverage.
  3. Cash Flow Statement: Tracks the flow of cash in and out of the business, highlighting liquidity and solvency.

1.2 Key Ratios#

Fundamental analysis employs various ratios derived from financial statements to gauge a company’s performance. Examples include:

RatioFormulaInterpretation
Price-to-Earnings (P/E)Price per Share / Earnings per ShareReflects how much investors are willing to pay for one dollar of earnings.
Return on Equity (ROE)Net Income / Shareholders’ EquityMeasures how effectively a company uses equity to generate profits.
Debt-to-Equity (D/E)Total Liabilities / Shareholders’ EquityGauges leverage and financial risk.
Earnings per Share (EPS)(Net Income - Preferred Dividends) / Common Shares OutstandingIndicates profit allocated to each share.

1.3 Qualitative Factors#

Beyond numerical data, fundamental analysis also considers qualitative elements such as industry competition, management quality, and macroeconomic influences. Though these factors are less tangible, they can greatly impact long-term prospects.

By incorporating fundamental analysis, you develop a strong understanding of a company’s value proposition. However, raw fundamentals alone may not illuminate shorter-term market inefficiencies. That’s where technical analysis steps in.


2. Basics of Technical Analysis#

Technical analysis involves studying past market data – primarily price and volume – to forecast future price movements. Rather than focusing on intrinsic value, technical analysis relies on charts, patterns, and indicators.

The simplest elements of technical analysis are trend lines and moving averages. By plotting price data over various time horizons, you can observe whether a stock is trending upward, downward, or sideways. Key tools include:

  • Simple Moving Average (SMA)
  • Exponential Moving Average (EMA)
  • Bollinger Bands
  • Support and Resistance Levels

2.2 Momentum and Volatility Indicators#

Technical analysts often use momentum indicators, such as the Relative Strength Index (RSI) and Moving Average Convergence Divergence (MACD), to identify potential overbought or oversold conditions. Volatility measures, like the Average True Range (ATR), help gauge market fluctuations and set appropriate risk controls.

2.3 Patterns and Volume Analysis#

Candlestick patterns (e.g., doji, hammer, engulfing patterns) and volume breakouts provide additional context. For example, a surge in volume accompanying a price breakout could signal strong momentum and confirm a potential trend shift.

Technical analysis can be powerful in timing trades and reacting to market sentiment. However, relying on price-driven signals alone may neglect the deeper, long-term strengths (or weaknesses) of a company’s fundamentals. A blend of these approaches often yields the most robust strategies.


3. Introduction to Qlib#

Qlib is an open-source quantitative investment platform designed primarily for end-to-end stock analysis. It offers:

  1. Data Handling: Qlib can manage large volumes of daily, minute-level, or even tick-level data.
  2. Feature Engineering: The library provides a wide range of built-in functions to create factors, including technical indicators, volatility metrics, and more.
  3. Model Building: Qlib supports the development and evaluation of predictive models for time-series data.
  4. Research Workflow Integration: You can smoothly connect data ingestion, feature engineering, strategy design, backtesting, and result analysis.

By merging fundamental data with Qlib’s technical factor library, you can construct rich multi-factor models. Here, you will learn the fundamentals of setting up Qlib, loading your data, and crafting your first combined factor strategy.


4. Setting Up the Qlib Environment#

To get started with Qlib, follow these steps:

  1. Install Dependencies:
    Qlib is primarily developed in Python. Make sure you have a recent version of Python (3.7+).

  2. Install Qlib:
    You can install Qlib using pip:

    Terminal window
    pip install pyqlib
  3. Set Up Data:
    Although Qlib can download sample datasets (e.g., Yahoo data), you’ll likely want to integrate your own data sources for fundamental information. Qlib also offers scripts for building a local dataset environment.

  4. Initialize Qlib:
    Within your Python scripts or notebooks, you’ll need to import Qlib and initialize it:

    import qlib
    from qlib.config import REG_CN
    qlib.init(provider_uri='~/.qlib/qlib_data/cn_data', region=REG_CN)

    Adjust provider_uri to the location of your local data repository. The above example assumes Chinese market data (region=REG_CN), but you can also configure for other regions.

Following these steps will prepare your environment to run fundamental or technical analyses. Next, we’ll explore how to systematically handle and combine different data sources.


5. Data Acquisition and Management#

Quant strategies often involve multiple data sources. Qlib primarily handles pricing and volume data, but you can also integrate external fundamental data. Here’s an overview of how to manage both.

5.1 Ingesting Market Data#

After installing and initializing Qlib, you can use Qlib’s built-in data structures to query historical price data:

from qlib.data import D
# Example: query daily data for a sample stock
df_price = D.features(
instruments='SH600519',
fields=['$close', '$volume'],
start_time='2019-01-01',
end_time='2020-12-31'
)
print(df_price.head())

This code fetches the closing price and volume for the instrument SH600519 (Kweichow Moutai in China’s A-share market) between 2019 and 2020.

5.2 Incorporating Fundamental Data#

Fundamental datasets are not directly included in Qlib’s default installation. You’ll need to process and store your own data, aligning it with market data. A typical approach involves:

  1. Collecting Fundamentals: Use APIs from financial data providers (e.g., Yahoo Finance, Quandl, Bloomberg, S&P Global) or official filings.
  2. Standardizing Tickers: Ensure tickers match the naming convention in Qlib’s data provider.
  3. Aligning Dates: Decide on the granularity you wish to use (e.g., quarterly fundamentals aligned with monthly or weekly bars).
  4. Import/Storage: Place the preprocessed fundamental data into a format that Qlib can reference.

Although direct integration requires additional scripts, Qlib can reference external CSV files or databases, enabling you to merge fundamental features with Qlib’s built-in technical factors.

5.3 Factor Construction Workflow#

Once both price and fundamental data are ingested, you can create custom data pipelines. Qlib’s factor library includes technical indicators such as MA, RSI, dedicated price transformations, and more. For fundamental data, you may define custom factors in Python, referencing your stored fundamental fields.


6. Combining Fundamental and Technical Factors#

A multi-factor approach blends the strengths of different data domains. For example, you might consider:

  • Earnings per Share (EPS Growth) + RSI: A measure of fundamental growth combined with a technical momentum indicator.
  • Debt-to-Equity + MACD: A gauge of balance sheet health plus trend confirmation.

6.1 Simple Example of Factor Definition#

Below is a conceptual outline of how you can define a new factor that combines fundamental metrics (like EPS) and technical indicators (like the 30-day SMA of closing price). We’ll call it HybridFactor:

import pandas as pd
def hybrid_factor(fundamentals_df, price_df):
"""
Combine fundamental data with a technical indicator.
:param fundamentals_df: DataFrame with columns [‘EPS’] for each instrument and date
:param price_df: DataFrame with columns [‘$close’] for each instrument and date
:return: DataFrame with the combined factor for each instrument and date
"""
# Compute 30-day simple moving average of price
sma_30 = price_df['$close'].rolling(window=30).mean()
# Standardize or normalize the fundamental metric
eps_norm = (fundamentals_df['EPS'] - fundamentals_df['EPS'].mean()) / fundamentals_df['EPS'].std()
# Combine
combined_factor = sma_30 * eps_norm # or some other formula
return combined_factor

Your actual logic may be more complex—this code is for illustration, omitting data alignment steps. Integrating these insights in Qlib typically requires creating a factor function or class that can be integrated into Qlib’s workflow.

6.2 Handling Nulls and Data Alignment#

Financial data often comes with missing values and mismatched dates. Be prepared to handle:\

  • Holidays and weekends: Stock markets are closed on specific days, resulting in missing rows.
  • Non-overlapping accounting periods: Fundamentals release quarterly, possibly leaving gaps in monthly or daily data.

Best practices include forward-filling or backward-filling fundamental data until updated figures become available, while using standard daily data for prices.

6.3 Setting up a Qlib Workflow#

In Qlib, a typical workflow integrates factor definitions into a pipeline where each factor is computed sequentially. You can store intermediate results and feed them to a model. By defining your fundamental-based factors and technical-based factors as separate modules, you can apply them individually or in combination.


7. Case Study: Building a Simple Hybrid Strategy#

To illustrate the synergy of fundamental and technical analysis in Qlib, let’s construct a simplified example from start to finish.

7.1 Example Strategy Description#

  1. Universe: A chosen set of stocks (e.g., the largest 300 stocks by market cap).
  2. Factor 1 (Fundamental): Quarterly EPS growth rate (EPS_Growth).
  3. Factor 2 (Technical): 14-day RSI (RSI_14).
  4. Signal:
    • Rank stocks by EPS_Growth in descending order.
    • Filter out stocks with RSI_14 > 70 (potentially overbought).
    • Build a portfolio with the top 10 stocks from the remaining list.

Let’s walk through how you might implement this in Qlib, assuming you have a DataFrame of fundamental data and Qlib’s standard price/technical pipelines.

7.2 Preparing the Data#

Below is a high-level example. Note that you’ll need properly aligned fundamental data. For demonstration, we’ll assume you have a DataFrame fund_df with columns [‘symbol’, ‘date’, ‘EPS_Growth’] and that your Qlib environment is already initialized.

import qlib
from qlib.data import D
import pandas as pd
# Initialize Qlib
qlib.init(provider_uri='~/.qlib/qlib_data/cn_data')
# Load fundamental data (for example, from CSV or a database)
fund_df = pd.read_csv('fundamental_data.csv', parse_dates=['date'])
# Ensure appropriate alignment with Qlib’s instrument naming if necessary

7.3 Technical Indicator Calculation#

Now, we fetch the 14-day RSI. Qlib already supports computing RSI directly:

from qlib.contrib.data.handler import Alpha158
# Alpha158 is an example data handler that calculates many factors including RSI
# For demonstration, we only focus on RSI output here
instruments = ['SH600519', 'SZ000001', ...] # example instruments
# Set a date range
start_date = '2020-01-01'
end_date = '2021-01-01'
# Prepare a data handler
data_handler = Alpha158(instruments=instruments, start_time=start_date, end_time=end_date, fit_start_time=start_date, fit_end_time=end_date)
# The data handler allows you to fetch computed features
data = data_handler.fetch(features=["RSI_14"])
rsi_df = data["RSI_14"].reset_index()

You can then merge rsi_df with your fundamental data frames on [‘symbol’, ‘date’]. You’ll likely take care of missing dates or use a date-filling strategy to ensure alignment.

7.4 Signal Generation#

Finally, generating signals involves filtering and ranking:

# Merge the fundamental and RSI DataFrames
signal_df = pd.merge(fund_df, rsi_df, on=['instrument', 'datetime'], how='inner')
# Filter out overbought stocks (RSI > 70)
signal_df = signal_df[signal_df['RSI_14'] <= 70]
# Rank by EPS_Growth descending
signal_df['rank'] = signal_df.groupby('datetime')['EPS_Growth'].rank(method='first', ascending=False)
# Select top 10 for each day
top_picks = signal_df[signal_df['rank'] <= 10]

This DataFrame top_picks now contains, for each date, the top 10 stocks that pass the fundamental filter (EPS_Growth) and the technical screen (RSI < 70). You can use this as the foundation for your portfolio construction.

7.5 Backtesting#

Qlib provides backtesting modules to evaluate your strategy performance. By defining an execution model, cost assumptions, and a rebalancing schedule, you can run a historical simulation to gauge risk and reward characteristics.

While this is a simplified example, it demonstrates the workflow of combining fundamental and technical indicators. In practice, you’d incorporate more robust factor definitions, risk controls, and portfolio optimization routines.


8. Advanced Concepts and Expansions#

Once you have a basic setup, you can explore more sophisticated techniques:

8.1 Factor Engineering and Selection#

  1. Composite Factors: Combine multiple fundamental metrics (e.g., ROE, Debt-to-Equity, P/E) into a single factor using weighting, PCA, or other dimension-reduction techniques.
  2. Factor Neutralization: Mitigate biases (e.g., industry, market-cap) by neutralizing factors relative to known risk exposures.

8.2 Data Frequency and Market Microstructure Enhancements#

  • High-Frequency Data: If your strategy benefits from intraday patterns, Qlib’s minute-level data can be used for advanced short-term signals.
  • Tick Data: For ultra-high-frequency users, consider storing and analyzing tick-level order book data, though this requires custom ingestion.

8.3 Predictive Modeling with Machine Learning#

Qlib integrates well with popular ML frameworks like scikit-learn, LightGBM, and PyTorch. You can create complex models (e.g., gradient boosting, neural networks) that predict future returns based on both fundamental and technical features. Common steps include:

  1. Feature Engineering: Construct YOY comparisons for fundamentals, advanced technical indicators, sentiment, or alternative data.
  2. Model Training: Split data into training, validation, and test sets. Evaluate performance on out-of-sample periods.
  3. Hyperparameter Tuning: Use Bayesian optimization or cross-validation to refine model settings.
  4. Ensemble Methods: Combine multiple models (fundamentals-driven, trend-driven, or factor-based) for more robust predictions.

8.4 Risk Management and Portfolio Optimization#

Professional strategies place significant emphasis on risk control. Qlib is compatible with external libraries that provide advanced optimization algorithms (e.g., Mean-Variance, Black-Litterman). Some key elements include:

  1. Position Sizing: Adjust allocations based on signal confidence or volatility forecasts.
  2. Stop-Losses: Employ dynamic rules tied to drawdowns or volatility spikes.
  3. Beta Hedging: Hedge systematic risk using index futures or options.

8.5 Automated Pipeline and Workflow#

By building reusable modules in Qlib, you can create fully automated pipelines:

  1. Data Update: Download and preprocess new fundamental and market data.
  2. Factor Computation: Recompute or update factors daily or quarterly.
  3. Predictive Modeling: Retrain or refresh your machine learning models as new data arrives.
  4. Portfolio Construction: Generate signals and rebalance your portfolio on a scheduled basis.

9. Summary#

Combining fundamental and technical analysis can provide a more holistic view of both an asset’s intrinsic value and its market sentiment. Qlib, with its powerful data management, factor computation, and modeling framework, is an excellent tool for executing this combined approach.

Key takeaways from this guide:

  1. Fundamental Analysis highlights a company’s performance via metrics like EPS, ROE, and cash flow.
  2. Technical Analysis focuses on price and volume-driven indicators for market timing and trend assessment.
  3. Qlib Setup involves installing Python dependencies, initializing Qlib, and configuring data providers.
  4. Data Management with Qlib integrates both market data and external fundamental data into a unified research framework.
  5. Factor Blending is straightforward once your data is properly aligned. You can combine fundamentals, technical factors, and custom logic into signals.
  6. Backtesting and Expansion: Qlib offers modules for evaluating your strategies historically, and you can add machine learning, factor neutralization, or advanced risk management as you become more experienced.

A successful multi-factor approach often requires iteration and refinement, especially when merging data of different frequencies, dealing with missing data, and accounting for market microstructure complexities. Nonetheless, by systematically layering fundamental and technical insights, you can craft more robust and adaptive quantitative strategies.

As you advance, experiment with more nuanced factor definitions, incorporate alternative data (e.g., satellite imagery, web scraping, social media sentiment), and accelerate your experiments with automated pipelines. The beauty of Qlib lies in its extensibility, allowing researchers and traders at all levels to prototype and deploy sophisticated models with relative ease.

Combining fundamental and technical analysis via Qlib Quant opens a world of possibilities. Start with the foundational ideas in this guide, and then incrementally enhance your approach as your data access, modeling expertise, and market insights deepen. Through careful experimentation and persistent iteration, you can develop systematic strategies that stand on the shoulders of both fundamental conviction and technical precision.

Combining Fundamental and Technical Analysis via Qlib Quant
https://closeaiblog.vercel.app/posts/qlib/12/
Author
CloseAI
Published at
2025-06-28
License
CC BY-NC-SA 4.0