mcpField
N
NexusTrade Financial MCP

NexusTrade Financial MCP

認証済みおすすめリモート
nexustrade.io金融データ10今日更新

NexusTrade Financial MCP について

NexusTrade Financial MCP は、NexusTrade の定量調査・取引プラットフォームを AI アシスタントやエージェントに提供します。市場調査、戦略作成、バックテスト、ポートフォリオ操作に加え、管理されたペーパー取引や実取引に対応します。

主な機能

  1. 01市場調査とポートフォリオ構築
  2. 02型付き TypeScript 戦略ビルダー
  3. 03バックテスト、最適化、ウォークフォワード検証
  4. 04マネージドコンピューティングと Aurora エージェント
  5. 05クリエイター検索、購読、ポートフォリオのフォーク
  6. 06ペーパー取引と制御された証券口座操作

活用シーン

  1. 01市場を調査してポートフォリオを構築
  2. 02取引戦略のバックテストと最適化
  3. 03マーケットプレイスのポートフォリオをフォークまたは購読
  4. 04ペーパーまたは実取引ポートフォリオで戦略を追随

MCP 対応

ホスト型リモート MCP サーバー `https://nexustrade.io/api/mcp` は、調査、バックテスト、計算、ポートフォリオの採用、取引など120以上のツールを提供します。MCP クライアントは Streamable HTTP で接続でき、stdio のみ対応するクライアントでは `mcp-remote` を利用できます。

設定

リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。

エンドポイントhttps://nexustrade.io/api/mcp
インストールコマンドをコピー
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。

ツール

121
パラメーター型必須説明
pagenumberいいえページ番号(デフォルトは 1)
limitnumberいいえページサイズ(デフォルトは 10、最大 100)
portfolioIdstringいいえエージェントの絞り込みに使用する、任意のポートフォリオ ID またはエイリアス
includeArchivedbooleanいいえアーカイブ済みのエージェントを含めます。デフォルトは false です
starredOnlybooleanいいえスター付きのトップレベルエージェントのみを返し、starredOrder の昇順、次に starredAt の降順で並べ替えます。デフォルトは false です
searchstringいいえtitle と initialPrompt を対象に、大文字小文字を区別しない部分文字列検索を行います

詳細

NexusTrade

NexusTrade TypeScript SDK

型付き TypeScript で取引戦略を作成できます。ライブ運用と同じエンジンでバックテストできます。

npm Node License Deps

クイックスタート · 戦略の作成 · ポーリング · エージェント · Lake SQL · 認証 · エラー


npm install nexustrade

ランタイム依存関係はゼロです。 ESM と CommonJS のビルドが型定義とともに提供されます。

MCP サーバー

NexusTrade は、ホスト型のリモート Model Context Protocol サーバーとしてもプラットフォームを提供しています。最新の MCP クライアントは、本番環境の Streamable HTTP エンドポイントに直接接続し、NexusTrade OAuth を自動的に検出します。

claude mcp add --transport http nexustrade https://nexustrade.io/api/mcp

Cursor や、リモート接続に対応したその他のクライアントでは、次のように設定します。

{
  "mcpServers": {
    "nexustrade": {
      "url": "https://nexustrade.io/api/mcp"
    }
  }
}

Claude Desktop や stdio のみ対応するその他のクライアントでは、定評のある mcp-remote ブリッジを使用してください。リポジトリのクローンや、ローカルの NexusTrade サーバーは必要ありません。

{
  "mcpServers": {
    "nexustrade": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote@latest",
        "https://nexustrade.io/api/mcp",
        "--transport",
        "http-only"
      ]
    }
  }
}

稼働中のサーバーは、市場調査、ポートフォリオ構築、バックテスト、最適化、ウォークフォワード検証、マネージドコンピューティング、Aurora エージェント、ペーパートレード、管理された証券取引業務にわたる 120 以上のツールを提供します。クリエイターマーケットプレイスのツールは、戦略を利用するための一連の流れをすべてカバーしています。

  • search_creators は、公開クリエイターとそのマーケットプレイスのポートフォリオを検索します。
  • subscribe_portfolio は、収益化された掲載内容を検証し、安全な購入プレビューを返します。支払いはユーザーが NexusTrade で完了します。MCP ツールを介して支払うことはありません。
  • fork_shared_portfolio は、マーケットプレイスの戦略を一度だけ編集可能なコピーとして、新規または既存のポートフォリオに作成します。
  • copy_trade_shared は、アクセス可能な戦略を、指定した配分でペーパーまたはライブのポートフォリオに継続的に反映します。

開発者ガイド、ユーティリティツールのリファレンス、Aurora ツールのリファレンスをご覧ください。

調査や過去の実績は投資助言ではなく、将来の運用成果を保証するものでもありません。ペーパーとライブのモードは明確に区別してください。ポートフォリオ、スケジュール、証券取引注文に影響する可能性のあるツールには、認証済みアカウントの NexusTrade 権限および承認コントロールが適用されます。

クイックスタート

import {
  NexusTradeClient,
  always,
  backtest,
  buy,
  portfolio,
  stockAsset,
  strategy,
} from "nexustrade";

const client = new NexusTradeClient();

const book = portfolio("Example", [
  strategy("Buy SPY", always(), buy(stockAsset("SPY"), 100)),
]);

const operation = await client.createBacktest(
  backtest(book, { startDate: "2024-01-01", endDate: "2024-12-31" }),
  { idempotencyKey: "example-v1" }
);
const result = await client.waitForBacktest(operation.id as string);
console.log(result.result);

バックテスト操作では、送信直後と、最終的な result の両方で warnings: string[] が含まれる場合があります。これらは重要な注意事項として扱ってください。警告があっても、操作が成功から失敗に変わるわけではありません。

担保資産のリスク

ターミナル操作の result.statistics は、返した結果だけでなく、実行でどれだけの資本がリスクにさらされていたかを示します。2 つのフィールドがこれを表し、型は BacktestCollateralStatistics です。

フィールド意味
peakReservedCollateral任意のティックでロックされた担保の最大額(口座通貨単位)
medianReservedCollateral1 つ以上のポジションを保有していたティック全体の中央値

