python初心者がQuantXでアルゴリズム投資にTryしてみる


#お前は誰だ？
はじめまして、都内の某大学に通う3年です。Pythonをマスターしようと必死に勉強中。1年以内に、pythonで機械学習を用いた投資アルゴリズムをゴリゴリと書けるように、精進してまいります。
記事に対する指摘や意見などありましたら、どんどんコメントください、よろしくお願い致します！

#QuantXとは
株式会社Smart TradeのメインサービスであるQuantXについて紹介します。
QuantX : https://quantx.io/top
>QuantXは株式や仮想通貨などの売買ルール(アルゴリズムと呼んでいます)の作成、販売ができるシステムトレードプラットフォームです。Python Codingを利用した自由度の高い方法と、Visual Codingを利用したプログラミングの知識がなくてもアルゴリズムを作成できる環境をご用意しています。（※Visual Codingは今後提供予定）作成されたアルゴリズムは実際の過去のデータでシミュレーションして成績を確認できます。開発したアルゴリズムはご自身のトレードに、またはQuantX Storeで販売できます。

限られたプロだけではなく、テクノロジーの力を駆使して、個人投資家などが広く自由に投資を行える環境を提供するというビジョンに共感しジョインしました。

#早速登録してみる
<img width="1243" alt="スクリーンショット 2018-12-25 11.42.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/269343/4d6d5f35-52c9-171d-7e5e-12be61d0da9e.png">
FacebookやGoogleアカウントでの登録もできるのでスムーズに登録できます。
登録すると、2019/01/31まで無料トライアルキャンペーンらしく、3つのアルゴリズムを無料で試せるとのこと、これは嬉しい！
<img width="1236" alt="スクリーンショット 2018-12-25 11.43.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/269343/585c3272-247f-2b1a-4a7d-9445e4635c51.png">

販売アルゴリズムは現在30個程度あります。ほとんどの累積損益がプラスって、めちゃくちゃ優秀なアルゴリズムばかりではないですか！！こうゆうのを見ると、勘や経験に頼る素人の株式投資なんてやってる場合ではないなぁと感じます。
<img width="1062" alt="スクリーンショット 2018-12-25 11.46.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/269343/f81ec1ee-10a0-8b48-d285-1c1a19796a2a.png">

#移動平均線を用いたアルゴリズムを作成してみる
QuantX Factory : https://factory.quantx.io/
コーディングの経験も乏しいですが、ザッカーバーグの名言である「Done is better than perfect.」に習い、サンプルコードを利用し、3種類のポートフォリオ×買い・売りラインを{1,2,3}%と変更し、アルゴリズム作成を試みようと思います。
<img width="1235" alt="スクリーンショット 2018-12-25 14.05.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/269343/0bbca6c9-7c45-b005-86fa-d06d321e2934.png">

ポートフォリオは以下の通り！
###ポートフォリオ1(バランス型)
サイバーエージェント
村田製作所
小田急
三菱東京UFJ銀行
日水
日本テレビHD
東京電力
三菱地所
ソフトバンクグループ


###ポートフォリオ2(マザーズ企業)
ミクシィ
デジタルガレージ
アドウェイズ
オイシックス・ラ・大地
カヤック
ALBERT
そーせいグループ
アクトコール
ライフネット生命保険

###ポートフォリオ3(銀行株)
三井住友フィナンシャルグループ
千葉銀行
みずほフィナンシャルグループ
三菱東京UFJ銀行
新生銀行
りそなホールディングス
セブン銀行
横浜銀行
静岡銀行

コードは以下そのまま貼り付けていただければ、恐らく動くと思います。

