researcher: 人間とAIエージェントのための検索可能なクオンツ研究アーカイブ
クオンツ研究は、どこにでもあって、どこにもない。必要な論文はarXivにある。リファレンス実装はGitHubにある。直観は、誰かが2019年に書いたブログ記事のどこかに埋もれている。実際のエントリー/エグジットのロジックは、TradingView上の400いいねが付いてドキュメントのないPineスクリプトだ。4つのコーパス、4つの検索ボックス、4種類の慣習、そしてクロスリファレンスはゼロ。あるアイデアが1週間のバックテストに値するかどうかを判断しようとするとき、本当のコストはこの断片化にある — 読むことではなく、見つけることなのだ。
そこで、私たちは自分たちのものを作った。researcher.marketmaker.cc は、クオンツトレーディング研究のためのキュレーションされたアーカイブ兼検索エンジンである。通常はarXiv、GitHub、クオンツブログ、TradingViewに散らばっている素材を一箇所にまとめ、そのすべてを全文検索向けにインデックス化し、そして — ここが私たちが最も重視している部分だが — Model Context Protocol (MCP) エンドポイントと公開REST APIを通じて、コーパス全体をAIエージェントに公開している。人間がキーボードでブラウズでき、エージェントがツール呼び出しでクエリできる研究基盤であり、その両者がまったく同じインデックスに支えられている。
この記事では、中に何が入っているか、どう構築されているか、そして私たちのAIエージェントスタックの中でなぜそこに位置しているのかを案内する。
コーパスに何が入っているか

researcher は、それぞれ独自の全文インデックスを持つ4つの主要データセットを統合している。以下の件数は2026-06-12時点のもので、これらは変動する — arXivパイプラインは毎日実行され、インデックスはソースから再構築されるため、数値は増えていく。
| データセット | ソース | ドキュメント数 | 検索対象 |
|---|---|---|---|
| Papers(論文) | arXiv q-fin (1997–2026) | 約18,647 | タイトル、アブストラクト、著者(カテゴリでフィルタ) |
| Code(コード) | GitHubリポジトリ | 約12,957 | 名前、説明、トピック(言語、スターでフィルタ) |
| Articles(記事) | クオンツブログ | 約4,633 | タイトル、説明(ソース、日付でフィルタ) |
| Strategies(戦略) | TradingViewのPineスクリプト | 約15,180 | タイトル、説明、タグ(カテゴリでフィルタ) |
4つの検索可能なインデックス全体で、ちょうど51,000件あまりのドキュメントになる。papers インデックスは最大の単一コーパスであり、私たちが最も力を注いだものでもある。これは、手作業で選んだサブセットではなく、1997年までさかのぼるarXivの定量ファイナンス(q-fin.*)の情報の奔流をまるごと収めたものだ。以前のサイトは、キュレーションされた数百本の論文しか搭載していなかった。現在のインデックスは完全なq-finコーパスであり、その上にキュレーションされた来歴情報をマージしてあるため、特定のクオンツブログでも参照されていた論文は、その帰属情報を併せ持つ。
4つの検索インデックスに加えて、人間向けのサイトはさらに多くを重ねている。私たち自身が書く研究ノートと日次ダイジェスト、クオンツのサイトと著者のディレクトリ、関連するYouTubeチャンネルをインデックス化した動画セクション、そしてファンドディレクトリだ。4つのインデックスが検索可能な背骨であり、それ以外のすべてはその周りのキュレーションである。
単一の信頼できる情報源(Single Source of Truth)

私たちにとって初期に静かに壊れたもの — そして今では強く対策しているもの — が、件数の不一致だ。ホームページはある数を示し、検索は別の数を返し、APIは三つ目の数を返した。ある時点では、トップページが719本の論文を宣伝している一方で、検索は18,000本超を返していた。研究ツールへの信頼にとって、コーパスが自身の規模について自分自身と一致できないことほど致命的なものはない。
その修正は、すべての表示面を一箇所から読ませることだった。papersコーパスについては、Meilisearchが信頼できる情報源である。アプリバンドルの中に論文の第二のコピーが存在することはない。ホームページの件数、/papers の件数、APIが返す件数、そして実際に検索するドキュメントは、すべて同じインデックスだ。コーパス自体は、キュレーションされた論文セットを取り込み、それをarXivの情報の奔流とユニオンし(arXivの id で重複排除し、来歴の配列をマージし)、新しい順にソートし、インデクサが消費する単一の約25 MBのファイルを書き出す、というオフラインの取り込みステップで構築される。そのファイルはおよそ15,000〜18,000レコードであり、意図的にクライアントにバンドルされない — そのサイズのコーパスをブラウザに送る筋合いはない。
他の3つのデータセット(コード、記事、Pineスクリプト)は、サーバーサイドでそれぞれのJSONファイルから読み込まれ、同じファイルからインデックス化される。Meiliを情報源とする方式への移行が、計画された次のステップだ。全体に共通するルールはこうだ。データはサーバーで読み、数メガバイトのデータセットをクライアントバンドルに決して import せず、インデックスと表示される件数を同じ出所から来させること。同期ずれは構造的に不可能になる。
検索: 全文、タイプミス耐性、ファセット