どちらも省略可能で、null の場合もあります。この不在自体が実際の回答です。エンジンが担保の報告を開始する前のバックテスト実行では値がなく、何もロックしなかったポートフォリオとは異なります。$0 ではなく「未記録」と表示してください。ここでのゼロは「この戦略にはリスクがない」と読めてしまいますが、フィールドが未入力の場合はその正反対です。ポートフォリオの価値で代用しないでください。数千ドルしかリスクにさらしていないポートフォリオでも、全額をリスクにさらしていると報告されてしまいます。

cash - buyingPower からどちらの数値も再構成しないでください。Buying power は上下限でクランプされ、未決済のクレジットスプレッドのプレミアム項も含むため、逆算はまさにこの指標が対象とする、高い担保を必要とするポートフォリオで破綻します。

戦略の作成

すべてのビルダーは、NexusTrade エンジンが実行するものと同じインジケーター仕様から生成されるため、ポートフォリオは慣例ではなく、構築時点で有効です。

TypeScript では比較演算子をオーバーロードできないため、インジケーターは gt / gte / lt / lte / eq / neq および and / or で組み合わせます。

import * as nt from "nexustrade";

const book = nt.portfolio(
  "Momentum",
  [
    nt.strategy(
      "Rotate into strength",
      nt.always(),
      nt.dynamicRebalance({
        universe: nt.universe("SP500"),
        pipeline: [
          nt.filter(nt.gt(nt.Price(nt.CANDIDATE), nt.SMA(nt.CANDIDATE, 200))),
          nt.selectTop(nt.RSI(nt.CANDIDATE, 14), 10),
        ],
        weightIndicator: nt.RSI(nt.CANDIDATE, 14),
        limit: 10,
        deploymentPercent: nt.Value(80),
      })
    ),
  ],
  { initialValue: 100_000 }
);

議会の開示シグナルもネイティブインジケーターです。議院を明示的に選択しない限り、下院と上院が組み合わされます。金額指標は開示された下限値がデフォルトで使用され、確定済みのオプション開示はデフォルトで除外されます。

const pelosiPurchases = nt.PoliticalTrades(
  nt.CANDIDATE,
  "Nancy Pelosi",
  "BuyAmount",
  90,
  "LowerBound",
  "Equity",
);

すべての議員を含めるには、届出者に "" を使用します。BuyCount は正規化された購入イベントの件数を数え、BuyAmount は開示された金額を測定します。基礎となるティッカーに関連付けられたオプション開示の取引活動が必要な場合にのみ、"Option" を選択してください。

注文の執行方法は戦略に属します。省略すると後方互換性のある Market がデフォルトで使用されます。Buy/Sell には固定単価を使用するか、オプション戦略の最大ネットデビット/最小ネットクレジットを設定します。

nt.strategy("Buy SPY at my price", nt.always(), nt.buy(nt.stockAsset("SPY"), 10), {
  orderExecution: nt.limitOrder({
    price: nt.unitPriceLimit(500),
    workingTime: nt.goodForDay(),
  }),
});

nt.strategy("Sell the spread for $1.50 or better", nt.always(), optionAction, {
  orderExecution: nt.limitOrder({
    price: nt.minimumNetCredit(1.5),
    workingTime: nt.goodForMinutes(30),
  }),
});

オプションのネットリミットは、戦略が保有するポジションに連動させることもできます。数値の代わりにインジケーターを渡すと、戦略が発動したときにエンジンがその値を評価します。その時点で正の値がなければ、注文は出されません。

nt.strategy("Sell the credit spread for the debit fill plus $0.50", whenDebitSpreadHeld, creditSpreadAction, {
  orderExecution: nt.limitOrder({
    price: nt.minimumNetCredit(
      nt.Plus(nt.OptionSpreadEntryPrice("SPX", "call", "long", "vertical"), nt.Value(0.5)),
    ),
    workingTime: nt.goodForDay(),
  }),
});

currentLimit() は、動的リバランス戦略向けに、相場に連動する Limit を作成します。現在の気配値より不利にならないよう保護しますが、指値注文として価格を維持するものではありません。ライブのオプション戦略では、明示的な Limit ポリシーを選択する必要があります。

オプションの選択と実行制限

strategy(..., { pendingOrderPolicy: "CancelConflictingBuys" }) を指定すると、バックテストで競合する保留中の買い注文よりも決済を優先できます。省略した場合は、待機する動作が維持されます。ブローカーのキャンセル確認が実装されていないため、ペーパー環境および本番環境へのデプロイでは、このオプトイン設定は拒否されます。この設定では、明示的に "Wait" を指定することもできます。

ビルダーが記述するのはドラフトです。型チェックを通過しても、エンジンが要求されたすべてのルールを実行できるとは限りません。API はポートフォリオ全体とその条件を検証します。

  • 有効期限セレクターでは、DTE の範囲と nearest、middle、furthest を指定できます。middle は、対象となる有効期限をインデックス順で並べたときの中央を選択します。180 日など、指定した日数に最も近い有効期限を選択するものではありません。月次のみ、または四半期のみの有効期限フィルターはありません。
  • rebalanceOption は、renewBeforeDays(整数、1~90)と revisitDisclosedTargets を受け付けます。これらは、モデル化された政治資金開示オプションの目標を維持します。戦略には、銘柄が Option で、会員 ID がちょうど 1 つの NewPoliticalDisclosure 条件を含める必要があります。これらのフィールドは、トレンド戦略向けの汎用的な決済・置換ロールを実装するものではありません。
  • バックテストでは、ジョブの feeConfig.OptionSlippageFraction が気配値ベースの約定を設定します。0 はミッド価格、1 は買いでアスク価格、売りでビッド価格を使用し、デフォルトは 0.5 です。このジョブ設定では、最終取引価格へのフォールバックは追加されず、本番環境での注文執行も定義されません。
  • 評価のタイミングと注文の執行は別々です。OpenClose は取引セッションの開始時と終了時に評価をスケジュールしますが、終値で確認したシグナルを次の始値での注文に引き継ぐ機能はありません。タイミングオフセットを明示的にゼロにし、gt(MinutesAfterOpen(), Value(0)) 条件を指定すると、評価をカレンダー上の取引セッション終了時に限定できます。MinutesUntilClose は東部時間の 16:00 までの残り時間を数えるため、早期終了する取引セッションを識別できません。

