Skip to content

algotrade-plutus/ProtoSmartBeta

Repository files navigation

Static Badge Static Badge Static Badge

PROTO:Smart Beta

Select and hold Vietnamese equities by Price-to-Earnings ratio and dividend yield, rebalanced monthly.

Abstract

This project uses the Price-to-Earnings (P/E) ratio and the dividend yield (DY) to select and hold stocks in the Vietnamese stock market. The portfolio is rebalanced on the first day of each month; if that day is a holiday, rebalancing is carried out on the next trading day.

Developed and evaluated end-to-end on data from the Algotrade database over an in-sample period of 2019-01-01 → 2022-01-01 and an out-of-sample period of 2022-01-01 → 2024-01-01, following the 9-step Development Process and the Plutus Reproducibility Standard. On the in-sample period it reaches a Sharpe ratio of 1.2971 and a holding-period return of 104.9%; on the out-of-sample period it reaches a Sharpe ratio of -0.3497 and a holding-period return of -3.171%. Every reported number is reproducible in an isolated Docker container via plutus-verify against a committed groundtruth baseline (see Implementation & Reproducibility).

Introduction

In value investing, one common approach to stock selection involves identifying undervalued companies with strong income potential. This strategy leverages two key financial metrics: the Price-to-Earnings (P/E) ratio and the dividend yield. The P/E ratio helps assess whether a stock is trading at a reasonable price relative to its earnings, while the dividend yield highlights its income-generating potential.

The core idea is to select stocks with a low P/E ratio and a high dividend yield, as these stocks may represent undervalued opportunities that also offer steady cash returns. This method is particularly effective in mature or stable markets, such as the Vietnamese stock market, where dividend-paying companies are often more established and financially sound.

1. Forming Algorithm Hypothesis

We filter and maintain a portfolio of stocks with a price-to-earnings (P/E) ratio within the range of (0, 15) and a dividend yield (DY) greater than 0.01. The dividend yield is calculated as:

  • DY = DPS / Price

where DPS denotes dividends per share. Existing holdings are sold before purchasing new stocks at each rebalancing period. The strategy does not yet account for trading volume; it is assumed that all stocks can be bought immediately without liquidity constraints.

2. Data Preparation

  • Source: Algotrade database (daily close prices, financial info for EPS/DPS, and the VNINDEX benchmark), shipped as processed CSVs via Google Drive.
  • Period: in-sample 2019-01-01 → 2022-01-01; out-of-sample 2022-01-01 → 2024-01-01.
  • Fees: each buy and each sell is charged a 0.035% fee. Starting capital is 25,000,000 VND.

The daily close price and financial data (Net Profit After Tax Attributable to Shareholders, outstanding shares, dividends paid) are extracted, used to compute P/E and DPS, and stored as CSV files to reduce the time required for subsequent steps. The data lands under data/is/ (in-sample) and data/os/ (out-of-sample).

Obtaining the data

Option 1 — Download from Google Drive (no database credentials needed). Download from this Google Drive folder. Place the data/ folder at the repo root:

data
├── is
│   ├── pe_dps.csv
│   └── vnindex.csv
└── os
    ├── pe_dps.csv
    └── vnindex.csv

Option 2 — Collect from the database. Requires read access to the Algotrade database. Copy .env.example to .env and fill in the connection variables the loader reads (HOST, PORT, DATABASE, USER_DB, PASSWORD), then run:

psb-load-data

3. Forming Set of Rules

At each monthly rebalancing date (the first trading day of the month):

  1. Compute, for every eligible stock, its P/E ratio and dividend yield (DY = DPS / Price) from the latest available financial and price data.
  2. Select the stocks whose P/E falls inside the configured range and whose DY exceeds the configured lower bound (in-sample defaults: P/E in [0, 15], DY ≥ 0.01).
  3. Liquidate all current holdings, then allocate capital across the newly selected stocks (lot-rounded), holding until the next rebalancing date.

Trading volume / liquidity is not modelled — all selected stocks are assumed immediately tradable.

Evaluation Metrics

The rules are evaluated with the following metrics, which are also the expected values verified by plutus check:

  • Sharpe Ratio
  • Information Ratio
  • Sortino Ratio
  • Maximum Drawdown (MDD)
  • HPR (%) and Excess HPR (%) vs the VNINDEX benchmark
  • Monthly return (%), Excess monthly return (%), and Annual return (%)