検索エンジンは Meilisearch で、アプリと同じサーバー上で動作し、localhostにバインドされている — 公開されてはいない。私たちはこれをベクトルストアではなく、全文検索エンジンとして使っている。埋め込みもなければ、意味的類似性の魔法もない。「この概念に言及している論文とリポジトリを見つけて」という用途には、タイトル、アブストラクト、説明、著者、タグに対するタイプミス耐性のある字句検索のほうが、埋め込みインデックスでは得られないかたちで、高速で、予測可能で、デバッグしやすい。各インデックスは完全な元のドキュメントに追加の _id を加えて保存するので、検索は完全に水和されたレコードを返し、アプリはそれを直接レンダリングできる — ヒットを再水和するための二度目のフェッチは不要だ。
実務で効いてくる詳細をいくつか挙げる。
-
タイプミス耐性とリレバンスのランキングは、Meilisearchから無償で得られる。
momentmを検索しても momentum 論文は見つかる。結果は単にフィルタされるだけでなく、ランク付けされる。 -
ファセットフィルタリング。 論文はarXivの
category(q-fin.PM、q-fin.TR、…)で、リポジトリはlanguageとstarsで、記事はsourceとdateで、Pineスクリプトはcategoryでフィルタする。/papersページは、そのカテゴリのドロップダウンをインデックスのライブなファセット分布から構築するので、フィルタの選択肢は常にコーパスに実際にあるものを反映する。 -
camelCaseの分割。 Meilisearchは空白と句読点でトークン化するが、camelCaseでは分割しない。つまり、文字どおり
TradingAgentsという名前のリポジトリは単一トークンとなり、自然なクエリ「trading agents」では到達できない。インデックス化の際、私たちはname_splitフィールドを導出する —TradingAgents→TradingAgents Trading Agents、ai-hedge-fund→ai-hedge-fund ai hedge fund— そしてそれを検索可能な属性に加える。元のトークンは最初に保持されるので完全名一致は依然として最上位にランクされ、導出されたフィールドはクライアントに決して返されない。これは小さなことだが、フラッグシップのリポジトリを見つけられるか見つけられないかを分ける違いになる。 -
ブラウズ = 新しい順。 空のクエリはエラーではなく、ブラウズのパスだ。
/papersでは、空のクエリはpublishedの降順でソートされるので、このページは最新のq-fin研究の逆時系列フィードも兼ねる。 -
集計用のサイドインデックス。 いくつかの数値は、Meilisearchがクエリ時に安く計算できない — 全リポジトリにわたるスター数の合計、Pythonファイルの合計、ノートブックの合計などだ。ページ読み込みのたびにコーパス全体をスキャンするのではなく、インデクサはそれらの合計を、インデックス時に一度だけ、データセットごとに1ドキュメントを保持する小さな
researcher_metaインデックスに書き込む。statsエンドポイントはそれをそのまま読み返す。再インデックス時にしか変わらない件数は、再インデックス時にしか計算しない。 -
実際に使えるページネーションの上限。 papersインデックスはMeilisearchの
maxTotalHitsを50,000に引き上げ、publishedをソート可能とマークしているので、約1万8千件のドキュメントのコーパスを深くページングし、全体を新しい順にソートできる — リレバンスヒットの最初のページだけではない。
インデクサは冪等だ。各インデックスがなければ作成し、設定を再適用し、_id(論文はarXiv idから、リポジトリと記事はURLのハッシュから導出する)でキー付けして2,000件ずつのバッチですべてのドキュメントをアップサートする。インデックス全体がソースファイルから再構築可能であるため、管理すべきバックアップは存在しない — ロールバックとは、単なる再インデックスだ。再実行は構造上、安全である。
エージェントからアクセス可能: MCPと公開API