近似を作成する場合は、実際の有効期限ポリシー、シグナルのタイミング、約定、置換の動作を明記してください。バックテストの結果が示すのは、その近似対象の手法そのものではなく、実装した内容です。

構築できるもの — 170 以上の生成されたビルダー
グループ例
価格と出来高Price OpeningPrice HighOfDay MinuteBarHigh MinuteBarLow HeikinAshi VWAP Volume GapPercentage
テクニカル指標SMA EMA RSI BollingerBand AverageTrueRange CrossAbove
ポジションの状態PositionValue PositionPercentChange PositionMaxDrawdown
ポートフォリオの状態PortfolioValue BuyingPower MaxDrawdown InitialValue
ファンダメンタルズFundamental Economic DaysUntilEarnings IsIndexMember IsIndustry
オプションOptionDaysToExpiration OptionCollateral OptionSpreadEntryPrice OptionUnrealizedPnL openOption closeOption
アクションbuy sell alert dynamicRebalance rebalanceOption
選択filter selectTop selectPercentile universe
ロジックalways atLeast atMost exactly fewerThan multi and or sequence
アンカーされたレベルIndicatorAtEntry LastOrderPrice IndicatorAtMinutesAfterOpen IndicatorWindowAgo

すべてのビルダーは完全に型付けされており、エディターで API 全体を補完できます。

## ジョブはエンジン上で実行されます — ポーリングが必要です

create* は作業をキューに登録し、すぐに返ります。結果が得られた時点で 解決するわけではありません。現在、Webhook はありません。

sequenceDiagram
    participant You
    participant SDK
    participant Engine

    You->>SDK: createBacktest(book)
    SDK->>Engine: POST (enqueue)
    Engine-->>SDK: id, status=queued
    SDK-->>You: operation (returns immediately)

    loop waitForBacktest — backoff 2s→15s
        SDK->>Engine: GET /operations/{id}
        Engine-->>SDK: status update
    end

    SDK-->>You: result (when completed)

    Note over You,Engine: Poll timeout throws operation_timeout.<br/>The job keeps running — call wait again with the same id.

どの種類のジョブも同じ形式のレスポンスを返すため、すべてのジョブで同じポーラーを使用できます。

{
  id: "op_...",
  kind: "backtest",          // backtest | optimization | walk_forward
  status: "queued",          // queued | running | completed | failed | cancelled
  result: {...},             // present only once terminal
  error: { code, message, retryable },
}
const finished = await client.waitForBacktest(operation.id as string);
オプションデフォルト意味
timeoutSeconds900待機を打ち切ります(ジョブは実行を続けます)
pollIntervalSeconds2初回の間隔。以降は 1.5 倍ずつ延長します
maxPollIntervalSeconds15間隔の上限
throwOnFailuretrue返却する代わりに、failed/cancelled で例外をスローします

タイムアウトすると operation_timeout がスローされますが、ジョブはキャンセルされません。再送信するのではなく、 同じ ID を指定して再度待機関数を呼び出してください。

一時的なネットワーク障害および HTTP 408/429/5xx のポーリングエラーでは、待機期限内に同じ操作を 最大 2 回連続で再試行します。障害が継続する場合は、元のエラーコードと操作 ID が維持され、新しいジョブは送信されません。

永続的なレイクエクスポートのサーバー側の制限時間はデフォルトで 900 秒です(登録済みの API キーでは最大 1800 秒を指定できます)。waitForLakeQuery のデフォルトは、キューでの待機時間を含めて 1200 秒です。 コンピュートトークンの制限時間はデフォルトで 90 秒、最大で 180 秒のままです。クライアント側の待機タイムアウトを延長しても、サーバー側の制限時間は延長されません。

バッチ処理。 createBacktests は 1 回のリクエストで複数のバックテストを送信し、それぞれについて 1 つの操作を返します。waitForBacktests(operations) はそのすべてを待機します。ループよりもこちらを優先してください。リクエストは 1 回、冪等性キーは 1 つ、レート制限枠も 1 つで済みます。

最適化とウォークフォワードも同じ形式です。

const study = await client.createWalkForward(
  nt.walkForward(book, {
    globalStartDate: "2022-01-01",
    globalEndDate: "2024-12-31",
    foldCount: 4,
  }),
  { idempotencyKey: "wf-v1" }
);
await client.waitForWalkForward(study.id as string);

ポートフォリオのデプロイ

ブックを作成してバックテストを実行しても、永続化はされません。save でアカウントに保存し、deploy で実行を開始します。

const book = nt.portfolio("Momentum", [
  /* … */
]);

await book.save({ idempotencyKey: "momentum-v1" }); // persists; sets book.id
const deployment = await book.deploy(); // starts paper trading
await book.undeploy(); // stops it

save と deploy は異なる ID を生成します。この違いは重要です。 save は ドラフト を永続化し、book.id にその ID を設定します。deploy は実際のペーパーポートフォリオを新たに作成し、独自の portfolioId を返します。デプロイではドラフトがポートフォリオに変換されるのではなく、ポートフォリオが新たに作成されるため、2 つの ID は共存します。ライブ状態を読み取る操作では deployment.portfolioId を使用してください。 book.id はドラフトを指します。

deployment.portfolioId; // the running portfolio
deployment.deploymentType; // paper, unless you deployed an existing live one
deployment.outcome; // created | reactivated

ハンドルのメソッドは省略可能な transport を受け付けます。省略した場合は、環境から解決されます。ID はあるもののハンドルがない場合は、クライアントでも同じ操作を実行できます(client.deploy(id)、client.undeploy(id))。

await client.listPortfolios({ includePaper: true, includePositions: true });
await client.getPortfolio(portfolioId);
保存済みポートフォリオの編集

updatePortfolio は、LLM を介さずに決定論的な編集を適用します。 operations 配列は型付きユニオンなので、コンパイラーは編集ごとに必要なフィールドを把握できます。

import type { PortfolioEditOperation } from "nexustrade";

