ドキュメント1.0 (latest)
ページOHLCV とバーデータ · 10 / 29

OHLCV とバーデータ

QuantCraft のバックテストでは、取引するシンボルごとに OHLCV(始値、高値、安値、終値、出来高)のローソク足が必要です。エンジンはストラテジーが実行される前にそのデータを読み込み、各ステップで現在のバーのビュー(bar)を渡して、ストラテジーのライフサイクルのコールバックを駆動します。実行の終了時には、on_finish(bars, …) に渡される全系列を任意で扱えます。読み込みは Test(コードの実行)から設定します。

このページでは、データの取得元(ローダー)、日付範囲とウォームアップの仕組み、そして on_finish での全系列の bars 引数の使い方を説明します。価格と提出書類のデータを組み合わせる場合はファンダメンタルデータと併せて参照してください。取引と価格の関係についてはアカウントモデルを参照してください。


ローダー(データソース)

Run backtest の Symbol & data タブで価格フィードを選びます。エンジンは内部で、次の 2 つのローダーのいずれかを使います。

接続済みブローカーのフィード

  • あなたの接続済みブローカーアカウントから、API キーとシークレット、または有効なリンク ID を持つ OAuth 連携の接続を使ってローソク足を読み込みます。
  • 米国株と暗号資産をサポートします(アセットの種類はダイアログで選択)。
  • 多くの時間枠をサポートします。日足、週足、1 時間足、4 時間足、日中の複数の分足(アプリのチャートの時間枠ラベルに対応)。
  • 履歴は、要求した範囲が満たされるまで(従来の「日付を明示しない」モードでは最小バー数に達するまで)チャンクに分けて取得されます。

ブローカー接続のデータや日中の時間枠すべて(1 分から 4 時間、さらに日足と週足)が必要なときは、接続済みブローカーのフィードを使います。

QuantCraft ストレージ(ホスト型)

  • サインインしていれば、QuantCraft のホスト型ストレージからローソク足を読み込みます(アプリがセッショントークンを送信します)。
  • ファイルはシンボルと時間枠ごとに整理されています。無料プランでは、バックテストダイアログに日足、週足、月足が表示され、Premium で日中足と拡張時間枠が使えます。
  • ファイル全体を取得し、必要に応じて選択した暦日範囲に絞り込みます。
  • 日足バーの t は "2024-01-02" のような日付のみで、UTC として読み取られます。

QuantCraft B2 の時間枠コード: 1s、1m、2m、m5、15m、30m、h1、2h、4h、d、w、m、q、y。注意:m は月足であり分ではありません。1 分は 1m、5 分は m5 です。

日付範囲にバーがないと、No AAPL bars (d) between 2010-01-01 and 2010-02-01. Available range is … to … — adjust the backtest dates. のようなメッセージで読み込みが失敗します。

ブローカーの認証情報なしでサインインしているとき、または QuantCraft のシンボルカタログからホスト型の OHLCV バンドル(5 分、1 時間、日、週、月)が欲しいときは、QuantCraft ストレージを使います。

どちらを選ぶか

必要なもの一般的な選択
接続済みブローカーの日中の時間枠すべて(1m、5m、15m、30m、1H、4H など)接続済みブローカーのフィード
QuantCraft カタログの 5 分足または 1 時間足QuantCraft ストレージ
ホスト型ファイルの日足/週足/月足QuantCraft ストレージ
接続済みブローカーアカウント+キー接続済みブローカーのフィード
ブローカー認証情報なしのサインイン済みアクセスQuantCraft ストレージ

ストラテジーのコールバックでは、グローバルな OHLCV シングルトンではなく、エンジンが渡す bar オブジェクトから価格を読んでください。IDE では、モジュールレベルの qc_ohlcv はファイルの読み込み時に未設定のことが多く、それに頼ると壊れる可能性があります。また、スクリーナーターゲットの実行では None であり、設定されている場合でもウォームアップを含む読み込み範囲全体に及ぶため、チャートが描画する実行ウィンドウとは異なり、チャート系列のソースには不適切です。bar ビューは、現在のシミュレーションステップに対して常に正しい値です。


時間範囲

どのバーがバックテストに参加するかは、開始日、終了日、そして任意のウォームアップで制御します。

暦日範囲(start_date + end_date)

Simulation タブで両方の日付を設定した場合(形式は YYYY-MM-DD、UTC の暦日として解釈):

  • エンジンは、そのウィンドウに入るバーだけを保持します。
  • 範囲は半開区間として扱われます。開始日の始まりから終了日の終わりまで、製品の通常の慣例に従います(終了暦日のバーは、エンジンの設定どおりに含まれます)。

**接続済みブローカーのフィード:**その暦日の範囲でローソク足が要求されます。

QuantCraft ストレージ:ファイルの全系列がダウンロードされ、同じ暦日ウィンドウに絞り込まれます。

両方の日付を省略した場合:

  • 接続済みブローカーのフィードは従来の後方探索を使います。入力した固定の暦日ウィンドウではなく、十分な履歴が読み込まれるまで(時間枠の制限の範囲内で)エンジンが時間をさかのぼります。
  • QuantCraft ストレージはファイル内のすべてのバーを使います(追加のフィルターなし)。

ウォームアップバー(warmup_bars)

任意の非負の整数:インジケーターが履歴切れにならずにさかのぼれるよう、開始日より前に追加で読み込まれるバー。

  • ウォームアップバーは、最初の実行バーで bar.close[1]、bar.close[2]、…、および bar.bars_back から参照できます。
  • on_bar / on_tick / on_timer は、引き続き選択した実行ウィンドウの内側でのみ実行されます。ウォームアップは履歴専用で、結果にシミュレーション上の「取引日」が増えることはありません。

bar_index と暦日の違い

  • bar_index は実行バーのみを数えます(選択範囲内の最初のバーが 0、次が 1、…)。ウォームアップのみのバーは数えません。
  • バーは、実行ウィンドウ内で古いものから新しいものへシミュレートされます。

コールバック内のバーデータ(bar)

すべての on_bar と on_tick(および設定されている場合はフォワード実行の on_timer)で、エンジンは bar、つまりそのコールバックが対象とするシンボルの OHLC バービュー(OhlcvBarView)を渡します。読み取り専用のマッピングのように動作しますが、isinstance(bar, dict) は偽です。dict 専用の API ではなく、bar["close"] や属性形式のアクセスを使ってください。

バックテストでは、on_tick は各バーの OHLC から作られた合成価格を受け取ります(1 バーにつき 4 回の呼び出しで、実際のティック履歴はありません)。フォワード実行では、接続済みブローカーのライブ気配ごとに on_tick が発火し、price 引数が最新のマークを追跡します — ストラテジーのライフサイクルを参照してください。

読み取り専用のマッピングとして使えます。

o = float(bar["open"]) h = float(bar["high"]) l = float(bar["low"]) c = float(bar["close"]) v = float(bar["volume"]) t = bar["t"] # ISO timestamp string (QuantCraft B2 daily bars: a date like "2024-01-02", UTC)

オフセット指定のインデックスで、現在のバーを基準にした履歴(同じバー、過去の終値など)も読み取れます。

current_close = bar.close[0] prev_close = bar.close[1]
  • bar.close[0] は現在のバーコンテキストの終値です(バックテストの on_bar での float(bar["close"]) と同じ考え方)。各コールバックでそれがどのバーを指すかは、on_bar と on_tick でのバーのインデックスを参照してください。
  • インデックスが大きいほど時間をさかのぼります。bar.bars_back はどこまでさかのぼれるかを示します。

on_bar と on_tick でのバーのインデックス

bar.close[0]、bar.close[1]、… のようなオフセットは、常にコールバックが見える最新のバーから過去に向かって数えます。ただし、どのバーが「最新」かはコールバックによって異なります。

3 本の確定したローソク足と 1 本の形成中のローソク足の図。on_bar では、確定したばかりのローソク足が Bar 0、それ以前が Bar 1 と Bar 2。on_tick では、形成中のローソク足が Bar 0、確定したばかりのローソク足が Bar 1、それ以前が Bar 2 と Bar 3。

  • on_bar は、バーが確定したときに発火します。インデックス [0] は確定したばかりのそのバー、[1] はその前のバー、[2] はさらにその前、というようになります。すべてのインデックスが完了済みのバーを指します。
  • on_tick は、バーがまだ形成中に発火します。インデックス [0] は形成中のバー(ティックごとに値が変わります)、[1] は最後に確定したバー、[2] はその前、というようになります。

つまり、同じローソク足は on_tick では on_bar のときよりインデックスが 1 つ大きくなります。

ローソク足on_baron_tick
形成中(未確定)見えない[0]
確定したばかり[0][1]
その 1 つ前[1][2]
その 2 つ前[2][3]
def on_bar(bar_index, bar, fundamentals=None, symbol=None): last_closed = bar.close[0] # the bar that just closed one_before = bar.close[1] def on_tick(bar_index, tick_in_bar, price, bar, fundamentals=None, symbol=None): forming = bar.close[0] # still forming — latest price so far last_closed = bar.close[1] # same candle on_bar saw as [0]

同じずれは、ビュー上のすべての系列(open、high、low、close、volume)に当てはまります。ロジックを on_bar から on_tick に移す場合は、同じローソク足を読み続けるために各オフセットに 1 を足してください。

バックテスト: on_tick は現在のバーを 4 つの合成ティックとして再生するため、そこでの [0] はシミュレート中のバーで、その完全な行から読み取られます(下記の [0] の出来高を参照)。フォワード実行のような、部分的に作られたローソク足ではありません。

ライブデータの精度(フォワード実行)

ブローカーからのライブ価格ストリームは近似であり、市場の完全な記録ではありません。

  • 無料のライブデータプランでは、通常は 1 つの取引所の約定しか見えません(米国の全取引のごく一部)。そのため、ライブで作られたローソク足は出来高がはるかに少なく、真の高値と安値を逃すことがあります。
  • 有料の統合フィードプランではすべての取引所が見えますが、特に値動きの活発な銘柄の寄り付き付近では、約定が遅れて一括で届くことがあります。

アプリは、ライブで作られた各ローソク足を、確定直後にブローカーの確定済み履歴バーに置き換えます。1 分足のような小さな時間枠では、次のようになります。

インデックス内容用途
bar.close[0]ライブティックから作られる形成中のローソク足現在の価格の推定
bar.close[1]確定したばかりのバー。最初の約 10〜30 秒はティックから作られたままのことがある新しいバーが始まった直後は注意して使う
bar.close[2]完全に確定したバー確認済みの終値が必要なシグナル

1 分足で確認済みの終値に依存するシグナルには、bar.close[2] を使うことをおすすめします。

[0] の出来高:

  • **フォワードの on_tick:**形成中のローソク足の volume[0] は暫定値です(多くは 1 ティック分のサイズ)。直前に完了したバーの出来高には volume[1] を使います。
  • バックテスト:4 つの合成ティックはすべてバーの完全な行を使うため、volume[0] は暫定的なティックサイズではなくバー全体の出来高です。

ここは、ステップごとの取引ロジック、つまりエントリー、バー終値でのエグジット、単純移動平均、そして現在のバーと過去の参照だけが必要なあらゆる処理に適した場所です。


プライマリと追加の時間枠(get_bar)

実行のプライマリ時間枠は、rt.get_bar で常に利用できます(Additional timeframes に列挙する必要はありません)。ストラテジーが別の解像度のバー(たとえば 5 分足のバックテストでの日足のトレンドフィルター)も必要とする場合は、Run backtest ダイアログの Symbol & data にある Additional timeframes ドロップダウンでそれらを選択し、任意のコールバックから読み取ります。

from quantcraft import Timeframe import quantcraft.runtime as rt def on_bar(bar_index, bar, fundamentals=None, symbol=None): # Primary TF works without listing it under Additional timeframes # (use the Timeframe member that matches the modal primary, e.g. M5): prev_primary = rt.get_bar(Timeframe.M5, shift=1) daily = rt.get_bar(Timeframe.DAILY, shift=1) if daily and bar.close[0] > daily.close: ... # primary bar closed above yesterday's daily close

Additional timeframes はバックテストで設定し、選択内容は実行プリセット(.qcs)の secondaryTimeframes に保存します。

BarSnapshot のフィールド

get_bar は、open、high、low、close、volume、t を持つ BarSnapshot(または None)を返します。

shift の意味

shift.close.high / .low / .open
0現在の約定価格 — 同じコールバック内ではすべての時間枠で同一(バックテスト。下記のフォワードの注記を参照)その時間枠の保存済みバーから — プライマリ時間枠とは統一されていない
>= 1その時間枠で完了したバーの終値完了したバーの完全な OHLC — 直前のローソク足のヒゲにはこちらが望ましい

バックテスト:get_bar は、プライマリ時間枠でも各追加時間枠でも、現在のシミュレーションステップまでのバーしか参照できず、それ以降は決して見えません。shift=0 では、副時間枠の high/low は各時間枠でシミュレーションクロックに時間整合されます。get_bar はクロックシンボルのバーを読みます。複数シンボルの実行では、履歴には各ティッカー自身の bar.close[i] を使ってください。

フォワード実行:プライマリの bar は、チャートのツールバーの時間枠に従います。副バッファは、その時間枠のストリームでバーが完了したときに更新されます。shift=0 の high/low は、そのバケットが完了するまで遅れることがあるため、直前バーの OHLC を確実に得るには shift=1 を使ってください。フォワードの shift=0 の .close は各バッファ自身の最新の終値で、時間枠間で統一されていません。on_tick では、プライマリバーの volume[0] は暫定値(形成中)の場合があります。

その時間枠に実行用のバッファがない場合(プライマリでもなく、Additional timeframes にも選択されていない場合)、Screener のバックテスト(クロックシンボルなし — 履歴には各ティッカー自身の bar.close[i] オフセットを使用)、またはデータが利用できない場合は、None を返します。バックテストでの例外が 1 つあります。選択していない時間枠に対する shift=0 は、None ではなくプライマリ時間枠の現在のスナップショットを返します。

tf は Timeframe のメンバー、または "1D" / "5Min" のような文字列です。

Timeframe 列挙型

from quantcraft import Timeframe でインポートします。

メンバー文字列値説明
M1"1Min"1 分足
M5"5Min"5 分足
M15"15Min"15 分足
M30"30Min"30 分足
H1"1Hour"1 時間足
H4"4Hour"4 時間足
DAILY"1D"日足
WEEKLY"1Week"週足

QuantCraft B2 の一部の時間枠(2 分、2 時間、1 秒、月足 m、四半期足 q、年足 y)には Timeframe のメンバーがありません。get_bar には文字列として渡してください。


任意の全系列:on_finish(bars, …)

シミュレーションが終了すると、エンジンは on_finish を 1 回呼び出します。ストラテジーが拡張シグネチャを定義していれば、後処理(実行全体にわたるインジケーター、系列のエクスポート、refresh_metrics 用の最終マークなど)のために全系列の OHLC 行を受け取ります。

def on_finish(bars, symbol=None, bars_by_symbol=None): ...

bars — クロックシンボル、古い順

  • bars はクロックシンボルの辞書の list です(そのティッカーが読み込まれていればスクリプトの SYMBOL、なければ最初に読み込まれたシンボル。ダイアログにはプライマリシンボルの設定項目がありません)。Screener の実行ではクロックシンボルがなく、bars は []、symbol は "" なので、bars_by_symbol を使ってください。
  • 順序は時系列:古いバーが先、新しいバーが最後です。ノートブック形式の API における QcOhlcv の [0] = 最新 というインデックスの慣例とは逆です。
  • 各行には、少なくとも open、high、low、close、volume が含まれ、タイムスタンプがある場合は t も含まれます。ファンダメンタルデータが有効な場合、行にはそのバーの fundamentals スナップショットも含まれることがあります。

