QuantX SDK チョットワカル になりたい

# 【注意】maron0.0.1で実行しています!!!新エンジン(maron0.0.5)での実行については保証できないので注意してください!!

# 対象の読者
- QuantX FactoryとQuantX SDKの基本的な使い方は知っていて、QuantX SDKのより詳しい使い方を知りたい人。
- 「QuantX SDKチョットワカル」と自信を持って言えるようになりたい人。

# 始めに
この記事は、[QuantX SDK](https://pypi.org/project/quantx-sdk/)を使用する上で気づいた私の細かな知見を共有する記事です。基本的な使用方法は[この記事](https://qiita.com/katakyo/items/ac01dcd6c692c3585596)を参照してください。また、QuantX SDKの基本的な使い方は知っているものとして話を進めていきます。


## quantx_sdk.root module

```py
from quantx_sdk import QX
qx = QX(access_key, secret_key)
```
SDKを使う時に最初に生成するqxのことです。個人的に便利に感じたroot moduleの便利なメソッドを紹介します。

### current_rate_limit()
現在のレートリミットを取得します。

#### 使用例

```py
ret = api.current_rate_limit()
# limit値
limit = ret["limit"]
# 残り呼び出し回数
remaining = ret["remaining"]
```

#### Tips
SDKでは大量のバックテスト処理を行うことが多いかと思います。しかし、あまり多くのバックテストを実行するとAPI制限を食らってしまうことがあります。そこでremainingを利用することにより残りの呼び出し回数によって処理を変えることができます。

```py
while(true):
    # ---
    # バックテストを行うような何かしらの処理
    # ---
    ret = api.current_rate_limit()
    remaining = ret["remaining"]
    if remaining < 100:
        time.sleep(60 * 10)
```

## quantx_sdk.backtest_result module

```py
res = project.backtest(bt_params)
res = res.join()
```

名前の通り、バックテストの結果です。次はこのbacktest_moduleが持つ便利関数を紹介します。

### benchmark()
損益率の推移を取得します。戻り値はpandas.DataFrameになっています。
このDataFrameのcolumnは

```py
Index(['portfolio_value', 'cash', 'positions_value', 'returns', 'pnl',
       'portfolio_daily_returns', 'benchmark', 'benchmark_cumulative_returns',
       'benchmark_daily_returns', 'portfolio_cumulative_returns'])
```

となっていて、各行に各日付のデータが入っています。

#### イメージ
```py
            portfolio_value      cash  ...  benchmark_daily_returns  portfolio_cumulative_returns
index                                  ...
2016-06-06         10000000  10000000  ...                      NaN                           0.0
2016-06-07         10000000  10000000  ...                 0.005754                           0.0
2016-06-08         10000000  10000000  ...                 0.009325                           0.0
2016-06-09         10000000  10000000  ...                -0.009655                           0.0
2016-06-10         10000000  10000000  ...                -0.004020                           0.0
```

#### 使用例

```py
df = res.benchmark()
```


### log()
バックテストのログを返す関数です。つまり`ctx.logger.debug()`関数などによってQuantXのログの部分に出力される文字列を取得できます。

#### 使用例
```py
print(res.log())
```

### signal_history_by_symbol(symbol)
引数で`jp.stock.xxxx`(文字列)のような銘柄コードを指定して、その銘柄のシグナル履歴を取得できます。つまりアルゴリズムで定義したinitalize()関数の_my_signal()関数の戻り値の部分の各日付の値を取得できます。

#### 使用例
言葉だけではあまり伝わらないと思うので実際に使ってみます。_my_signal()関数の戻り値をこのように定義します。

```py
return {
    "wma5":s_wma,
    "wma25":m_wma,
    "wma75":l_wma,
    "buy:sig": buy_sig,
    "sell:sig": sell_sig,
}
```

このアルゴリズムのバックテストをSDKで実行し`res.signal_history_by_symbol('jp.stock.9943')`を見てみましょう。

```py
# 先頭5つを抜粋
            buy:sig  sell:sig        wma25         wma5        wma75
2016-06-06      0.0       0.0  1864.698462  1866.000000  1873.122807
2016-06-07      0.0       0.0  1864.504615  1864.400000  1872.653684
2016-06-08      0.0       0.0  1864.400000  1863.866667  1872.208772
2016-06-09      0.0       0.0  1864.378462  1863.733333  1871.788772
2016-06-10      0.0       0.0  1864.104615  1862.533333  1871.292982
```
確かにシグナルを取得できています。
この表を可視化して、取得した値が正しいのか確認してみましょう。

```py
from matplotlib import pyplot as plt

# dfに9943の銘柄のシグナルを入れる
df = res.signal_history_by_symbol('jp.stock.9943')
# DataFrameが持つplot関数で可視化
df.plot(y=['wma5'])
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227269/597fe9a6-3188-b6e5-4ef8-bedb91e6767d.png)

このような結果となりました。QuantX Fuctoryの方で全く同じコードを同じ条件で実行しwma5を見てみると、たしかに概形が同じであることを確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227269/c3801a00-5322-1cab-f779-f8b667c5bdd9.png)

#### Tips
アルゴリズムの戻り値定義の部分を

```py
return {
    "wma5":s_wma,
    "wma25":m_wma,
    "wma75":l_wma,
    "cpa": data["close_price_adj"],
    "buy:sig": buy_sig,
    "sell:sig": sell_sig,
}
```
SDK実行側のコードを

```py
df = res.signal_history_by_symbol('jp.stock.9943')
df['cpa']
```

のようにすることで終値の取得もできます。


他にも始値や出来高等も取得できます。なにを取得できるかは[ドキュメント](https://factory.quantx.io/handbook/ja/api.html#ctx)を参照してください。

### trade_history_by_symbol(symbol)
引数に指定した銘柄の取引履歴を取得します。戻り値は注文日、完了日、値段、量などが入ったDataFrame型です。

#### 使用例

```py
df2 = res.trade_history_by_symbol('jp.stock.9943')
print(df2)
```

```py
#先頭5つ抜粋
             date order_date complete_date  price  amount  comission      comment
0   jp.stock.9943 2016-07-11    2016-07-12   1874    4200          0   SIGNAL BUY
1   jp.stock.9943 2017-03-06    2017-03-07   2044    -100          0   SIGNAL BUY
2   jp.stock.9943 2017-03-29    2017-03-30   2021     100          0   SIGNAL BUY
3   jp.stock.9943 2017-05-17    2017-05-18   2056    -100          0   SIGNAL BUY
4   jp.stock.9943 2017-08-31    2017-09-01   2273    -100          0   SIGNAL BUY
```

#### Tips
先程の`signal_history_by_symbol`関数と合わせると、QuantX Factoryで描画されるグラフとほとんど同じものをローカルで描画できるようになります。(需要があるかはわかりませんが…)

##### コード例

```py
df = res.signal_history_by_symbol('jp.stock.9943')
df2 = res.trade_history_by_symbol('jp.stock.9943')

plt.plot(df.index, df['wma75'])
plt.plot(df.index, df['cpa'])

for complete_date, amount in zip(df2['complete_date'], df2['amount']):
    complete_date = str(complete_date).split()[0]
    if amount >= 0:
        plt.scatter(complete_date, df['cpa'][complete_date], color='r')
    else:
        plt.scatter(complete_date, df['cpa'][complete_date], color='b')
plt.show()
```
##### 結果
QuantX上で描画されたグラフ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227269/f566c057-61a6-16c1-a1c0-a0f46094d633.png)

ローカルで描画されたグラフ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227269/a064fbd8-53ae-730f-fa94-f0db5875dd63.png)

# おしまい
ここまで読んでいただきありがとうございました。間違ってるところがあれば教えてください。

# 参考
[Google Colaboratory上で行うQuantX-SDK事始め](https://qiita.com/katakyo/items/ac01dcd6c692c3585596)
[quantx-sdk](https://pypi.org/project/quantx-sdk/)