const operations: PortfolioEditOperation[] = [
  { type: "rename", name: "AAPL Income" },
  {
    type: "replaceStrategy",
    targetStrategyId: strategyId, // or targetStrategyName
    strategyObject: nt.strategy(
      "Buy AAPL",
      nt.always(),
      nt.buy(nt.stockAsset("AAPL"), 25, "percent of portfolio"),
      {
        orderExecution: nt.limitOrder({
          price: nt.unitPriceLimit(150),
          workingTime: nt.goodForDay(),
        }),
      },
    ),
  },
];

await client.updatePortfolio(portfolioId, operations, {
  idempotencyKey: "aapl-limit-v1",
});

完成した portfolio パッチを指定して、updatePortfolio の操作を 1 つ使うことをおすすめします。 strategies、deployment(頻度とタイミング)、name、policy.stockEligibility、dividendPolicy、アラートをまとめて変更できます。省略したフィールドは保存済みの値が維持されます。ドラフトの開始資金と機能は、デプロイ前に限り変更できます。既存の戦略操作と名前変更操作も引き続きサポートされています。 1 回の呼び出しで対象に対して作成したすべての操作がまとめてコミットされます。検証に失敗した場合、どの操作も保存されません。同じ冪等性キーを再利用すると、保存済みの結果が再現されます。デプロイ、デプロイ解除、削除、自動承認は、引き続き個別のアカウント操作です。

replaceStrategies はセット全体を置き換えるため、配列から抜けた戦略は削除されます。変更しない戦略は、それぞれが持つ orderExecution も含めてそのまま引き継いでください。そうしないと、動作していた Limit が暗黙的に Market に戻ります。removeStrategies には取得したポートフォリオの戦略 ID を指定します。名前による削除は拒否されます。

株式の適格性は、作成時に指定します。portfolio(...) に policy: { stockEligibility } を渡すか、ハンドルで setStockEligibility(...) を呼び出すことで、時価総額の範囲、業種フィルター、 missingMarketCapBehavior、shareClassBehavior を設定できます。省略したフィールドにはデフォルト値が適用されます。GOOG/GOOGL のペア戦略には ALL_CLASSES が必要です。デフォルトでは企業ごとに 1 つの株式クラスのみが保持されるためです。

const pair = portfolio("GOOG/GOOGL pair", strategies, {
  policy: { stockEligibility: { shareClassBehavior: "ALL_CLASSES" } },
});

自動取引を作成時に指定することはできません。有効化できるのは所有者のみで、Portfolio Settings から行います。また、automatedApproval を指定するポリシーは送信前に拒否されます。取得したハンドルには、型付きの読み取り専用 policy スナップショットが含まれます。そのコピーを保存またはデプロイすると、株式の適格性のみが引き継がれます。

listPortfolios では、includePaper、includeLive、includeInactive、includeChatPortfolios、search、limit、page を使ってフィルターできます。search が設定されている場合、includePositions のデフォルトはオフです。

ここで作成するポートフォリオは常にペーパーです。_ライブ_ポートフォリオの作成は引き続きウェブアプリで行います。ここから注文や証券会社のステータスを確認できます。ライブ取引を参照してください。

ただし、deploy によってライブ取引が開始される場合があります。 すでにデプロイ済みのポートフォリオの ID を指定すると、そのポートフォリオは現在の種類のまま再有効化されます。そのため、一時停止中のライブポートフォリオに対する client.deploy(id) は、接続済みの証券会社を通じたライブ取引を再開します。また、上記の includeLive: true を指定すると、そのような ID が返されます。デプロイをシミュレーションとして扱う前に、deployment.deploymentType を確認してください。

ライブ取引

ライブ取引には、アカウントに証券会社をリンクする必要があります。リンクには OAuth リダイレクトを使うため、API キーでは完了できません。人が URL を開く必要があります。

await client.listBrokerages();
// [{ brokerage: "Alpaca", connected: false,
//    connectUrl: "https://nexustrade.io/live-trading" }, ...]

await client.connectBrokerage("Alpaca"); // logs the URL, waits until connected

connectBrokerage は、デフォルトでは stdout が TTY の場合にのみ待機します。CI、cron、または run_compute では、誰もいない状態で 5 分間停止するのではなく、メッセージ内の URL とともに brokerage_not_connected エラーで直ちに拒否されます。どちらかに固定するには { wait: true } または { wait: false } を渡してください。

ライブのみの一覧取得で結果が空の場合も、空の配列では理由が分からないため、同じエラーで拒否されます。

await client.listPortfolios({ includeLive: true, includePaper: false });
// NexusTradeApiError: brokerage_not_connected: No live portfolios, and no
// brokerage is connected. Connect one at https://nexustrade.io/live-trading
注文
const result = await client.createOrders(
  portfolioId,
  [
    {
      asset: { name: "SPY", type: "STOCK", symbol: "SPY" },
      side: "BUY",
      quantity: 10,
      orderType: "MARKET",
    },
  ],
  { idempotencyKey: "rebalance-2024-04-01" }
);

// Dollar notional (stock/crypto only — options require contract quantity):
await client.createOrders(
  portfolioId,
  [
    {
      asset: { name: "AAPL", type: "STOCK", symbol: "AAPL" },
      side: "BUY",
      amount: 500,
      orderType: "MARKET",
    },
  ],
  { idempotencyKey: "buy-aapl-500" }
);

ペーパー注文はただちに受け付けられます。ライブ注文は承認待ちとしてステージングされ、この呼び出しによってブローカーに送信されることはありません。

if (result.requiresApproval) {
  console.log("nothing has traded yet — approve at", result.approvalUrl);
}

承認なしでライブ注文を送信する引数、スコープ、フラグはありません。呼び出し元が何を求めても、証券会社との境界で未承認のライブ注文は拒否されます。これはこのメソッドが約束するものではなく、システムの特性です。1 リクエストあたりの注文数は最大 50 件です。

注文の一覧表示には read キーが必要です。キャンセルには trade キーが必要です。どちらも登録済みのアカウントが必要で、コンピュートサンドボックス内では利用できません。

const page = await client.listOrders({
  portfolioId,
  statuses: ["Accepted", "Pending User Approval"],
  page: 1,
  limit: 50,
});
console.log(page.orders, page.totalPages);

// Cancel only explicit IDs you selected from the listing.
const cancellation = await client.cancelOrders(["ORDER_ID"], {
  portfolioId,
  idempotencyKey: "cancel-order-v1",
});
console.log(cancellation.canceled, cancellation.rejected);

