Skip to content

Changelog

Note

This changelog is maintained in its original Chinese-English mixed format. Technical terms and API references are already in English.

2.0.4 (2026-05-01)

Fix

  • backtest/sim.py: Moved _prefetch_market_datasets() out of _prepare_simulation_inputs and now call it before sim() enters _backtest_context(). Previously prefetch ran inside the prefer_local_if_exists=True context, causing data.gets() to skip expiry checks and .recent merges. If a sim_dataset's local pickle (e.g. etl:adj_close) had not yet been refreshed at session start, sim would silently use the stale cache and report.creturn.index[-1] would be cut off earlier than user code's data.get('price:收盤價').index[-1]. Hoisting prefetch out of the context lets every dataset listed by sim_datasets() run through the normal expiry / recent merge path before backtest cache lockdown.

2.0.3 (2026-04-28)

Performance

  • data.gets(): Parallelize the stale-cache .recent merge loop with ThreadPoolExecutor (up to 8 workers). For a 4-dataset all-stale fetch at ~200ms RTT, wall-clock collapses from ~1030ms to ~420ms (2.4× speedup).
  • data/auth.py, data/get.py: Unify the download path to a single GET → pre-allocated bytearray(content_length) + memoryview slice writes → feather.read_feather(pa.py_buffer(raw)) zero-copy parse → set_dataframe_bytes verbatim persist. Drops the old stream-to-disk per-chunk callback, feather metadata validation read, and pandas re-encoding round-trip. Chunk size raised from 64 KiB to 1 MiB, cutting progress callbacks for a 100 MB download from ~1600 to ~100. Local micro-benchmarks show consistent 1.21-1.28× speedup across small / medium / parallel scenarios.

Refactor

  • data/get.py: Remove _download_persist_file_storage_misses, _download_file_storage_misses_to_storage, _download_persist_one_file_storage_miss, _validate_feather_file, and the isinstance(target_storage, FileStorage) branch in _materialize_full_misses. FileStorage and CacheStorage now share one _download_full_miss_frames_persist_full_miss_frames path.
  • data/get.py: Extract _run_parallel_tasks(keys, worker) generator, shared by _resolve_recent_candidates and _download_full_miss_frames_threaded (same min(8, n) ThreadPoolExecutor + as_completed pattern). Single-task case falls back to in-thread execution.
  • data/auth.py: Delete _download_ipc_file, add _download_feather_bytes (streaming with optional progress lives here), and have _download_dataframe return (df, raw_bytes).
  • data/storage.py: Add FileStorage.set_dataframe_bytes(name, payload, expiry) — writes raw feather bytes verbatim, skipping df.to_feather re-encoding. Remove set_feather_file, set_feather_bytes, and the unused validate_fn parameter from _atomic_file_replace. set_dataframe and set_dataframe_bytes share a _persist_feather helper.
  • Net -213 lines, 162 related tests still green.

2.0.2 (2026-04-28)

Changed

  • markets/tw.py: TWMarket.sim_datasets() prefetch list now reincludes the five always-loaded TW tables (benchmark_return:發行量加權股價報酬指數, security_categories, price:成交股數, etl:is_flagged_stock, etl:market_value) so they ride a single batched request instead of trickling in via on-demand fetches during sim. This partially reverts 2.0.1's on-demand split — peak RSS rises slightly in exchange for a steadier batched-quota profile.
  • finlab/core: Rebuild everything.js and style.css web component dashboard assets.

Fix

  • finlab/core: Throttle dashboard iframe height updates with requestAnimationFrame and compare getBoundingClientRect() height to prevent ResizeObserver/scrollHeight feedback loops in certain layouts.

2.0.1 (2026-04-22)

Changed

  • finlab/core: Update web component dashboard assets.
  • finlab/core: Bundle the Cython core and dashboard assets directly in the main repo instead of cloning the finlab_core submodule.

2.0.0 (2026-04-04)

View the FinLab 2.0.0 feature introduction

Engineering

  • exceptions: Add finlab.exceptions module with structured exception hierarchy (FinlabError, DataError, BacktestError, BrokerError, AuthError, PortfolioError, ConfigError)
  • backtest: Refactor 500-line sim() into 5 independently testable stage functions (_validate_sim_inputs, _prepare_price_data, _normalize_position, _execute_simulation, _build_sim_report), passing data between stages via _NormalizedPosition and _SimulationResult dataclasses
  • data: Add DataContext class encapsulating 13 module-level globals into a single object, with override() context manager for safely overriding state temporarily, laying groundwork for parallel strategy execution
  • optimize: Remove eval() call in combinations.py, replace with AST-based safe condition parser to eliminate arbitrary code execution risk
  • exceptions: Narrow 47 except Exception clauses across 20 files to specific exception types (requests.RequestException, OSError, KeyError, etc.), improving error observability in the trading system
  • ci: Add pytest-cov coverage threshold (fail_under=50), enforced in CI, excluding vendored/submodule code
  • ruff: Re-enable BLE001 (blind except) and C901 (mccabe complexity) lint rules, with per-file-ignores for functions pending refactor

Features

  • data: Add pip-style real-time download progress to data.gets(), supporting multi-row concurrent updates during parallel downloads. Auto-detects environment: terminal shows ANSI colored progress bars (with speed and size), Jupyter Notebook shows HTML progress bars. Correct CJK character width alignment, zero extra dependencies
  • polars_frame: Add .cs accessor to PolarsFrame for cross-sectional data transforms (aligned with FinlabDataFrame.cs):
  • rank() — percentile rank
  • zscore() — standardization
  • demean() — de-mean
  • winsorize(lower, upper) — percentile winsorization
  • bucket(n) — equal-quantile bucketing
  • polars_frame: Add .sector accessor to PolarsFrame for within-industry data transforms (aligned with FinlabDataFrame.sector):
  • rank(), mean(), std(), median(), sum(), min(), max(), count()
  • zscore(), demean(), winsorize(), bucket()
  • polars_frame: Add 5 statistical methods to PolarsFrame.rolling(n):
  • std() — rolling standard deviation
  • var() — rolling variance
  • skew() — rolling skewness
  • kurt() — rolling kurtosis
  • median() — rolling median
  • dataframe: Add 7 within-industry aggregation methods to df.sector accessor:
  • mean() — industry mean
  • std(ddof) — industry standard deviation
  • median() — industry median
  • sum() — industry sum
  • min() — industry minimum
  • max() — industry maximum
  • count() — industry valid count
  • dataframe: Add df.weight accessor for portfolio weight construction:
  • cap_industry(max_weight) — cap max weight per industry, redistribute excess proportionally
  • clip_by_volume(total_fund, max_participation_ratio) — clip individual stock weights by average daily volume
  • inverse_volatility(window) — inverse-volatility weighting, lower-volatility stocks get higher weight
  • risk_parity(window) — risk parity weighting, equalizing risk contribution per holding
  • correlation(diversify) — adjust weights by correlation, diversify or concentrate
  • target_volatility(target, window) — scale weights to achieve target annualized volatility
  • limit_turnover(max_turnover) — cap two-way turnover between rebalances
  • drawdown_control(max_drawdown) — automatically reduce exposure when drawdown exceeds threshold
  • dataframe: Add df.cs accessor for cross-sectional data transforms:
  • rank() — percentile rank
  • winsorize(lower, upper) — percentile winsorization
  • bucket(n) — equal-quantile bucketing
  • zscore() — standardization
  • demean() — de-mean
  • dataframe: Add df.sector accessor for within-industry data transforms (same 5 methods as df.cs, computed within industry)
  • online: Add PositionStreamMixin for real-time position streaming:
  • Hybrid mode: initialize via get_position(), update in real-time via Fill events, periodic reconciliation polling (default 30s)
  • Add PositionUpdate dataclass with snapshot_key() deduplication
  • RealtimeProvider auto-inherits subscribe_positions() / on_position() interface