A risk-free rate of 6% per annum (≈ 0.023% per day) is used as the benchmark for the Sharpe and Sortino ratios.

Implementation & Reproducibility

The pipeline is packaged as proto-smart-beta (a src/-layout Python package) with console-script entry points — psb-load-data (data preparation), psb-backtest (in-sample), psb-optimize (optimization), and psb-evaluate (out-of-sample); each step below shows its own command.

Environment setup

uv sync     # create the env from the committed uv.lock and install the package

The environment is pinned by pyproject.toml + a committed uv.lock, so uv sync --frozen restores it exactly and installs the proto-smart-beta package (which is what makes the psb-* console scripts available). Database credentials are only needed for Option 2 of Data Preparation; the Google Drive path needs none.

Reproducibility

This repo ships a .plutus/manifest.yaml declaring the environment, data sources, steps, and expected metrics. Reproduce every result in an isolated Docker container with plutus-verify 0.5.1, installed from the public release wheel:

# Requires Docker running and uv installed
uv venv .plutus-venv && source .plutus-venv/bin/activate
uv pip install "plutus-verify[runner] @ https://github.com/algotrade-plutus/plutus-verify/releases/download/v0.5.1/plutus_verify-0.5.1-py3-none-any.whl"

plutus check .     # build -> run each step in-container -> compare vs baseline

The [runner] extra brings Docker orchestration and gdown (used to fetch the Google Drive data source). plutus check builds the image from the locked environment, installs the proto-smart-beta package (env.install_project), downloads the data source into a cache, runs each step in-container via its console script, and compares the emitted metrics and charts against the committed .plutus/expected/ baseline. Exit code 0 = reproduced (within tolerance), 1 = partial, 2 = failed.

4. In-sample Backtesting

Parameters (period, fees, capital, P/E and DY ranges) are specified in parameter/backtesting_parameter.json. Run:

psb-backtest

Charts are written to result/backtest/.

In-sample result (2019-01-01 → 2022-01-01)

Metric Value
Sharpe Ratio 1.2971
Information Ratio 0.4716
Sortino Ratio 1.7298
Maximum Drawdown (MDD) -0.2828
HPR (%) 104.9
Excess HPR (%) 35.98
Monthly return (%) 2.2617
Excess monthly return (%) 0.5012
Annual return (%) 27.09

Holding-period return vs the VNINDEX benchmark — result/backtest/hpr.svg HPR chart with VNINDEX benchmark

Drawdown over time — result/backtest/drawdown.svg Drawdown chart

5. Optimization

The search space is configured in parameter/optimization_parameter.json (P/E upper bound and DY lower bound), optimized over 100 Optuna trials to maximize the in-sample Sharpe ratio. A fixed random seed reproduces the search. Run:

psb-optimize

The optimized parameters are written to parameter/optimized_parameter.json. With seed 2024, the current optimum is:

{
    "pe": [0, 10],
    "dy": [0.056272982721535775, 1e6]
}

6. Out-of-sample Backtesting

Using the optimized parameters from Step 5, evaluate on the out-of-sample period:

psb-evaluate

Charts are written to result/optimization/.

Out-of-sample result (2022-01-01 → 2024-01-01)

Metric Value
Sharpe Ratio -0.3497
Information Ratio 0.7442
Sortino Ratio -0.4363
Maximum Drawdown (MDD) -0.4604
HPR (%) -3.171
Excess HPR (%) 18.27
Monthly return (%) -0.1905
Excess monthly return (%) 0.8779
Annual return (%) -4.244

Holding-period return vs the VNINDEX benchmark — result/optimization/hpr.svg HPR chart with VNINDEX benchmark

Drawdown over time — result/optimization/drawdown.svg Drawdown chart

Reference

[1] ALGOTRADE, Algorithmic Trading Theory and Practice - A Practical Guide with Applications on the Vietnamese Stock Market, 1st ed. DIMI BOOK, 2023, pp. 64–67. Accessed: Apr. 30, 2025. [Online]. Available: Link

[2] ALGOTRADE, "Weighting Methods Used in Smart-Beta Strategy," Website, Jul. 10, 2024. Available: Link (accessed Apr. 30, 2025).

About

Prototype SmartBeta

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages