ページ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]、… のようなオフセットは、常にコールバックが見える最新のバーから過去に向かって数えます。ただし、どのバーが「最新」かはコールバックによって異なります。

on_barは、バーが確定したときに発火します。インデックス[0]は確定したばかりのそのバー、[1]はその前のバー、[2]はさらにその前、というようになります。すべてのインデックスが完了済みのバーを指します。on_tickは、バーがまだ形成中に発火します。インデックス[0]は形成中のバー(ティックごとに値が変わります)、[1]は最後に確定したバー、[2]はその前、というようになります。
つまり、同じローソク足は on_tick では on_bar のときよりインデックスが 1 つ大きくなります。
| ローソク足 | on_bar | on_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 closeAdditional 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 を使ってください。 |

