Skip to main content

Defensive monitoring layer for finlab data.get API - detect unexpected data changes

Project description

finlab-sentinel

Python versions Windows Linux macOS License: MIT CI coverage

finlab-sentinelfinlab 套件的防禦層,用於監控 data.get API 的資料變化,防止未預期的資料異動影響回測或選股結果。

功能特色

  • 自動比對: 每次 data.get 時自動比對歷史資料
  • 滾動備份: 保留 7 天(可配置)的備份資料
  • 智慧檢測:
    • 數值容差比對(可配置 rtol/atol)
    • dtype 變更檢測
    • NA 類型差異檢測(pd.NA vs np.nan vs None)
  • 彈性政策:
    • append_only: 只允許新增,不允許刪除或修改歷史
    • threshold: 允許小幅度變更(如 10% 以內)
    • 黑名單配置:指定可修改歷史的資料集
  • 可配置行為:
    • 拋出例外(預設)
    • 警告並使用快取
    • 警告並使用新資料
  • 通知機制: 支援自訂 callback(如 LINE、email 通知)
  • CLI 工具: 管理備份、查看差異、接受新資料

安裝

pip install finlab-sentinel

或使用 uv:

uv add finlab-sentinel

快速開始

import finlab_sentinel

# 啟用 sentinel
finlab_sentinel.enable()

# 正常使用 finlab
from finlab import data
close = data.get('price:收盤價')  # 自動備份並比對

# 如果資料異常,會根據配置拋出例外或警告

配置

建立 sentinel.toml 檔案:

[storage]
path = "~/.finlab-sentinel/"
retention_days = 7

[comparison]
rtol = 1e-5
change_threshold = 0.10

[comparison.policies]
default_mode = "append_only"
history_modifiable = ["fundamental_features:某些財報資料"]

[anomaly]
behavior = "raise"  # raise | warn_return_cached | warn_return_new
save_reports = true

# 可選:設定通知 callback
# callback = "myproject.notifications:send_line"

CLI 使用

# 列出所有備份
sentinel list

# 清理過期備份
sentinel cleanup --days 14

# 查看資料差異
sentinel diff "price:收盤價"

# 接受新資料作為基準
sentinel accept "price:收盤價" --reason "確認資料修正"

# 匯出備份
sentinel export "price:收盤價" -o ./backup.parquet

處理資料異常

當檢測到資料異常時:

from finlab_sentinel import DataAnomalyError

try:
    close = data.get('price:收盤價')
except DataAnomalyError as e:
    print(f"資料異常: {e.report.summary}")
    # 檢查報告詳情
    print(f"變動比例: {e.report.comparison_result.change_ratio:.1%}")

    # 如果確認要接受新資料
    from finlab_sentinel.core.interceptor import accept_current_data
    accept_current_data('price:收盤價', reason="確認資料修正")

自訂通知

def send_line_notification(report):
    """當檢測到異常時發送 LINE 通知"""
    import requests
    requests.post(
        "https://notify-api.line.me/api/notify",
        headers={"Authorization": f"Bearer {LINE_TOKEN}"},
        data={"message": f"finlab 資料異常: {report.summary}"}
    )

# 在 sentinel.toml 中設定
# [anomaly]
# callback = "myproject.notifications:send_line_notification"

開發

# Clone 專案
git clone https://github.com/yourusername/finlab-sentinel
cd finlab-sentinel

# 使用 uv 安裝開發依賴
uv sync --dev

# 執行測試
uv run pytest

# 執行 lint
uv run ruff check src/ tests/
uv run mypy src/

License

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

finlab_sentinel-0.1.1.tar.gz (43.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

finlab_sentinel-0.1.1-py3-none-any.whl (38.9 kB view details)

Uploaded Python 3

File details

Details for the file finlab_sentinel-0.1.1.tar.gz.

File metadata

  • Download URL: finlab_sentinel-0.1.1.tar.gz
  • Upload date:
  • Size: 43.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for finlab_sentinel-0.1.1.tar.gz
Algorithm Hash digest
SHA256 107c17c0055dee71c34ee76e58548436937c94ce96f789830d9bc94b7f396b1d
MD5 60e62f3989959900bb177090d4950dd0
BLAKE2b-256 2c926ccbe019688b020f0acff9eac6346746510b4db15b174d1337fd50dd0b45

See more details on using hashes here.

File details

Details for the file finlab_sentinel-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for finlab_sentinel-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 138a45cff7c28a56126318bb6843d7122245f64d914af797f65efec0cf894a22
MD5 41a70f67c3736b711e4a993c3127f551
BLAKE2b-256 899ce12c81c724e9912a0aa2d03190a5523441aeb70f908e0713eb1c3ea6da77

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page