Refactor

  • dataframe: Extract _fetch_refined_categories() as shared helper, eliminating duplicate industry name cleaning logic between FinlabDataFrame._get_column_categories and PolarsFrame sector accessor
  • polars_frame: Extract _build_grouped_op() and _build_sector_agg() helpers, unifying expression construction logic in _CrossSection and _SectorOp
  • dataframe: Refactor FinlabDataFrame into a package (finlab/dataframe/), containing core.py, weight.py, cs.py, sector.py, existing import paths unaffected
  • dataframe: Add from finlab import FinlabDataFrame top-level export
  • dataframe: Extract _get_column_categories() as shared helper, eliminating duplicate logic between groupby_category and industry weight methods

Fix

  • analysis: Fix calc_shapley_values and calc_factor_return always raising ValueError due to using Python not on pandas boolean Series instead of element-wise ~ operator (#71)

Docs

  • market: Fix non-existent dataset name etl:us_adj_close in docs, corrected to us_price:adj_close (#68)

Chore

  • Add polars as optional dependency (pip install finlab[polars])

Tests

  • Add 34 tests covering rolling extensions, cs accessor, sector AST nodes and expression construction
  • Add 68 tests covering all new weight / cs / sector methods
  • Add unit tests for calc_factor_return and calc_shapley_values, verifying mask operations and input validation

1.5.13 (2026-03-22)

Features

  • data: Add index parameter to universe(), us_universe(), set_universe(), set_us_universe() for filtering US stocks by market index (S&P 500, NASDAQ 100). Combinable with sector, industry, exchange (#55, #57)
  • market: Add Taiwan convertible bond market (TW CB Market) with to_html support in finlab_core (#64, 399e789)

Fix

  • storage: Fix _check_and_apply_reset_time being redundantly checked across multiple Python processes. Use a marker file to record applied reset timestamp and expiry.pkl mtime, shared across processes. Also fix bug where save_expiry() failure still wrote the marker, causing subsequent resets to be permanently skipped (34c5055)
  • analysis: Fix MaeMfeAnalysis.calc_edge_ratio() ZeroDivisionError when entry_price is zero in US market backtests, and deduplicate edge ratio computation in display() (#45, #66)
  • compat: Replace deprecated pandas resample aliases ('M', 'Y', 'A') with 'ME'/'YE' (pandas ≥ 2.2), centralize to finlab.compat.MONTHLY_END / YEARLY_END constants, and fix string-based version comparison bug (#63)
  • portfolio: Fix PortfolioSyncManager.from_cloud() / to_cloud() using wrong token parameter name (hardcoded api_token instead of token_type), and fix notebook.py passing tuple instead of string (#52)
  • hold_until: Fix ValueError in hold_until() under pandas 3.0 Copy-on-Write mode (#67)
  • report: Fix position2 not populated with trade data and incorrect entryAdjPrice calculation (d89f782)
  • report: Fix "hold" actions not normalized in cloud report round-trip, and auto-rebuild stale Cython modules (c476cba)
  • report: Fix updated_at not propagated to positionConfig.created in CloudReport.__init__ (26eb765)
  • online: Update submodule — fix token_type not routed correctly in dashboard API calls (87ecf68)
  • data: Fix trailing delimiter in IndicatorName.decode for parameterless indicators (87e3c80)
  • data: Fix universe not reset after big_investments(), causing column mismatch in subsequent strategies (0c84806)
  • compat: Fix _pd_version parser failing on pandas prerelease version strings (5399d97)

Refactor

  • deprecation: Improve deprecation warnings to show once, extract deadline constant, deduplicate auth imports (b7f6072)

Docs

  • backtest: Update sim() docstrings and fix batch order example — progress applies to remaining delta (#56)
  • portfolio: Remove non-existent create_report() and get_returns() from Portfolio examples (#51)

Tests

  • Fix 14 test failures across auth, projection, and E2E suites (a194ea1)

Chore

  • Bump Docker base image to Python 3.12 and update dependencies (66a44df)
  • Add twine to dev dependencies (28bb8eb)

1.5.12 (2026-03-17)

Fix

  • data: Fix data.get() returning stale data in long-running sessions (e.g. Google Colab) — _loaded_datasets was completely skipping expiry checks. Now checks local expiry time and triggers merge/download when expired
  • online: Fix Sinopac broker hardcoding all stock contracts to TSE exchange, causing OTC stock real-time quote subscriptions and tick backfill to fail. Now dynamically detects TSE/OTC via snapshot API and caches results (e21f7fc)

1.5.11 (2026-03-11)

Features

  • report: Migrate report payload to canonical Firestore flow (users/{uid}/reports/{sid}) with cloud function projection for legacy docs (4719592)
  • data: Add data.get_role() and data.is_vip() for querying user role (e282344)

Fix

  • backtest: Fix sim() upload using daemon thread, causing upload to be killed on script exit (9b0b4c5)
  • data: is_tradable() now returns False when no expiry data available (conservative: can't verify freshness → don't trade) (9b0b4c5)
  • data: is_tradable and next_future_expiry now only check session-loaded datasets (b16eda4)
  • report: Fix report projection legacy parity (daily_mean, return_table, drawdown_details, trail_stop) (83a4e33, dea8afa)
  • report: Strip time-series arrays from Firestore legacy docs to avoid 40K index limit (9af94d9)
  • report: Fix market-close timestamp timezone normalization (91ba4dc)
  • report: Keep cloud report schedulers and execution in sync (11ef166)
  • report: Tighten cloud report migration validation (297de5e)
  • storage: Make file storage writes atomic across processes (8436ab8)
  • analysis: Fix LiquidityAnalysis mutating report.trades causing intermittent KeyError (a14d9fb)
  • docs: Fix i18n alternate links and redirect Location headers (784e4a1, e58b085)

Tests

  • Add E2E parity test verifying report projection legacy docs match old write_database output (5d893a3)
  • Tighten E2E parity test: compare stats, trades, all position fields and strategy summary (f2e5929, d702a84)
  • Add firebase admin report migration test coverage (7358a45)
  • Add market close timestamp normalization tests (d747ccc)
  • Fix test_data_freshness tests to align with scoped expiry behavior (9b0b4c5)

Chore

  • online: Update submodule — add Stock.pct_change across all brokers (94032d5)

1.5.9

Refactor

  • analysis: Remove Report subclass (~270 lines); to_text() and to_terminal() are now provided directly by the Report class in finlab_core. from finlab.analysis import Report still works (#43)

Features

  • data: Add an 80% quota-usage warning so data.get() notifies users before the quota is exhausted (#40)
  • schemas: Added finlab.schemas with formal dataclass/TypedDict contracts (PositionEntry, OrderEntry, PortfolioData, etc.)
  • online: OrderExecutor.generate_orders() now supports as_entries and quantity_type, with a typed convenience API generate_order_entries()
  • portfolio: PortfolioSyncManager now provides typed data access APIs: get_data() / set_data() and get_data_typed() / set_data_typed()

Fix

  • dataframe: Fix path-matching failure in FinlabDataFrame.__setattr__ on Windows that caused internal set_index calls to be incorrectly blocked
  • backtest: sim() uses market-specific default fee_ratio and tax_ratio instead of fixed defaults (#38)
  • market: get_market_by_name() supports market short-code fallback (MARKET_CODE_TO_CLASS) (#37)
  • analysis: Fix the candlestick chart spinning indefinitely when a Firestore API request fails; show an error message with a retry button instead (#23)

Docs

  • Remove the git-clone install guide for the not-yet-open-source repository (#27)
  • Improve Market.get_price() docs: add full parameter descriptions, required return values, and implementation examples (#26)
  • Added a typed data migration guide and symbol / stock_id deprecation policy notes (docs/details/typed_data_interfaces.md)

Chore

  • Add Claude Code GitHub Actions workflow (#25)

1.5.8

Features

  • verify: Add verify_strategy(), an automatic detector for lookahead bias
  • dataframe: Forbid assigning directly to FinlabDataFrame.index to prevent lookahead bias
  • dataframe: rank() gains a valid parameter for filtering on valid values
  • data: Add next_future_expiry() to automatically skip expired data
  • data: Add a data-freshness check to make sure data is up to date before trading
  • terminal: Add report.to_terminal(), a terminal chart tool for viewing backtest results without Jupyter
  • auth: Switch to Firebase browser login, with automatic session naming, env-var authentication, and FINLAB_API_TOKEN migration prompts
  • compat: Full stock_idsymbol migration; stock_id remains available for backward compatibility
  • pyodide: report.upload() now runs synchronously in Pyodide environments

Performance

  • Overall strategy execution speedup of 3.4x (12.9s → 3.8s, covering data loading, signal computation, and backtest)
Step Before After Speedup
data.get (4 calls) 0.40s 0.00s
vol.average(20) 0.69s 0.62s 1.1x
pb.rank() 1.57s 1.04s 1.5x
rev.rank() 1.49s 0.50s 3.0x
is_smallest(10) 5.25s 0.40s 13.3x
sim() 3.30s 1.08s 3.1x
  • dataframe: is_largest / is_smallest switched to numpy argsort(kind='stable') instead of pandas apply(nlargest/nsmallest), preserving consistent column-order tie-breaking (13.3x)
  • dataframe: rank(axis=1) uses a numpy argsort fast path and ranks before index_str_to_date() expansion, avoiding ranking after quarterly data (51 rows) is expanded to daily (2110 rows) (3.0x)
  • dataframe: reshape() adds a fast path that skips reindex when two DataFrames already share the same index/columns
  • backtest: sim() uses prefer_local_if_exists internally to avoid redundant cloud expiry checks
  • backtest: Position normalization uses numpy array operations instead of pandas .div().fillna()
  • backtest: upload runs asynchronously on a daemon thread so it does not block backtest result return
  • backtest: Cache TWMarket._categories_cache to avoid repeated data.get('security_categories') calls
  • data: Add _finalized_cache to cache post-processed results from data.get(), skipping process_data conversion on repeat calls
  • data: Check expiry before reading the DataFrame to avoid unnecessary disk I/O
  • data: FileStorage.get_dataframe() skips the os.path.getmtime syscall on memory-cache hits

Fix

  • backtest: Fix a bug where touched_exit gap-open take-profit/stop-loss triggers multiplied position value by cr_old, inflating creturn. When the open price already exceeded the take-profit (or stop-loss) level, the touch_open path formula pos *= open_r / r diverged from touch_high/touch_low; corrected to pos = entry_pos * open_r
  • backtest: Fix floating-point drift in pdays (profitable days) calculation
  • analysis: Fix missing display() method on AlphaBetaAnalysis that caused run_analysis('AlphaBetaAnalysis') to produce no output
  • dataframe: Fix hold_until compatibility under Pandas 2.0+ Copy-on-Write
  • dataframe: Fix conversion error in is_largest/is_smallest when encountering pd.NA
  • dataframe: Replace eval() with ast.literal_eval() in industry_rank to fix a security issue
  • data: Fix truncate_end quarterly-financial truncation logic by using a disclosure-date mask, preventing accidental removal of already disclosed data
  • data: Fix _finalized_cache not including universe and truncate in its cache key
  • data: Fix _get_expiry_dict not filtering already-loaded datasets
  • storage: Fix missing mtime cache validation when sharing across multiple processes
  • portfolio: Fix Portfolio inconsistency when a strategy weight is zero
  • portfolio: Fix close-strategy incorrectly selling positions during open sync when historical data is empty
  • auth: Fix unnecessary browser login on failed token refresh
  • auth: Fix login() not checking the cached token first
  • auth: Switch to a stable machine ID instead of the unreliable uuid.getnode()
  • auth: Support id_token for backtest uploads and cloud data requests
  • sim: Fix pandas 3.0 compatibility when trade_at_price is a DataFrame

Docs

  • Add tutorials for neutralize / neutralize_industry
  • Add complete API reference and strengthen documentation structure
  • Add an introduction to the FinLab AI Skill (finlab.finance)
  • Fix incorrect take-profit / trailing-stop parameter names in the docs
  • Fix the erroneous description that trade_at_price='close' is a future-function
  • Fix ML strategy workflow docs that referenced a non-existent API

1.5.7 (2026-01-28)

Features

  • data: Improve data.search() — uses the Firestore API and simplifies output to a list of strings directly usable in data.get()
  • data: Support US stock data search (US catalog)

Refactor

  • data: Improve data-fetch and storage modules; extract shared helpers for readability

Fix

  • backtest: Fix pandas 3.0 ArrowStringArray compatibility — ensure DataFrame columns convert to a numpy array correctly
  • data: Narrow the exception scope in indicator() to avoid misleading TA-Lib install messages for invalid indicator names
  • data: Fix duplicate entries in the data catalog
  • tests: Fix randomness in the calc_regression_stats test by adding a fixed seed for stable results

Chore

  • Drop Python 3.8 support; minimum required version is now Python 3.9

1.5.4 (2025-11-21)

Fix

  • core: Fix Report error in is_rebalance_due when resample is a string
  • data: Fix FileStorage.get_time_expired failing to auto-update data when shared across multiple processes

Features

  • doc: Streamlined example documentation

1.5.4 (2025-11-14)

Refactor

  • data.universe: Refactor the universe module

Fix

  • core: Fix backward-compatibility issue in Report when is_rebalance_due is called

1.5.3 (2025-10-03)

Features

  • dataframe: Implement a truncation-window feature that accelerates data fetching based on finlab.data configuration

Refactor

  • data: Restructure the storage architecture and split modules (introduce storage.py, reshape __init__.py and universe.py) and integrate the truncation flow
  • portfolio: Streamline the trade-update flow; asset-value calculation now uses market-specific prices for greater accuracy

Fix

  • data.indicator: Correct adjust_price type validation to require booleans and improve error messages
  • label: excess_over_median/mean uses subtract for more consistent and readable arithmetic
  • backtest: Improve arguments resampling logic, unifying how resample_dates and position index types are handled

Docs

  • factor_analysis: Fix variable naming and add clearer examples; update navigation and tutorial content
  • docs: Remove navigation entries that no longer exist; update example docs and mkdocs settings

1.5.0 (2025-08-01)

Features

  • factor_analysis: Add factor-trend analysis along with short example documentation
  • plot: Add a unified plotly style with multiple color ranges and marker support; adds configurable color bands for line charts
  • plot: Enhance plot_line with advanced customization options and comprehensive examples; add plot_line_example and plot_line_financial_example
  • tests: Add support for serializing backtest results to pickle

Refactor

  • factor_analysis: Rename functions and parameters for clarity; update docs to reflect the changes
  • docs: Update the changelog and adjust module structure / naming

Fix

  • data: Add use_local_data_only and force_cloud_download options
  • feature: Improve market-configuration logic to correctly restore the original market setting in multi-core environments
  • liquidityAnalysis: Ensure trade-price and volume shapes stay aligned and convert them to DataFrame format
  • backtest: Fix position-filter logic so only valid market data is retained and converted to floats
  • doc: Fix plotly rendering issue (switch to static png)

Docs

  • Add the factor-crowding analysis page to navigation
  • Add simplified tutorials and refresh the practical-example tutorial for clarity
  • Update the practical-example documentation
  • Add KaTeX support for math rendering and remove outdated factor-crowding analysis
  • Add Yuanta Securities setup instructions to the order-API docs and remove the outdated PE-PB chart image
  • Fix Yuanta Securities references in the order-API docs

1.4.0 (2024-05-29)

Features

  • portfolio: Add get_total_position to return current holdings as a DataFrame
  • pyproject: Add shioaji support to the dev group

Refactor

  • backtest: Replace Exception with ValueError and TypeError for better error handling
  • market: Convert the Market class to an abstract base class and update the tw market

Fix

  • qlib: Improve error handling for a missing finlab[qlib] module with a more detailed message
  • data: Add use_local_data_only and force_cloud_download features
  • data: Update the get return type to FinlabDataFrame
  • data: Include additional exports in __all__
  • pytorch_nn: Remove a broken import and add ICLoss for information-coefficient loss
  • portfolio: Improve the remove-position logic and tighten update conditions
  • docker: Pin the finlab version to 1.4.0

1.3.0 (2024-05-24)

Features

  • online: Add pocket-account integration
  • fubon: Add the Yuanta Securities order-entry system
  • data: Add entry names for financial-data indicators
  • dataframe: Add a lookahead warning to the rank method
  • setup: Add classifiers for Python 3.7 and 3.8
  • requirements: Add Jinja2 and ipython
  • test: Add pytest as a dev dependency with a slow marker
  • Migrate to uv for dependency management

Refactor

  • alphalens: Remove the alphalens module and related features
  • portfolio: Improve position-removal logs in PortfolioSyncManager
  • backtest: Comment out unused global-report setup code
  • plot: Remove obsolete plot tests from plot_test.py
  • ml: Improve factory initialization and type hints in the combine function

Fix

  • setup: Enable find_namespace_packages and improve path handling
  • liquidityAnalysis: Fix disposition-stock detection logic and the date baseline for limit-up/down evaluation
  • docker: Update pandas and ta-lib versions
  • backtest: Update the backtest-upload message
  • ml: Fix variable reference in the combine function
  • analysis: Fix the end date used by drawdown
  • parallel: Fix ParallelExt compatibility with newer joblib versions
  • pyproject: Pin the Cython version for compatibility

Docs

  • docs: Rename getting-start.md and update mkdocs.yml
  • order_api: Update certificate acquisition and package installation instructions

Type Safety

  • core: Add type hints for FinlabDataFrame and the backtest module

1.2.27 (2025-05-15)

Features

  • Add the Yuanta Securities order-entry system
  • finlab.ml.feature.combine supports a dictionary of functions for feature generation
  • finlab.dataframe.FinlabDataFrame: Refactor rank to automatically handle cross-sectional comparison on financial reports, preventing potential lookahead bias
  • finlab.dataframe.FinlabDataFrame: Refactor rank to warn users when lookahead is possible

Fix

  • Fix qlib model reference

1.2.24 (2025-05-02)

Features

  • Integrate the full qlib feature set into finlab.ml; installing finlab is now enough to use qlib features (pip install finlab[qlib])

Refactor

  • report: Support report.to_html(path) for exporting the report to an HTML file
  • report: Support report._repr_html_() for direct display inside Jupyter notebooks
  • Move dashboard out of the report module into a standalone finlab.core.dashboard module

Fix

  • Fix minor data errors in report.trades related to warning stocks, disposition stocks, and full-delivery stocks
  • Fix report.weights.name and report.next_weights.name possibly being None

1.2.23 (2025-03-25)

Fix

  • Fix report.upload raising when resample=pd.DatetimeIndex

1.2.22 (2025-03-25)

Features

  • PositionScheduler supports multiple strategies and rebalance logic
  • backtest.sim automatically computes the next trading day when resample=None

Fixes

  • Update the macOS build architecture setting to keep only universal2
  • Fix resample parameter handling so it can be used directly
  • Adjust PositionScheduler.from_report to match the new resample logic
  • Update and fix associated unit tests

1.2.21 (2025-03-12)

Features

  • report.is_stop_triggered() detects whether stop-loss / take-profit has fired
  • report.is_rebalance_due() detects whether a rebalance is due
  • report.to_pickle('PATH') saves the report as a pickle file
  • report.from_pickle('PATH') loads the report from a pickle file
  • backtest.sim backtest-speed optimization

Fixes

  • PortfolioSyncManager handles the weight = 0 case
  • data.get retries automatically on download errors
  • backtest.sim skips symbols that throw exceptions automatically
  • backtest.sim fixes incorrect short-return display

1.2.20 (2024-12-09)

Refactor

  • MarketInfo is moved into the finlab.market module
  • TWMarketInfo is moved into finlab.markets.tw and renamed to TWMarket
  • fix(market_info): rename loop variable for clarity in shared memory creation
  • Use finlab.config.set_market for setting the global market info
  • Remove ml.get_market and ml.set_market; use finlab.config.set_market instead
  • Remove data.indicator(...market) in favor of finlab.config.set_market
  • Remove df.hold_until(...market) in favor of finlab.config.set_market

1.2.17 (2024-10-19)

Features

  • Rename report.weight.name to the backtest's last date for easier inspection
  • Rename report.next_weight.name to the rebalance date for easier inspection
  • Support numpy>=2.0; note that talib does not yet support it, so talib users must wait
  • Position supports optional weight storage and calculation for quick comparison between lots and weights
  • FugleAccount switches to websocket for order connection and updates
  • OrderExecutor gains progress, which interpolates between "current positions" and "target positions" for smoother rebalancing

Fixes

  • finlab.online.sinopac no longer errors when a stock has no trades for the day

1.2.16 (2024-10-02)

Fixed

  • data.get reduces unnecessary network calls
  • cli: Fix an unnecessary webview import error
  • finlab.online.sinopac: Fix get_trades converting timestamps to UTC when computing times
  • finlab.portfolio: Fix PortfolioSyncManager.to_cloud and to_json possibly producing incompatible formats

1.2.15 (2024-09-08)

Fixed

  • position.from_report: Fix weight.index being non-string
  • finlab.portfolio: Fix error raised when holding untradeable stocks
  • finlab.online: Fix error raised when attempting to trade untradeable stocks (now raises a warning instead)
  • finlab.data: Fix data.search returning empty results
  • finlab.portfolio: Fix stop-loss / take-profit being skipped at certain moments

1.2.12 (2024-8-27)

Features

  • dashboard: Add "market correlation" panel with a selectable time range
  • portfolio: Add PortfolioSyncManager.get_position(at='open') for planning the day's open positions
  • online.position: Improve position display
  • online.position: Add the ability to iterate over position info with a for-loop
  • tool.factor_analysis: Add factor-analysis features — in addition to IC, supports get_metric for computing various factor metrics
  • portfolio: PortfolioSyncManager auto-detects when smooth_transition should kick in — no smoothing on init, smoothing afterwards
  • doc: Improve the portfolio order-placement tutorial
  • sinopac: Sinopac Securities supports get_trades for reconciling account trade records

Fixed

  • data: Fix a circular import triggered by data.get on some operating systems
  • cli: Fix the finlab nb command triggering import webview

1.2.11 (2024-8-19)

Fixed

  • backtest: Fix stop-loss / take-profit occasionally using future data
  • test: Use historical data when testing the backtest system
  • report: Fix incorrect industry display in the backtest report
  • online: Fix too many decimal places being shown when placing orders
  • schedule: Fix strategy execution using the wrong token
  • portfolio.cloud_report: Support int-typed returns (used in rare cases)
  • backtest: Hide out-sample data when backtesting in-sample
  • data: Auto-abort downloads that exceed 5 minutes with an error message

1.2.9 (2024-8-3)

Feature

  • finlab.portfolio: PortfolioSyncManager.update accepts custom_position to set per-stock lot counts
  • finlab.portfolio: PortfolioSyncManager.update accepts excluded_stock_ids to ignore specified stocks

1.2.8 (2024-8-1)

Fix

  • Fix backtest errors in certain conditions

1.2.7 (2024-8-1)

Fix

  • Fix return calculation error when stocks settle at a non-close price
  • finlab.portfolio: Suppress unnecessary warnings from PortfolioSyncManager.update

1.2.5 (2024-7-29)

Feature

  • Stock dashboard: Add an option to hide stock names

Fix

  • Fix the stock dashboard so open_close_avg is labeled "average price"
  • Fix return calculation: inter-period transitions no longer accrue trading fees
  • Fix NaN handling in the dashboard

1.2.4 (2024-7-28)

Feature

  • finlab.portfolio: PortfolioSyncManager gains to_file and from_file for loading and saving data

Fix

  • finlab.portfolio: Fix PortfolioSyncManager error when handling odd lots
  • finlab.portfolio: Fix PortfolioSyncManager odd-lot values displayed to four decimal places

1.2.2 (2024-7-27)

Fix

  • finlab.cli: Fix the nb command erroring when not yet initialized
  • finlab.portfolio: Raise a more detailed error when the cloud strategy download cannot find the strategy
  • finlab.portfolio: Fix error raised when live_trading_performance is None
  • finlab.portfolio: Fix create_multi_asset_report path and return-value issues
  • finlab.portfolio: Fix errors in sync manager during stop-loss / take-profit
  • finlab.backtest: When resample=None, compute returns using holding-period returns
  • finlab.backtest: Fix NaN introduced by close-price settlement during intraday simulation
  • finlab.report: Fix exit-reason display when per-period returns are split

1.2.0 (2024-7-27)

Features

  • finlab.backtest: Add intraday dashboard and cumulative-return dashboard
  • finlab.backtest: Regardless of trade_at_price, all settlements now occur after market close
  • finlab.backtest: Open-price buy/sell with stop-loss / take-profit evaluated at the close
  • finlab.report: Add industry category to report.trades
  • finlab.portfolio: Add a new module for applying strategies to real portfolios
  • finlab.portfolio: Add tutorial documentation for using the module in real portfolios
  • finlab.cli: Add a CLI module for command-line operations and order placement
  • finlab.cli: Add tutorial documentation for using the CLI
  • Add docs describing how to use regex for industry selection
  • finlab.online: Enable automatic Fugle API login without manual password entry

Fix

  • finlab.sinopac: Fix account-balance calculation settling too early in the early hours of Sunday

1.1.6 (2024-7-11)

Fix

  • Fix offline-version data-cache reads during backtests
  • Fix Windows datetimeint32 conversion not being supported in backtests

1.1.4 (2024-7-9)

Features

  • Add strategy expiration time to remind users when data is stale and must be rerun
  • Backtest panel: Show entry and current prices together
  • Backtest panel: Reverse the default return display (most recent first)
  • Backtest panel: Improve holdings-price display

Fix

  • Fix finlab.tools.factor_analysis error caused by misaligned factor dates
  • Fix warning emitted under Pandas 2.2.0 when bridging to Pandas 3.0.0
  • ffn_core: Fix Tabular construction error
  • ffn_core: Fix Pandas 3.0.0 compatibility
  • Fix incorrect entry-price display on the backtest page
  • Backtest page: Fix stock history records
  • Backtest page: Account for recent maximum drawdown
  • Fix plot "annual average return" to handle the no-backtest case

1.1.3 (2024-6-4)

Features

  • Fix finlab.tools.factor_analysis and add multi-factor support
  • LINE Notify: Include the strategy name in notifications

Fix

  • Fix show_alerting_stocks not working

1.1.2 (2024-5-23)

Feature

  • Add the finlab.tools.factor_analysis module for factor analysis

Fix

  • Fix handling of NaN in prices
  • Fix multi-core processing logic in finlab.ml.feature.ta that raised on single-core machines
  • Fix the reference timing for the next rebalance: use the current close-price date instead of the position-change date to avoid referencing the wrong price on the next rebalance
  • Fix finlab.ml.qlib.get_models models producing inf or NaN labels during training

Refactor

  • Refactor bank-balance and settlement messaging

1.1.1 (2024-4-25)

Refactor

  • Add "Required installation" and "Model library (optional)" sections to machine_learning.md to clearly separate install commands
  • Standardize and correct market_close_at_timestamp and tzinfo on the MarketInfo and TWMarketInfo classes in market_info.py for readability and consistency
  • Convert some methods from dynamic to static implementation to improve efficiency and reduce dependencies
  • qlib.py: Handle the segments parameter in WrapperModel.fit so that custom data segments are processed correctly

Fix

  • Fix logical-condition error in market_info.py, correctly distinguishing the conditional branches
  • Adjust NaN handling in data.py so that invalid data is excluded from indicator computations
  • Adjust the multi-core processing logic in feature.py's ta function based on core count to work correctly inside Docker
  • Fix label.py errors when calling maximum_adverse_excursion to ensure correct function behavior
  • Fix label.py errors when calling maximum_favorable_excursion to ensure correct function behavior

1.1.0

Features

  • Add support for Microsoft Qlib by adding the pyqlib dependency to the Dockerfile, letting users run Qlib directly inside the Docker container.

Fix

  • Fix inconsistent version numbers across multiple files, unifying the version to 1.0.10.
  • Refactor code in finlab/ml/qlib.py, removing outdated comments and unused code to improve clarity and maintainability.
  • Update the finlab/online submodule reference to pick up the latest features and fixes.
  • Simplify run_online_test.sh and run_all_test.sh, removing unnecessary comments and code for a leaner, more efficient test process.

1.0.6

  • fix(report): Fix importlib.resources not working on python<=3.6, python==3.8,3.7, python >=3.9

1.0.5

  • fix(report): Fix importlib.resources not working on python<=3.8

1.0.4

  • feat(backtest): Add tests related to backtests and instruments
  • fix(backtest): Fix the issue of removing next_weight force to 1
  • fix(us_market): Fix support for market_close_at_timestamp supporting None
  • chore(pandas 3.0): Support the new Pandas >= 3.0.0 new resample string format
  • feat(backtest): Add sl_enter and tp_enter to mark immediate stop loss / take profit held until the next rebalance

1.0.3

Fix

  • Support running backtests from the web frontend
  • Fix report.current_trades so that when a stock name is duplicated, the latest position takes precedence
  • Fix the dashboard's monthly revenue display: revert from 1st-to-31st back to the previous behavior (previous month 31st to this month 31st)
  • Fix trail_stop exiting too early when buying the same stock again
  • When entering a position the next day while simultaneously hitting stop loss / take profit, fix the report.action and report.next_weights display for stop_trading_next_period, and add unit tests.

1.0.2

Refactor

  • Remove the tailwind default css and switch to the style.css output by vite
  • Remove the web server and switch to an iframe docsrc (verified to work on all platforms)

Fix

  • Fix the web server port being unusable when displayed on docker

1.0.1

Features

  • Display trailing stop loss
  • Control light/dark mode from the top-right of the dashboard
  • Save the dashboard to a specified path

Fix

  • Fix the issue caused by the default read/write encoding of report being cp950 on Windows.
  • Fix stop loss not being displayed
  • Adjust CSS fonts and layout on Colab
  • Make chart axis colors responsive to light/dark mode
  • Fix chart memory not being released, which caused delayed tab switching

1.0.0

Features

  • Add unit tests for Position.from_report
  • Test report.next_weights under a variety of conditions
  • Launch the brand new dashboard interface
  • Support Python 3.12

Fix

  • Fix normalization of report.next_weights when stop loss or take profit is enabled
  • Fix categorical columns not being indexed correctly by Pandas's reindex function
  • Fix plotting errors for categorical columns when adding operators

0.5.13

Features

  • Integrate Pytest (commit e7a487c): Add Pytest to make testing more efficient.
  • finlab.ml intraday return calculation (commit 8804fb1): Add a label for computing intraday returns.
  • finlab.ml.feature.ta multiprocess feature computation (commit 1ab0463): Introduce multiprocess support in the feature computation module for better performance.

Fix

  • Optimize the get_location function (commit 253e98c): Improve get_location in data.py to handle failure cases better.
  • Timezone support in market info (commits aa2756b & 79b3671): Add timezone handling in market_info.py.
  • Trailing stop loss fix (commits 6522bf7 & e7fc1f3): Adjust trade calculations in backtest.py and fix trailing stop loss behavior.
  • Dataframe import fix (commit 626ada1): Fix the import issue in dataframe.py.
  • Feature initialization fix (commit 772d659): Fix the initialization issue in ml/feature.py.
  • Force cloud download (commit 7ec28a3): Fix the force_cloud_download implementation in data.py.

Other updates

  • Refactor (commit 26d1518): Refactor the online module for a better code structure.
  • Documentation updates (commits 44a93d4, 9f5683f, cd4a894): Update the documentation for backtest.py, data.py, and ml/feature.py.
  • Version update (commit d361d7f): Bump the version to 0.5.13.
  • Increase test coverage (commit 350dfbc): Increase test coverage in the Docker configuration.
  • Test system robustness (commit 1647479): Improve the robustness of the test system.
  • Online test Position.to_list (commit f3d086f): Update online_test.py to add list-conversion coverage.

0.5.12

  • Fix online test price update in run_online_test.sh to include FUGLE-configured environment variables.
  • Adjust test_update_price in online_test.py to compare floats correctly.
  • Modify event_study.py to work with non-trading days by reindexing against business days.

0.5.11

  • Fix an error being thrown when position is zero

0.5.10

  • Fix Sinopac API orders larger than 1000 NTD failing to place
  • Fix the FinlabDataframe memory leak error
  • Fix the login UI style to avoid errors when logging in from Colab
  • Fix data.search

0.5.9

  • Fix the reshape issue in dataframe operator arithmetic
  • Fix df[bool_selector] not working

0.5.8

  • Improve the speed of data.get
  • Improve Sinopac API order-placement efficiency (though this introduced some issues, which have been fixed)

0.5.7 (2023-11-4)

Fix

  • FinlabDataFrame: Fix the __hash__ method to correctly use a UUID when none is set.
  • hold_until method: Fix the reindex handling of self, exit, and rank.
  • market_info.get_market_info: Correct the reindex logic to ensure the updated index is used.
  • fetch_data: Fix the daily-average calculation in the report section.
  • data.py: Add a User-Agent header to HTTP requests to prevent fetch errors.
  • data.py: Fix saving an empty DataFrame.
  • ffn_core.py: Fix the divide-by-zero bug in calc_sharpe.

Features

  • tools: Add finlab.tools.event_study for event-trading research and related features.
  • backtest.py: Introduce fast_mode for fast backtests that skip stop loss / take profit.
  • dataframe.py: Cache the index_str_to_date method for better performance.
  • report.add_trade_info: Use Cython to speed up the computation.
  • setup.py: Enable O3 optimization when compiling the Cython extension.
  • backtest.py: Add documentation for the sim function covering the new features and parameters in detail.
  • dataframe.py: Implement index optimization, converting string indices into dates and caching the result.
  • Adjust setup.py to change the Python requirement from >=3.7 to >=3.6.
  • Update submodules to their latest commits.

Tests

  • Add tests for the report_test.py module to guarantee correctness of the query functionality.
  • Add multiple test cases covering different data types in report_test.py.
  • Update the run_test_docker.sh script to include the new test cases.

0.5.2 (2023-09-28)

Fix

  • Fix a recursive-import issue that appeared on a few operating systems
  • Fix liquidity analysis where NaN values were being silently cast to float by Pandas
  • trade_at_price fix
  • Fix excessive memory consumption when attempting to merge

0.5.0 (2023-09-14)

Features

  • Add a trailing stop loss feature via sim(..., trail_stop=0.1) to configure the trailing stop.
  • data.universe supports market='etf', and also categories such as domestic_etf, foreign_etf, leveraged_etf, vanilla_futures_etf, leveraged_futures_etf.
  • data.get supports updating data from both US and Taiwan servers, automatically choosing the closer server.
  • data.get automatically detects and links Google Drive to store downloaded data.
  • data.get now fully supports local-side data updates: instead of re-downloading everything, patches are fetched and applied locally, and a full reset only runs when necessary (enabled by default).
  • sim(..., trade_at_price) lets you simulate trades at other prices: 'close', 'open', 'open_close_avg', 'high_low_avg', or 'price_avg'.
  • Add underlying features to ensure compatibility with the new website.

Fixes

  • Fix stop loss / take profit for short positions
  • FinlabDataFrame.hold_until now returns bool (previously int)
  • FinlabDataFrame has broader support for auto-reshape and fill arithmetic, e.g. &= and += are now supported
  • Remove the force-configured logger
  • finlab.online: Fix the timezone issue when fetching total balance.
  • data.FileStorage: Fix file-path errors on Windows.
  • ffn: Remove soon-to-be-unsupported syntax and update to pandas 2.1 compatible syntax.
  • Auto-detect and convert position.index to datetime inside backtest(position)
  • Fix upload failures when report.trades is too long
  • Fix a backtest bug where an instrument that exited last period was not re-entered this period

0.4.6 (2023-08-11)

Fixes

  • Fix aggressive-pricing orders (extra_bid_pct) failing when the order price exceeds the daily price limit; the order price is now capped at the upper/lower limit.
  • Fix the order-placement API mis-judging stop loss / take profit positions in Position.from_report.
  • Fix the Sinopac API's failure to modify the price of odd-lot orders by auto-cancelling and re-placing the order.
  • Change the monthly-revenue index to datetime format, fixing the issue where data.set_storage mode forced a re-download of monthly revenue data.
  • Prevent NaN values from appearing in finlab.dataframe.industry rank().

Features

  • Add strategy-return statistics plotting via finlab.plot.StrategyReturnStats.
  • Fugle Market Data API v1.0 is now compatible with finlab.online; v0.3 is not supported. Users are reminded to upgrade the Market Data API from v0.3 to the latest v1.0, as Fugle will deprecate the old version. Note that v1.0 uses a different authentication scheme, so v0.3 API keys cannot be used with v1.0 HTTP and WebSocket APIs. You will need to re-apply for an API key to use the latest API; please visit the key application page.
  • Add aggressive-pricing (extra_bid_pct) support to the order-placement API's "update order price" flow: buy at x% above the last trade price, sell at x% below the last trade price.

0.4.5 (2023-07-05)

Fixes

  • Fix hold_until ranking breaking when the rank parameter is inf.
  • Fix the alphalens incompatibility with pandas 2.0.
  • Fix the Sinopac API failing to place odd-lot market orders; these are now placed at the daily price limit instead.
  • Fix the title display offset on the candle plot.
  • Fix report.position being reused in sim to produce consistent results.
  • Fix the edge-ratio time-series sorting; results can now be sorted in chronological order.

Features

  • Add us_universe to select US sub-industries.
  • Add aggressive-pricing support to the order-placement API: buy at x% above the last trade price, sell at x% below.

Doc

  • Add a US-market strategy example for users to reference and learn from.
  • Add documentation for the market parameter in data.indicator when using US data, making it easier to understand how to use it.

0.4.3 (2023-05-11)

Warnings: Backtesting result and performance will change.

Features

  • Improved RAM usage by removing sorting and swaplevel for machine learning features (e081c924).
  • Optimized backtest report (8babbd7a).
  • Implemented cross-validation for machine learning (e55828c0).
  • support infomation for stop loss and take profit assets (5f9272f3).
  • Hold_until functionality made available for US data (8437d62).
  • Added indicators control in plot_stats (7364d58).

Fixes

  • Fixed deadline considering business date for DataFrame (312f2fe1).
  • Fixed the issue where a float object had no attribute 'month' (d51a5901).
  • Fixed run_all_test (6203f56f).
  • Prevented deletion during map iteration in backtest_core (2d1d9b05).
  • Fixed login info (d177ed47).
  • Fixed alpha annualize estimation in analysis (26a8becf).
  • Fixed issue with short selling in online module (919521b9).
  • Synced win_ratio in maeMfeAnalysis (a9a31189).
  • Added rotc deadline in DataFrame (ac10597).

Refactoring

  • Refactored f_disclosure_date to_business_date, removed date too far, and improved speed (7dcb203b).
  • Refactored market selection according to DataFrame columns (039cbc96).
  • Fixed bugs and future warnings in the analysis module (ec93088f).
  • Refactored environment name capitalization in login module (635caed4).
  • Refactored login to use FINLAB_API_TOKEN (a5c9064d).
  • Informed free users that data is limited (bbabad14).

Tests

  • Added test_hold_until (ccc4ba89).

Doc

  • Updated daily_sortino documentation (b7d1d91d).
  • Updated get_data documentation (276862c2).

0.4.2 (2023-04-27)

New features

  • Add label trade-price support in machine learning
  • Add usage documentation for report.display() in reports
  • Add US market information to market info

Fixes

  • Fix display-string issues in the online module
  • Revert the backtest feature to a stable version
  • Adjust how the backtest feature updates holdings based on entry/exit prices
  • Fix detection of qlib.init
  • Fix benchmark-index timezone in reports
  • Handle pandas 2.0.0 compatibility issues
  • Handle the talib dependency issue
  • Fix entry/exit ratios becoming NaN in the backtest feature
  • Fix the fugle Account numpy reference in the documentation

Other

  • Add related docs in the machine-learning module
  • Add related docs in the market-info module

0.4.1 (2023-04-14)

  • (fix): fugle np not found

0.3.19 (2023-04-04)

  • (improve): memory usage in machine learning feature creation
  • (improve): machine learning feature for different freqnecy index
  • (fix): data.indicator support almost all talib functions
  • (fix): 2023/4/10 monthly revenue reveal change to 2023/4/12
  • (fix): sinopac calculate account balance

0.3.18 (2023-03-28)

  • (Breaking): update shioaji >= 1.0.0. Please refer to finlab.inline module
  • (feat): finlab.ml (document are not ready yet)
  • (feat): support qlib data
  • (feat): report add yearly and monthly return table
  • (fix): backtest entry exit signal both activate conflict

0.3.12 (2022-11-29)

  • (Breaking): report.get_stats() has new format
  • (feat): data.get now read expire date from server and update data dynamically
  • (feat): add a bunch of analysis for backtesting report
  • (feat): getpass password to hide api_token
  • (fix): report.weight and report.next_weights remove considering of price changed
  • (fix): backtest(..., resample_offset='10d') fix backtesting display date
  • (fix): finlab.online.order_executor show_alerting_stocks fix price
  • (fix): fugle order status not change even when it is filled
  • (fix): support update price of fraction lot size

0.3.11 (2022-11-10)

  • (Fix) finlab backtest asset shorting fee miner adjust
  • (Fix) finlab.report.weights and finlab.report.next_weights not defined
  • (Fix) fugle-trade remove flag accoding to 0.4.0
  • (Fix) fugle-trade fetch other source when stock.close is nan
  • (Fix) fugle-trade FugleAccount.get_position not latest position
  • (Feat) finlab.data.universe('STOCK_FUTURE') subset of TWII stocks
  • (Feat) add yearly return when upload report
  • (Feat) add fugle_trade version not compatable warning

0.3.10 (2022-10-13)

0.3.9 (2022-10-13)

  • (Fix) finlab.online.sinopac_account order_lot position zero
  • (Fix) finlab.online.fugle_account order_lot position duplicated
  • (Fix) finlab.backtest weight display remove normalized
  • (Fix) finlab.data windows FileStorage fix
  • (Fix) finlab.data indicator exception error

0.3.8 (2022-9-27)

  • (Fix) finlab.online.order_executor price +-10% limit order restricted
  • (Fix) finlab.online.order_executor Position.from_report handle price=0, weight=0, and duplicated stock id
  • (Fix) finlab.plot.StrategySunburst compatibility
  • (Fix) finlab.report.display display multiple chart

0.3.8.dev1 (2022-9-27)

  • (Fix) talib abstract module incompatible
  • (Fix) backtest result: alpha and beta
  • (Fix) finlab.online.panel
  • (Fix) finlab.online.fugle_account stock not traded error
  • (Fix) add cert custom password for sinopac
  • (Fix) remove duplicated columns from unnumeric_dtype.
  • (Fix) KY company disclosure deadline
  • (Chore) Candlestick data format generalized
  • (Chore) raise error when data.get not found
  • (Chore) logger.info to logger.warning in finlab.data
  • (Chore) fig return for report.display
  • (Feat) add retain_cost_when_rebalance flag

0.3.7.dev1 (2022-8-8)

  • More granular backtesting for touched_exit:
  • Previously, a stock that touched the target and bounced back would not be marked as a touched sell; now it is simulated as a touched sell.
  • Previously, a gap-down open meant the stock could not be sold at 0.07; now it will also be sold at the lower level.

0.3.5.dev (2022-7-18)

  • Add finlab.optimize for enumerating parameter combinations in backtests
  • Add the mae_mfe chart
  • mae_mfe short-side analysis
  • Rename report.get_trades()['position'] to weighting
  • backtest touched_exit fix
  • Fix bugs in finlab.analysis

0.3.3.dev (2022-7-1)

Bug fixes

  • Fix the weight display for short positions
  • TreeMap plotting fix
  • Fix historical financial-report publication times

Analysis — analyze backtest results

Add an Analysis framework that can fully analyze backtest results. Future analyses will inherit from Analysis and render charts, making reports richer.

liquidityAnalysis — liquidity test

A strategy simulates buying and selling at the close or open price, but in reality a stock may not trade successfully — for instance a disposition stock, a fully-delivered stock, or a prolonged limit-down. liquidityAnalysis checks whether any such instruments were bought during the backtest and computes their proportion, so you can ensure the strategy's liquidity matches your capital requirements. See the tutorial article for more detail.

report.run_analysis('LiquidityAnalysis')

inequalityAnalysis — inequality test

If you already have a strategy and want to add additional technical, chip, or profitability indicators, inequalityAnalysis lets you inspect whether they improve stock-selection performance. For example, to look at how the price-to-book ratio further filters stocks, use:

report.run_analysis('InequalityAnalysis', name='price_earning_ratio:股價淨值比')

Refer to the tutorial article for how to read the results.

0.3.2.dev (2022-6-23)

SunBurst — inspect strategy positions

Display the industries represented in the current holdings and which industry is weighted most heavily. See details!

Short selling and per-stock weights

The FinLab Package now supports short selling. If you already have a good strategy, try shorting 0050 — returns may drop slightly, but risk shrinks substantially, which is great for allocating capital across multiple stocks.

Also worth noting: the new version allows position to use weights in addition to the previous boolean signals (True/False). So in the code below, 2330 is longed at 50% weight and 1101 is shorted at 50%.

This weighting scheme is fully backward-compatible with the previous True/False position style, because True is treated as 1 and False as 0 in computation. When all weights are 1, the program allocates capital evenly across assets as before.

from finlab import data
from finlab import backtest

close = data.get('price:收盤價')

position = close < 0
position['2330'] = 0.5
position['1101'] = -0.5

r = backtest.sim(position)
r.display()

Pandas_ta support for technical indicators

Pandas_ta has emerged over the last couple of years as a strong alternative for computing technical indicators, largely because TaLib can be quite hard to install and ships with a fixed set of roughly 100 indicators that rarely get updated. In contrast, Pandas_ta computes indicators in pure Pandas, which plays well across operating systems. It also covers many of the newer indicators, such as the supertrend indicator, along with less-common ones like "Even Better Sinewave", which sounds pretty interesting. You can find all of them in the Pandas_ta docs.

from finlab import data

values = data.indicator('supertrend')