ここが、researcher を私たちのほかの取り組みと結びつける部分だ。コーパスは、検索ボックス付きの単なるウェブサイトではない — それはAIエージェントが呼び出せるツールだ。
MCPエンドポイント
researcher は、Streamable HTTP上の /api/mcp で Model Context Protocol サーバーを公開している。MCP互換のエージェントなら何でも — Claude、私たち自身のスタックのカスタムエージェント、プロトコルを話すものなら何でも — 接続して、ライブなコーパスに対して読み取り専用のツールを呼び出せる。データセットごとにグループ化された13個のツールがあり、一貫した search / get / list の形に従っている。
| グループ | ツール |
|---|---|
| Papers | search_papers、get_paper、list_papers |
| Code | search_repos、get_repo、list_repos |
| Articles | search_articles、get_article、list_articles_by_site |
| Strategies | search_pine、get_pine_script、list_pine |
| Knowledge | knowledge_query(graceful stub、将来のグラフ層のために予約) |
ツールのスキーマは、人間のためではなく、エージェントの便益のために書かれている。たとえば search_papers は、自身をタイトル、アブストラクト、著者に対するタイプミス耐性のあるリレバンスランク付き検索として宣言し、オプションの category フィルタ(例: q-fin.PM)と結果上限を持ち — そして、対象を絞り込んだら完全なアブストラクトのために get_paper を呼ぶようエージェントに伝える。search は、エージェントが多くの結果を安くスキャンできるよう、コンパクトでスニペットサイズのヒットを返す。get は、一つ選んだあとに完全なレコードを返す。この2段階の形が、エージェントのコンテキストウィンドウが必要のないアブストラクトで溺れるのを防ぐ。
具体的には、たとえば最適執行(optimal execution)を調べているエージェントは、search_papers("optimal execution", category: "q-fin.TR") を実行してタイトルとスニペットのランク付きショートリストを得て、search_repos("optimal execution", language: "Python") でリレバンス順にソートされスター数でフィルタできる実装を見つけ、search_pine("VWAP") で同じアイデアが公開されたTradingView戦略としてどう現れるかを見ることができる — 1時間前には3つの別々のウェブサイトだった3つのコーパスに対する、3回のツール呼び出しだ。それから1回の get_paper で、有望に見えたものの完全なアブストラクトを引き出す。エージェントはプロトコルから一度も離れず、どの結果も、再フェッチしに行かねばならない検索結果のスタブではなく、本物の水和されたレコードである。
公開REST API
MCPを使わない利用者のために、/api/v1/ の下に並行するRESTの表面がある。papers、repos、articles、pine、そして集計の stats だ。q、category、limit、offset のパラメータを持つプレーンなJSONを話し、各ページとともに真の合計件数とファセット分布を返し、CORSが有効化されている。GET /api/v1/papers?q=optimal+execution&category=q-fin.TR は、どこからでも一行で済む。同じエンドポイントが、サイト自身の /papers ページを駆動している — ブラウザもまた、ただのAPIクライアントなのだ。
正直に失敗する
嘘をつく検索バックエンドは、停止しているものよりたちが悪い。私たちは、Meilisearchに到達できないときに何が起きるかについて、意図的な立場をとった。データ層は、静かに空の結果を返すのではなく、失敗時にthrowする — そして呼び出し側がどう扱うかを決める。まだインメモリのコピーを保持しているデータセットでは、ツールはそのコピーに対するプレーンな .filter() にフォールバックするので、サイトは稼働し続ける。Meilisearchが信頼できる情報源であり、第二のコピーが存在しないpapersでは、ツールとAPIは、古いデータや部分的なデータを提供するのではなく、明示的なエラーを返す(APIは 503 で応答する)。各検索呼び出しには短いタイムアウトがあるので、ハングしたインデックスがツールを行き詰まらせることはない。原則はこうだ。大声で劣化せよ、間違った答えを静かに手渡すな。
データはどうやって入るのか

コーパスは、すべて無料の公開ソースに対して動くスクレイパーのパイプラインによって供給される。
- Papers は arXiv Atom API から来る。ハーベスタが完全な
q-finコーパスをJSONLに取り込み、ビルドステップがそれをキュレーションされたセットとユニオンし(arXiv idで重複排除、来歴をマージ)、その結果がインデクサに渡される。ハーベスタには、外部の読書リストからシードするための「これらの特定のidをエンリッチする」モードもある。 - Code は、クオンツに関連するGitHubリポジトリのクロールであり、フィルタリングに重要なメタデータ — スター、フォーク、主要言語、トピック、Pythonファイルとノートブックの数 — とともに取得される。
- Articles は、クオンツブログとアグリゲータからスクレイピングされ、より優れたものはリンク切れを生き延びられるようローカルにミラーされる。ホームページは、どの記事のローカルコピーを保存したかを示す。
- Strategies は、TradingViewのPineスクリプトであり、そのメタデータ — 著者、カテゴリ、タグ、いいね、そしてリスティングにコード、チャート、分析が含まれるかどうか — とともに収められる。
- Videos は、関連するYouTubeチャンネルをインデックス化し、トークやウォークスルーが文章による素材と並んで見つけられるようにする。
本番での再インデックスは、エンジンがインターネットに決して公開されないため、localhostにバインドされたMeilisearchへのSSHトンネル越しに実行される。ループ全体 — ハーベスト、ビルド、デプロイ、インデックス — は冪等に再実行できるよう設計されており、それがまさに日次のcronがすることだ。
アクセスとホスティング