一覧表示のデフォルトは Accepted と Pending User Approval です。他の状態を確認するには、Pending、Partially Filled、Filled、または Canceled を明示的に指定してください。ページ番号は 1 から始まり、デフォルトの上限は 50 件、最大は 100 件です。レスポンスには orders、total、returned、page、limit、totalPages、truncated、ignoredStatuses が含まれます。有効なステータスが残っている場合、未知のステータスは ignoredStatuses に報告されます。フィルターに有効なステータスがない場合はエラーが発生します。 追加の保留中リバランスアクションのページを取得するには、 includeRebalanceOrders: true を設定します。リバランスアクションの ID は注文 ID と別のもので、キャンセルには渡せません。

キャンセルで指定できる ID は最大 50 件で、canceled 配列と rejected 配列が返されます。成功した各項目には orderId、mode(db、broker、または already_canceled)、および一緒にキャンセルされた兄弟レッグを含む canceledOrderIds が含まれます。拒否された各項目には orderId と reason が含まれます。両方の配列を確認してください。HTTP リクエストが成功しても、すべての注文がキャンセルされたとは限りません。別のポートフォリオの注文を誤ってキャンセルしないよう、任意でポートフォリオ ID を指定できます。再試行時は、同じ冪等性キーと同一のペイロードを再利用してください。すでにキャンセル済みの注文は already_canceled を返します。

MCP/REST と同じキャンセルルールが適用されます。Accepted と Pending User Approval の注文はキャンセルできますが、Pending、Partially Filled、Filled の注文は拒否されます。リバランスの子注文は、親アクションから管理する必要があります。ブローカー ID を持つライブ注文は、ブローカーのキャンセル処理を呼び出します。作成時も、ライブ注文は引き続き人による承認待ちとしてステージングされます。

独自のデータ

カスタムデータソースとは、センチメントの件数、独自のファクターなど、プラットフォームにまだ含まれていない、自分が所有する時系列データです。作成してから、戦略で CustomIndicator を使って参照します。

const series = await client.createCustomIndicator(
  {
    name: "WSB NVDA Mentions",
    scope: "asset",
    description: "Daily r/wallstreetbets mentions",
    pointKind: "observation",
    points: [
      { timestamp: "2024-04-01", value: 152, ticker: "NVDA" },
      { timestamp: "2024-04-02", value: 90, ticker: "NVDA" },
    ],
  },
  { idempotencyKey: "wsb-mentions-v1" }
);

const busy = nt.gt(
  nt.CustomIndicator(nt.stockAsset("NVDA"), String(series.customIndicatorId)),
  100
);
const book = nt.portfolio("Attention", [
  nt.strategy("Buy the buzz", busy, nt.buy(nt.stockAsset("NVDA"), 25)),
]);

scope は "global"(系列が1つ)または "asset"(ティッカーごとに系列が1つ。すべてのポイントに ticker が必要)です。作成後に変更することはできません。

時間的な意味がわかっている場合は、pointKind を指定してください。時点サンプルには observation、期間終了時の値には period_aggregate と aggregatePeriod(1d、1w、1mo、1q のいずれか)、各行に明示的な公開時刻がある値には disclosed を指定します。SDK はインライン書き込みと大容量アップロードの両方で、この契約を適用します。同日の日付のみの観測値は、翌暦日にずれるのではなく、明示的な同日 UTC 時刻になります。

サイズに制限はありません。 points の数に上限はありません。リクエストに収まるバッチはリクエストと一緒に送信され、それより大きなバッチはストレージにアップロードされ、呼び出しが完了する前に検証されます。いずれの場合も、返されるインジケーターには実際に登録されたデータが反映されます。また、アップロードの検証に失敗した場合は、成功を報告するのではなくエラーになります。

系列を継続して増やす場合。 実行ごとに同じ ID に追加します。

await client.appendCustomIndicatorPoints(
  String(series.customIndicatorId),
  [{ timestamp: "2024-04-03", value: 118, ticker: "NVDA" }],
  { idempotencyKey: "wsb-mentions-2024-04-03" }
);

実行ごとに新しい系列を作成すると、履歴が分断され、どの戦略からも読み取れなくなります。同一のバッチを再送信しても問題ありません。重複分が二重に書き込まれることはありません。

呼び出し目的
createCustomIndicator(spec, { idempotencyKey })作成、任意でデータを初期投入
appendCustomIndicatorPoints(id, points, { idempotencyKey })ポイントを追加
replaceCustomIndicatorPoints(id, points, { idempotencyKey })ID を維持してポイントを置換
archiveCustomIndicator(id) / restoreCustomIndicator(id)取り消し可能なライフサイクル
listCustomIndicators() / getCustomIndicator(id)ID とデータ範囲を確認

ポイントでは timestamp、value、ticker、assetType、availableAt を指定できます。キャメルケースとスネークケースのどちらも使用でき、Date オブジェクトも指定できます。値の日付より後にその値を把握できるようになった場合は、availableAt を設定してください。たとえば、四半期末の日付が付いたものの、数週間後に公開された業績の数値などです。認識されないフィールドを指定すると、暗黙に破棄されるのではなくエラーになります。

ディスク上にあるファイルを渡す場合は、createCustomIndicatorUpload/completeCustomIndicatorUpload/waitForCustomIndicatorUpload を使って、3つの手順を直接実行できます。CSV、JSON、JSONL に対応しており、サイズは最大 100 MB です。

エージェントの実行

ほかのジョブはすべて、実行して結果をポーリングします。エージェントは例外です。 3つの状態(pending_plan_approval、pending_action_approval、awaiting_user_input)では、あなたが対応しないと処理を進められません。実行を反復し、停止したら回答してください。

sequenceDiagram
    participant You
    participant Run as AgentRun
    participant Engine

    You->>Run: createAgent(prompt)
    Run->>Engine: POST /agents
    Engine-->>Run: run id

    loop for await (const event of run)
        Run->>Engine: GET events (cursor)
        Engine-->>Run: new events

        alt event.needsApproval
            Run-->>You: plan or action awaiting approval
            You->>Run: approve() or reject()
            Run->>Engine: POST approval
        else event.needsInput
            Run-->>You: awaiting user input
            You->>Run: say("...")
            Run->>Engine: POST message
        else
            Run-->>You: event.text
        end
    end

    Run-->>You: terminal

    Note over You,Engine: Without approve/say, the run stalls and bills.<br/>Reattach later with attachAgent(run.id).