典型的な使い方:

def on_finish(bars, symbol=None, bars_by_symbol=None): if not bars: return closes = [float(b["close"]) for b in bars] last = float(bars[-1]["close"]) sym = (symbol or "AAPL").strip().upper() metrics = account.refresh_metrics({sym: last}) chart_indicators.add(...)

account.refresh_metrics({symbol: last_price}) を呼び出すときは、bars[-1]["close"](または最終行のフィールド)を最終マークとして使い、実行終了時に建玉が正しく評価されるようにします。

chart_indicators には、実行がバーを進める間にシンボルごとに蓄積した値を使い、on_finish はその引き渡しにだけ使うことをおすすめします。バーごとに追跡していなかったインジケーターに限り、bars から再計算してください — インジケーター系列を参照。

bars_by_symbol — 複数シンボルの実行

複数のティッカーをバックテストする場合でも、bars が指すのはクロックシンボルのみです。すべてのシンボルについて整列済みの全系列が必要なときは、bars_by_symbol を使います。

  • 大文字のティッカー → bars と同じ形のリスト(シンボルごとの時系列の dict)へのマッピング。
  • 終了時に、クロスセクションやシンボルごとの全履歴(相関、相対強度、シンボルごとのインジケーター)が必要なときに使います。

on_finish が不要な場合

ストラテジーに必要なのが現在のバーと過去のオフセットだけなら、on_bar / on_tick だけを実装し、全系列の重い処理を省けます。ロジックにとって on_finish は任意ですが、chart_indicators の系列を引き渡す場所であり、refresh_metrics が最後の価格を受け取る場所でもあります。on_finish 内のすべての return は無言であることに注意してください。実行は成功扱いのまま、その後に続くはずだった処理がスキップされるだけです。


Test Results との関係

構造化されたバックテスト結果には、ohlcv.bars(または同等のもの)のリストが含まれます。これはシミュレートされた実行ステップごとに 1 行で、OHLC フィールドと任意の fundamentals スナップショットを持ち、コールバックで見たものと整合します。on_finish(bars, …) は、エンジンがクロックシンボルの「実行全体」の計算に使うのと同じ時系列なので、終了時のコードは結果やチャートに表示されるものと一致します。


クイックリファレンス

トピックユーザー向けの要約
ローダー接続済みブローカーのフィード(キー+幅広い日中足)と QuantCraft ストレージ(サインイン済み。日足/週足/月足、Premium ならそれ以上)。
日付YYYY-MM-DD の開始+終了 → 暦日で絞り込んだウィンドウ。両方省略 → ブローカーフィードの従来の遡及、または QuantCraft ストレージのファイル全体。
ウォームアップbar オフセット用に開始前の追加履歴。コールバックは実行ウィンドウ内のみ。
ステップごとon_bar / on_tick で bar / bar["close"] / bar.close[k] を使う。[0] = on_bar では最後に確定したバー、on_tick では形成中のバー。
プライマリ/追加の時間枠プライマリは常に rt.get_bar。追加分は Additional timeframes + rt.get_bar(Timeframe.X, shift)。
全系列on_finish(bars, symbol=..., bars_by_symbol=...) を使う — bars はクロックシンボルの古い順、bars_by_symbol は複数シンボルの実行における全シンボル。
グローバルなファクターリターンQcOhlcv や bar にはありません — Fama-French ファクター(fama_french.qc)を使います。月次の rows は YYYYMM の dict です。rows[0] ではなく latest_row を使ってください。
OHLCV とバーデータ — ドキュメント (1.0 (latest)) | QuantCraft