researcher は私たちのServer 1上で、小さなDocker Composeスタックとして動作する。Traefikの背後のNext.jsコンテナと、localhostにバインドされたMeilisearchコンテナだ。Next.jsアプリは、データセットをサーバーサイドで読み、内部ネットワーク越しにMeilisearchと話す。
アクセスは、私たちの共有アイデンティティサービスである auth.marketmaker.cc を通じてゲートされる。トークンはRS256のJWTで、auth サービスのJWKSに対して検証される — すべての認可判断は署名をチェックし(厳格なissuerとアルゴリズムのチェックを伴い、鍵エンドポイントに到達できない場合はフェイルクローズする)、検証されないデコードのパスは、ナビバーにメールアドレスを表示するといった見た目だけのUIにのみ使われる。auth サービスはサービスごとのロールを発行する。researcher では、admin ロールが内部の管理エリア(そこで私たちはスクレイパーを実行・監視する)をゲートし、公開ホームページはトークンをまったく必要としない。これは私たちのほかの内部ツールの前面に立つのと同じ認証ファブリックであり、ひとつのログインがエコシステム全体に通用する。
Marketmakerスタックの中でどこに位置するか

researcher はインフラであって、目的地ではない。要点はウェブサイトではない — 要点は、人間とエージェントの両方が共有する、この分野のクエリ可能なビューを私たちが今や手にしているということだ。
人間としての私たちにとって、それはこのブログ自体の多くが生まれる場所だ。VectorBT のようなツールをレビューするとき、あるいは TradingAgents や Fincept Terminal のようなフレームワークを解剖するとき、その出発点はしばしば researcher 全体にわたる検索だ。これは何の論文の上に築かれているのか、同じ問題を解くほかのリポジトリは何か、誰がそれについて書いているのか。アーカイブが漏斗であり、ブログ記事はそこから落ちてくるものだ。
私たちのAIエージェントにとって、それはもっと構造的な何かだ。MCP越しに到達可能な研究基盤があるということは、戦略の作業をしているエージェントが、arXivをライブでスクレイピングしたり、4つの異なるAPIを操ったり、外に何があるか推測したりする必要がない、ということを意味する — エージェントは、すでに統合され、重複排除され、インデックス化されたコーパスに対して search_papers、search_repos、search_pine を呼ぶ。それは、私たちのcommand-and-operate (cmdop) とエージェントツールと同じ方向だ。実データに対する型付きで読み取り専用の、よくドキュメント化されたツールをエージェントに与え、バックエンドが利用できないときは大声で失敗し、ひとつの共有バックエンドが同一のインデックスから人間向けUIと機械向けインターフェースの両方に供給するようにする。人間がブラウズし、エージェントがクエリする — しかし両者は同じアーカイブを見ており、それこそが全体の狙いなのだ。
結論
researcher は、ある小さくて煩わしい問題 — クオンツ研究が、互いに話さない4つの場所に散らばっているという問題 — の修正として始まり、私たちが日々頼りにする何かへと変わった。論文、コード、記事、戦略にまたがるおよそ51,000件のドキュメントが、すべて一つの全文検索エンジンの背後にあり、すべてがブラウザを持つ人間によっても、MCPクライアントを持つエージェントによっても到達可能だ。それは意図的に華やかさを欠いている。埋め込みではなく全文検索、巧妙なキャッシュではなく単一の信頼できる情報源、停止を取り繕うのではなく正直なエラーをthrowするツール。
トレーディング研究のためのエージェントを作っているなら、その教訓は私たち固有のコーパスを超えて一般化する。エージェントに与えられる最もレバレッジの効くものは、より大きなモデルではなく、それが必要とするデータの、クリーンで統合され、クエリ可能なビューだ — 人間が信頼するのと同じインデックスを通じて公開されたもの。それが researcher なのである。
Authors
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.