アラートはHTTPの呼び出し時刻ではなく、新しく有効になったUSD/IDR観測値を前回の観測値と比較する。初回は基準値だけを保存し、古いデータやエラーでは状態を変えない。
- IDRの判定には
sources["IDR"]とeffective_at["IDR"]を使う。全体のsourceは要求した通貨の保守的な要約である。 - 最初の有効な観測は基準値だけ。閾値を越えたら一度だけ通知して解除し、後の観測が閾値未満に戻ったとき再武装する。
- 同じディレクトリの一時ファイルにJSONを書き、0600にしてから
os.replaceで置き換える。 - 10秒のタイムアウトを使い、キーは
EXCHANGERATE_API_KEYに置く。最小60秒間隔にし、429では状態を保ってRetry-Afterを守る。 - 完全なスクリプトをダウンロードし、閾値と状態パスをソース管理外で設定する。通知はローカルコンソールだけに出す。
通貨ごとの観測をモデル化する
IDRの判定には sources["IDR"] と effective_at["IDR"] を使う。全体のsourceは要求した通貨の保守的な要約である。
from decimal import Decimaldef idr_observation(payload: dict) -> dict: return { "rate": Decimal(str(payload["rates"]["IDR"])), "source": payload["sources"]["IDR"], "effective_at": payload["effective_at"]["IDR"], "market_session": payload["market_session"], }クロスポリシーを決める
最初の有効な観測は基準値だけ。閾値を越えたら一度だけ通知して解除し、後の観測が閾値未満に戻ったとき再武装する。
| 状況 | 状態の変化 | 通知 |
|---|---|---|
| 最初の有効観測 | 基準を保存 | なし |
| 閾値未満の新しい観測 | armed=true | なし |
| 武装中の閾値越え | armed=false | 1回 |
| 重複・古い観測またはエラー | 状態を維持 | なし |
状態を安全に保存する
同じディレクトリの一時ファイルにJSONを書き、0600にしてから os.replace で置き換える。
import jsonimport osimport tempfilefrom pathlib import Pathdef save_state(path: Path, state: dict) -> None: path.parent.mkdir(parents=True, exist_ok=True) fd, temporary = tempfile.mkstemp(prefix=f".{path.name}.", dir=path.parent, text=True) try: os.fchmod(fd, 0o600) with os.fdopen(fd, "w") as handle: json.dump(state, handle, sort_keys=True) handle.write("\n") os.replace(temporary, path) except Exception: try: os.unlink(temporary) except OSError: pass raiseネットワークとクォータを制限する
10秒のタイムアウトを使い、キーは EXCHANGERATE_API_KEY に置く。最小60秒間隔にし、429では状態を保って Retry-After を守る。 5分間隔の既定値は30日で約8,640回、60秒間隔は約43,200回で、共有クォータを超える可能性がある。
10秒のタイムアウトを使い、キーは EXCHANGERATE_API_KEY に置く。最小60秒間隔にし、429では状態を保って Retry-After を守る。
完全なモニターを実行する
完全なスクリプトをダウンロードし、閾値と状態パスをソース管理外で設定する。通知はローカルコンソールだけに出す。 既定の最大経過時間は1時間。日次参照や市場休場を使う場合はFX_ALERT_MAX_AGE_SECONDSを設定する。 python-exchange-rate-alerts.py
chmod 700 python-exchange-rate-alerts.pyexport EXCHANGERATE_API_KEY="your-key"export FX_ALERT_THRESHOLD_PCT="1.0"export FX_ALERT_POLL_SECONDS="300"export FX_ALERT_STATE_PATH="$HOME/.local/state/fx-alert.json"python3 python-exchange-rate-alerts.py市場を待たずにポリシーをテストする
初回、閾値未満、クロス、同じeffective_at、古い観測、再武装、二回目のクロスをネットワークモックでテストする。