const run = await client.createAgent("Find momentum names in the S&P 500", {
  idempotencyKey: "momentum-scan-v1",
  costCeilingUsd: 20,
});
for await (const event of run) {
  console.log(event.text);
  if (event.needsApproval) await run.approve();
  if (event.needsInput) await run.say("Focus on tech");
}

Lake SQL

NexusTrade の市場データレイクに対する読み取り専用 SQL で、サーバー側で解決される lake.* カタログを使用します。結果は、暗黙にメモリ上の配列へ展開されるのではなく、永続的な Parquet パーツとして保存されます。

flowchart LR
    A[createLakeQuery] --> B[waitForLakeQuery]
    B --> C[getLakeQueryManifest]
    C --> D[downloadLakeQueryPart]
    D --> E[Stream Parquet within your memory budget]
const query = await client.createLakeQuery(
  {
    query:
      "SELECT ticker, date, closingPrice FROM lake.daily_ohlc WHERE ticker = ?",
    params: ["AAPL"],
    limits: { maxRows: 10_000 },
  },
  { idempotencyKey: "aapl-daily-v1" }
);
const finished = await client.waitForLakeQuery(query.id as string);
const manifest = await client.getLakeQueryManifest(finished.id as string);

自然言語

SQL を書く代わりに、画面の内容を説明してください。サーバーが SQL を生成し、エンジンが読み取るものと同じ lake.* カタログに照らして検証してから実行し、行データと SQL 文の両方を返します。

const screen = await client.createNlScreen(
  "technology stocks with a market cap over 100 billion and a PE under 30"
);
const done = await client.waitForNlScreen(screen.id as string);

const result = done.result as Record<string, unknown>;
console.log(result.rows);
console.log(result.sql); // always check the SQL — it is model-generated

returnQuery の既定値が true なのは、SQL が監査証跡になるためです。SQL がなければ、行データは再現できない数値にすぎません。どの値を渡しても、失敗時には SQL が返されます。却下されたクエリこそ、読む価値が最も高いものだからです。

ステータスだけでなく、result.outcome に基づいて分岐してください。

outcome意味
ROWS一致する項目が見つかりました
EMPTYすべてのフィルターが実行されましたが、すべてを通過する項目はありませんでした。これも回答です
CLARIFICATION質問が曖昧です。result.clarification に確認内容が記載されます
GENERATION_FAILEDリトライ回数の上限に達しました。リトライする価値があるのはこのケースのみです

このメソッドは LLM のクレジットを消費します。以下の構造化された lake API は消費しません。

マニフェストと downloadLakeQueryPart を使って、ご自身のメモリ予算内で結果をストリーミングしてください。NexusTrade は、参照されているテーブルに適合するバックエンジンを選択します。エンジンが切り替わっても、SQL を変更する必要はありません。

Python SDK には、これらのエンドポイントを利用する DuckDB/pandas の便利なラッパー nt.lake.sql(...) も含まれています。

管理対象ウォッチリストのユニバース

nt.updateWatchlist({watchlistKey, memberId, instrument, amountBasis, chamber, output}) は、PoliticalRemainingPurchases から表示可能な管理対象リストを維持します。その戦略には条件がなく、注文も発注しません。nt.watchlistUniverse(watchlistKey) は、同じポートフォリオ内にある別の DynamicRebalance の対象として、その生成元が確定したメンバー構成を選択します。各キーには生成元が 1 つあり、複数のコンシューマーを設定できます。ほかのアクションタイプでは、このユニバースを使用できません。

const producer = nt.updateWatchlist({
  watchlistKey: "pelosi-holdings", memberId: "P000197", instrument: "Equity",
  amountBasis: "Midpoint", chamber: "All",
  output: {name: "Pelosi disclosed holdings", purpose: "Follow public holdings",
    alertSettings: {onChange: true, inApp: true, email: true, briefCadence: "weekly"}},
});
const consumerUniverse = nt.watchlistUniverse("pelosi-holdings");

output には、初期状態の名前、目的、アラートを指定します。その後のユーザーによる名前変更や設定が優先されます。ライブおよびペーパーのコンシューマーは、リストの永続的な公開を待ちます。バックテストではメンバー構成を実行内に保持し、ユーザーに表示されるリストは変更しません。銘柄の検出とデータ読み込みは引き続き全件対象となるため、パフォーマンスが向上するとは限りません。金額基準を省略した場合は LowerBound が使用されます。

updateInstitutionalWatchlist は、指定した運用会社の最新の一般公開済み完全株式ポートフォリオに正確に追従します。updateInsiderWatchlist は、一般公開された日を基準に条件を満たす買い付けを選択し、必要に応じて所有者、発行体、役職の範囲を指定できます。どちらも同じ公開およびコンシューマーの契約に従います。

const manager = nt.updateInstitutionalWatchlist({
  watchlistKey: "berkshire-equities", managerCik: "1067983",
});
const insider = nt.updateInsiderWatchlist({
  watchlistKey: "insider-purchases", windowDays: 90, role: "OfficerOrDirector",
});
const screen = nt.updateScreenerWatchlist({
  watchlistKey: "berkshire-top-20", refreshMinutes: 1440,
  columns: [nt.screenColumn("price", nt.screenPrice()),
    nt.screenColumn("holding", nt.screenDisclosure(manager.source))],
  filter: nt.screenAll(nt.screenCompare("price", "Gte", 5),
    nt.screenCompare("holding", "Gt", 0)),
  selection: nt.screenTop("holding", 20),
});
const screenUniverse = nt.watchlistUniverse("berkshire-top-20");

画面はスケジュールされた頻度で評価され、受け入れられたメンバー構成は更新の間、再利用されます。不足している事実は不明のまま扱われます。screenAny は OR ルールを組み合わせ、screenPercentile はフィルター済みの候補を、順位が判明している値に基づいてランク付けします。screenBarVolume と screenBarDollarVolume には、完了した過去のバーが必要です。このリリースでは、ライブのクオートからこれらの指標を取得できません。価格および開示指標はライブスクリーニングに対応しています。カバレッジまたは公開に失敗した場合、新規割り当ては停止しますが、コンシューマーの決済動作は維持されます。スクリーニングの実行にはインメモリの DuckDB を使用します。更新時にローカルのデータベースボリュームや LLM 呼び出しは必要ありません。

