IB API (3) オプション情報の取得

[IB API利用の準備～価格データのリクエスト](http://qiita.com/esplo/items/76849371bf1d3aec80fe)
[IB API (2) 仕組み～呼び出しの共通化](http://qiita.com/esplo/items/1815f7796dfcfc31ebcf)
の続きです。
今回はSPYのオプション情報を取得します。

# 対象者
- オプションを自動売買したい
- 売買アルゴリズムのカスタマイズを自由にしたい
- Java/C++/C#など、使い慣れた言語で書きたい
- IB証券(LLC)の口座を持っている

前回と同様ですが、今回はオプションのみです。

# 処理の流れ

1. まず対象の銘柄を決めます。今回はSPYにします
2. 銘柄に対し、オプションの一覧を取得します
3. 各オプションに対し、Greeksや価格を取得

2と3は同時にできそうですが、APIの仕組み上、まずは一覧を取得し（2）、詳細は一覧のそれぞれに対して要求します（3）。

# 関連するAPI

- 呼び出し) reqContractDetails
- コールバック) contractDetails / contractDetailsEnd

銘柄の詳細が得られます。
オプションでは、期日やストライクプライス・Call/Putの区別などが取得できます。

- 呼び出し) reqMktData
- コールバック) tickSnapshotEnd

リアルタイムで価格情報を取得します。
ただし、今回は「その時点での価格」があれば十分なので、引数で「スナップショットをください」と指定します。
スナップショットを要求した場合のみ、処理が終了した時点で`tickSnapshotEnd`が呼ばれます。
詳細はサンプルで。

- コールバック) tickPrice
- コールバック) tickSize
- コールバック) tickString
- コールバック) tickOptionComputation

reqMktDataをオプションに対して呼び出すと、↑の4つが呼ばれます。
tickPrice, tickSize, tickStringは一般的なリアルタイムデータを、tickOptionComputationは
Greeksやオプション価格を返してくれます。

# 手順

まずは、銘柄詳細を得る所までです。

```scala
val contract = new Contract()
contract.m_symbol = "SPY"
contract.m_secType = "OPT"
contract.m_currency = "USD"
contract.m_exchange = "SMART"

val reqId = client.getNextValidId()
client.socket.reqContractDetails(reqId, contract)
```

これにより、IBClient::contractDetailsでデータが返ってきます。
ここで重要なのは、contractDetails.m_summaryです。
この中にオプション1つの**リアルタイムでない**情報が入っています。

例えば、
`m_summary.m_expire`には期日、
`m_summary.m_strike`にはストライクプライス、
`m_summary.m_right`には"P"か"C"が入っています。

[Contract](https://www.interactivebrokers.com/en/software/api/apiguide/java/contract.htm)

データは↓のように処理します。

```scala
  override def contractDetailsEnd(reqId: Int): Unit =
    // complete

  override def contractDetails(reqId: Int, contractDetails: ContractDetails): Unit = {
    val contract = contractDetails.m_summary
    val date = LocalDate.parse(contract.m_expiry, DateTimeFormatter.ofPattern("yyyyMMdd"))
    // リストにcontractを保持、後でそれぞれに対しリアルタイムデータを要求する
  }
```

contractDetailsが何度か呼び出され、全てのオプション情報が取得できたらcontractDetailsEndが呼ばれます。

では次に、各オプションに対して価格情報などを取得します。

```scala
optionList.foreach(e =>
  client.socket.reqMktData(id, e.m_summary, "", true, null)
)
```

データは↓のように処理します。
今回はオプション以外のデータは不要として、捨てています。

```scala
override def tickPrice(tickerId: Int, field: Int, price: Double, canAutoExecute: Int): Unit = {}
override def tickSize(tickerId: Int, field: Int, size: Int): Unit = {}
override def tickString(tickerId: Int, tickType: Int, value: String): Unit = {}

override def tickOptionComputation(tickerId: Int, field: Int, impliedVol: Double, delta: Double, optPrice: Double, pvDividend: Double, gamma: Double, vega: Double, theta: Double, undPrice: Double): Unit = {
    val opt = // tickerIDに対応するデータ格納用変数
    opt.delta = delta
    opt.impliedVol = impliedVol
    opt.optPrice = optPrice
    opt.undPrice = undPrice
  })
}

override def tickSnapshotEnd(reqId: Int): Unit = {
  // complete
}
```

↑の例ではdeltaだけ保存していますが、引数にある通りGreeksは揃っています。



## 備考

存在するオプションの一覧を先に取得し、個別に価格を取り出すのが少しややこしいかもしれません。
とはいえ、リアルタイムで価格情報を更新するにはこうならざるを得ません。

なお、全てのオプションデータに対して価格を要求すると時間がかかるので、
私は期日や現在値±N%でフィルタリングしたりしています。

# まとめ

今回はオプション価格やGreeksの取得を行いました。
サンプルは最小限なので、データを上手く格納して処理しやすい形にしましょう。

次回は自動売買らしく、オーダーを投げてみます。