```python:algo.py

import pandas as pd
import talib as ta
import numpy as np

def initialize(ctx):
    # 設定
    ctx.logger.debug("initialize() called")
    ctx.configure(
      target="jp.stock.daily",
      channels={          # 利用チャンネル
        "jp.stock": {
          "symbols": [
            'jp.stock.4751',    #   サイバーエージェント
            'jp.stock.6981',    #   村田製作所
            'jp.stock.9007',    #   小田急
            'jp.stock.8306',    #   三菱東京UFJ銀行
            'jp.stock.1332',    #   日水
            'jp.stock.9404',    #   日本テレビHD
            'jp.stock.9501',    #   東京電力
            'jp.stock.8802',    #   三菱地所
            'jp.stock.9984',    #   ソフトバンクグループ
          ],
          "columns": [
            #"open_price_adj",    # 始値(株式分割調整後)
            #"high_price_adj",    # 高値(株式分割調整後)
            #"low_price_adj",     # 安値(株式分割調整後)
            "close_price",        # 終値
            "close_price_adj",    # 終値(株式分割調整後) 
            "volume_adj",         # 出来高
            "txn_volume",         # 売買代金
          ]
        }
      }
    )

    def _mavg_signal(data):
        #ns_sentiment = data["ns_sentiment"].fillna(method="ffill")
        # ctx.logger.debug(ns_sentiment)
        m25 = data["close_price_adj"].fillna(method='ffill').ewm(span=25).mean()
        dfma25 = (data["close_price_adj"] -  m25) / m25 * 100

        buy_sig = dfma25[(dfma25 < -3)]
        sell_sig = dfma25[(dfma25 > 3)]
        return {
            "mavg_25:price": m25,
            #"mavg_ratio:ratio": ratio,
            "buy:sig": buy_sig,
            "sell:sig": sell_sig,
        }

    # シグナル登録
    ctx.regist_signal("mavg_signal", _mavg_signal)

def handle_signals(ctx, date, current):

    '''
    current: pd.DataFrame
    '''

    done_syms = set([])
    for (sym,val) in ctx.portfolio.positions.items():
        returns = val["returns"]
        #ctx.logger.debug("%s %f" % (sym, returns))
        if returns < -0.02:
          sec = ctx.getSecurity(sym)
          sec.order(-val["amount"], comment="損切り(%f)" % returns)
          done_syms.add(sym)
        # elif returns > 0.08:
        #   sec = ctx.getSecurity(sym)
        #   sec.order(-val["amount"], comment="利益確定売(%f)" % returns)
        #   done_syms.add(sym)


    buy = current["buy:sig"].dropna()
    for (sym,val) in buy.items():
        if sym in done_syms:
          continue

        sec = ctx.getSecurity(sym)
        sec.order(sec.unit() * 1, comment="SIGNAL BUY")
        #ctx.logger.debug("BUY: %s,  %f" % (sec.code(), val))
        pass

    sell = current["sell:sig"].dropna()
    for (sym,val) in sell.items():
        if sym in done_syms:
          continue

        sec = ctx.getSecurity(sym)
        sec.order(sec.unit() * -1, comment="SIGNAL SELL")
        #ctx.logger.debug("SELL: %s,  %f" % (sec.code(), val))
        pass
```


#結果発表
3つのポートフォリオの損益率をまとめました。
※本当は他の指標も考慮するべきですが、初回なのでこのへんで、、、

|ポートフォリオ|±1%|±2%|±3%|
|---|:---:|---:|---:|
|1：バランス型|27.94%|22.08%|5.54%|
|2：マザーズ企業|-15.50%|-28.78%|-3.01%|
|3：銀行株|-9.49%|-7.92%|-7.82%|
いちばんポジティブな結果が出たポートフォリオ1で乖離率1%でシグナルは以下のようなパフォーマンスでした。
<img width="1242" alt="スクリーンショット 2018-12-25 15.56.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/269343/48db3310-4795-e23d-c1c6-54eb14fd34c2.png">

#まとめ
・パフォーマンスが一番良かったのはポートフォリオ1のシグナル±1%
・ベンチマークがプラスであっても、銘柄の選び方次第で損益率がマイナスになる

ということで、次回は新しい指標を織り交ぜてアルゴリズムの開発を行い、もっと深い考察を導けるようにしたいと思います。