メソッドの完全なリファレンス

NexusTradeClient のすべての公開メソッドを記載しています。このパッケージでは、メソッドがここに記載されていない場合にテストが失敗するため、このリストがコードと食い違うことはありません。

ライブ取引と注文

メソッド目的
listBrokerages()接続可能なすべての証券会社と、リンク済みかどうかを取得します
getBrokerage(brokerage)指定した証券会社がリンク済みかどうかを取得します
connectBrokerage(brokerage, { wait })接続 URL をログに出力し、リンクされるまで待機します
createOrders(portfolioId, orders, { idempotencyKey })注文をステージングします。実取引の注文には承認が必要です
listOrders(options)ポートフォリオ/ステータスで絞り込み、ページネーション付きで自分の注文を一覧表示します
cancelOrders(orderIds, { idempotencyKey, portfolioId })明示した ID の注文をキャンセルし、それぞれの結果を返します

ポートフォリオ

メソッド目的
createPortfolio(book, { idempotencyKey })ポートフォリオの定義を保存します
listPortfolios(options)フィルターとページネーションを使ってポートフォリオを一覧表示します
getPortfolio(portfolioId)1 件のポートフォリオを取得します
updatePortfolio(id, operations, { idempotencyKey })作成済みのポートフォリオパッチをアトミックに保存します
forkPublicPortfolio(sharedId, { idempotencyKey })公開ポートフォリオをワークスペースにフォークします
deploy(portfolioId, { frequency })そのポートフォリオでペーパートレードを開始します
undeploy(portfolioId)停止します

バックテスト

メソッド目的
createBacktest(handle, { idempotencyKey })1 件のバックテストを送信します
createBacktests(handles, { idempotencyKey })1 回のリクエストで複数のバックテストを送信します
getBacktest(backtestId)操作の状態を取得します
waitForBacktest(backtestId, options)終了状態になるまで待機します
waitForBacktests(operations, options)バッチ全体の処理完了まで待機します

最適化とウォークフォワード

メソッド目的
createOptimization(handle, { idempotencyKey })最適化を送信します
getOptimization(optimizationId)操作の状態を取得します
waitForOptimization(optimizationId, options)終了状態になるまで待機します
createSystematicSweep(handle, { idempotencyKey })明示した遺伝子のスイープを送信します
getSystematicSweep(optimizationId)スイープ操作の状態を取得します
waitForSystematicSweep(optimizationId, options)終了状態になるまで待機します
createWalkForward(handle, { idempotencyKey })ウォークフォワード分析を送信します
getWalkForward(studyId)操作の状態を取得します
waitForWalkForward(studyId, options)終了状態になるまで待機します

カスタムデータソース

メソッド目的
createCustomIndicator(spec, { idempotencyKey })系列を作成します。必要に応じて初期データを設定できます
listCustomIndicators(options)所有する系列を一覧表示します
getCustomIndicator(id)1 つの系列を読み込み、ポイント数と範囲を確認します
appendCustomIndicatorPoints(id, points, { idempotencyKey })ポイントを追加します
replaceCustomIndicatorPoints(id, points, { idempotencyKey, allowShrink })ID を維持したまま系列全体を置き換えます
archiveCustomIndicator(id, { confirm })系列をソフトアーカイブします
restoreCustomIndicator(id)アーカイブ済みの系列を復元します
createCustomIndicatorUpload(id, options)アップロード用スロットを開きます(CSV/JSON/JSONL)
completeCustomIndicatorUpload(id, jobId)アップロードされたバイト列の検証を開始します
getCustomIndicatorUpload(id, jobId)アップロード操作を読み込みます
waitForCustomIndicatorUpload(id, jobId, options)検証が完了するまで待機します

エージェントの実行

メソッド目的
createAgent(prompt, { idempotencyKey })実行を開始します
getAgent(agentId)ステータスを読み込みます
attachAgent(agentId, { cursor })すでに実行中の処理に再接続します

Lake SQL

メソッド目的
createLakeQuery(request, { idempotencyKey })読み取り専用の SQL を送信します
getLakeQuery(queryId)操作を読み込みます
waitForLakeQuery(queryId, options)終了状態になるまで待機します
cancelLakeQuery(queryId)所有するクエリをキャンセルします
createLakeAsk(question)平易な言葉で Lake に質問します
getLakeAsk(askId)操作を読み込みます
waitForLakeAsk(askId, options)終了状態になるまで待機します
cancelLakeAsk(askId)所有する質問をキャンセルします
getLakeQueryManifest(queryId)スキーマ、チェックサム、パートのメタデータ
downloadLakeQueryPart(queryId, part, options)Parquet パートを 1 つダウンロードします
getLakeCatalog()クエリ可能なテーブルを一覧表示します
describeLakeTable(table)1 つのテーブルの列と型を表示します

自然言語

メソッド目的
createNlScreen(question, { returnQuery })自然言語の質問から銘柄をスクリーニングします
getNlScreen(screenId)操作を読み取ります
waitForNlScreen(screenId, options)終了状態になるまで処理をブロックします
cancelNlScreen(screenId)所有するスクリーニングをキャンセルします

クライアントの構築

メソッド目的
new NexusTradeClient({ apiKey, baseUrl })明示的な認証情報
new NexusTradeClient()厳しい制限付きの遅延匿名ワークスペース
NexusTradeClient.fromEnvironment()環境変数または .env から読み取ります
exportWorkspaceSession()匿名ワークスペースを後で使うためにエクスポートします
importWorkspaceSession(token)既存の匿名ワークスペースを再開します

PortfolioHandle — portfolio(...) ビルダーおよび getPortfolio / listPortfolios によって返されます。

メソッド目的
save({ idempotencyKey })下書きとして保存し、.id を設定します
backtest({ startDate, endDate, idempotencyKey })保存済みの ID を優先してバックテストします
deploy({ frequency })実際のペーパーポートフォリオを作成します(新しい ID)
undeploy()デプロイを無効化します
setStockEligibility(eligibility)送信する銘柄の適格性を設定します

認証

API キーは任意です。キーがない場合、最初の API 操作時に実際の未登録の NexusTrade ワークスペースが遅延作成され、リクエスト、バックテスト、AI の制限がより厳しく適用されます。匿名ワークスペースでは、ポートフォリオの作成、編集、フォーク、バックテストの開始、プログラムからのエージェント/チャット機能の利用が可能です。遺伝的探索や体系的なスイープの開始、結果の読み取り、再実行、昇格、アウトオブサンプルのワークフローなど、すべての最適化操作には登録済み API キーが必要です。新しいプロセスでも作業を引き継ぐ場合は、ワークスペースの不透明なトークンをエクスポートしてください。

const guest = new NexusTradeClient();
await guest.listPortfolios();
const token = guest.exportWorkspaceSession();

const resumed = new NexusTradeClient({ workspaceSession: token });

明示的なワークスペーストークンの有効期限が切れると、 NexusTradeWorkspaceSessionExpiredError が発生します。SDK は、保存済みの作業が削除されたように見えてしまう新しいワークスペースを作成することはありません。

登録ユーザーは nexustrade.io/developers(Profile → API Keys)でキーを作成できます。キーは sk- で始まり、一度だけ表示されます。両方の認証情報が指定されている場合は、登録済みの Authorization が優先され、ワークスペースヘッダーは送信されません。

const client = new NexusTradeClient({
  apiKey: "sk-...",
  baseUrl: "https://nexustrade.io/api/v1",
});
// or set NEXUSTRADE_API_KEY / NEXUSTRADE_API_BASE_URL and:
const fromEnv = new NexusTradeClient();

どちらの変数も、カレントディレクトリまたはその上位にある .env ファイルから読み込まれます。そのため、エクスポート、dotenv 依存関係、--env-file フラグなしでローカルプロジェクトを使用できます。

# .env
NEXUSTRADE_API_KEY=sk-...
NEXUSTRADE_API_BASE_URL=https://nexustrade.io/api/v1

実際の環境変数が常に優先されます。.env の値が使われるのは変数が未設定の場合のみなので、古いファイルがエクスポート済みの値を上書きすることはありません。process.env に書き戻されることはありません。無効にするには NEXUSTRADE_DISABLE_DOTENV=1 を設定してください。

スコープ許可される操作
readポートフォリオ、バックテスト、遺伝的探索、スイープ、ウォークフォワードの読み取り
writeポートフォリオの作成/編集/フォーク、バックテスト、遺伝的探索/スイープ、ウォークフォワードの開始
lakeLake カタログ、クエリのライフサイクル、マニフェスト、結果パーツ

必要なスコープがキーに含まれていない場合は、403 insufficient_scope が返されます。

OAuth はここでは使用できません。 NexusTrade の OAuth フローは MCP サーバー向けです。 これらのエンドポイントで使用できるのは sk- API キーのみです。ベアラー JWT は 401 invalid_token で拒否されます。

トランスポートの強化。 ループバックを除き、HTTPS が必須です。クライアントはオリジンをまたぐリダイレクトを拒否するため、認証情報が別のホストに再送されることはありません。また、GET 以外のリクエストではリダイレクトを追跡しないため、有料ジョブが再送されることはありません。キーは #private フィールドに保持され、文字列化したクライアントに表示されることはありません。

冪等性

すべての変更操作にはキーが必要です。同じリクエストで同じキーを再利用すると、2つ目の有料ジョブを開始する代わりに元のリソースが返されるため、ネットワーク障害後の再試行は無料です。

await client.createBacktest(handle, { idempotencyKey: "momentum-2024-v1" });

エラー

import { NexusTradeApiError } from "nexustrade";

try {
  await client.createBacktest(handle, { idempotencyKey: "run-1" });
} catch (error) {
  if (
    error instanceof NexusTradeApiError &&
    error.code === "rate_limit_exceeded"
  ) {
    // back off
  }
  throw error;
}
ステータスコード意味
401invalid_tokenキー(または OAuth JWT)がない、形式が不正、または期限切れです
403insufficient_scopeキーに read、write、または lake の権限がありません
400invalid_request、invalid_portfolio入力の形式が不正です
400invalid_idempotency_key[A-Za-z0-9._:-]{1,160} に一致する必要があります
409idempotency_conflict異なるペイロードでキーが再利用されています
409idempotency_in_progress同じキーの最初の呼び出しがまだ実行中です。再ポーリングし、再送信しないでください
404not_found、operation_not_found不明な対象、または自分のものではありません
429rate_limit_exceeded待機してから再試行してください

失敗を示す HTTP ステータスがない場合、status は 0 です。該当するのは transport_error(API に到達できなかった場合)、unsafe_redirect、または成功応答に対する invalid_response のエンベロープ検証です。

タイムアウト

new HttpTransport({ timeoutSeconds })(デフォルトは 30)は、1 回のリクエストに対する合計実時間の期限です。これもポーリングのタイムアウトも、ジョブの所要時間を制限するものではありません。

対象範囲

ポートフォリオの作成、バックテスト、最適化、ウォークフォワード分析、およびマーケットデータレイクに対する読み取り専用 SQL を、バージョン管理された /api/v1/nexustrade で提供します。すべての機能を利用するには登録済みの API キーが必要です。匿名ワークスペースでは、ポートフォリオの作成とフォーク、バックテスト、プログラムによるエージェント/チャットの呼び出しに限定されます。スクリーナーとライブデプロイの作成は対象外です。注文機能にはアクセスできますが、ライブ注文は人間の承認を得るためのステージングのみで、送信されることはありません。deploy と undeploy は、ライブのものも含め、既存の ID が示す対象に対して実行されます。

要件

Node 18 以降(グローバルの fetch を使用)。コントリビューションの場合、テストスイートは node --test で TypeScript を直接実行するため、型ストリッピングに対応した Node 22.6 以降が必要です。公開されている dist/ は通常の JavaScript であり、この要件はありません。

この SDK をコーディングエージェントと使用する

AGENTS.md を参照してください。エージェントが NexusTrade の戦略を最初の試行で正しく作成するために必要な規約、不変条件、レシピが記載されています。

ライセンス

MIT

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。