LoginSignup
13
4

More than 5 years have passed since last update.

QuantXで初めてのアルゴリズムを書いてみて気づいたことをちょっと.

Last updated at Posted at 2018-05-13

QuantXとは

QuantXとは,Pythonで投資アルゴリズムを開発出来るウェブアプリケーションです.
詳しくは,@hiroshimodaさんのPythonで投資アルゴリズムを開発してみるをご参照下さい.

シグナル関数の書き方

(ある程度,python と pandas と QuantXを知っている人向けに書いています.)

QuantXの株価情報は pandas.Panel に入っていて,パネル使いにとっては便利な構造です.

Panel に慣れている人であれば, QuantX の help に記載されている
[DEMO] 移動平均を使った基本的なアルゴリズムも,このように書き直したくなるとおもいますが,

datapandas.Panel 型なのだから,このようにかけるはずだよね,と思ってSmartTradeさんに問い合わせたところ、dataはRead Onlyだそうで,itemを追加することは出来ないそうです.
よって下記のようには書けません:no_good_tone3:

## 間違った書き方!
    def _mavg_signal(data):

      ##欠損値を埋める
      data["close_price_adj"] = data["close_price_adj"].fillna(method='ffill')
      data["ma25"] = data["close_price_adj"].rolling(window=25, center=False).mean()
      data["ma75"] = data["close_price_adj"].rolling(window=75, center=False).mean()
      data["ratio"] = data["ma25"] / data["ma75"] 
      data["buy_signal"] = (data["ratio"] > 1.02) & (data["ratio"] < 1.05)
      data["sell_signal"] = data["ratio"] < 0.95

      return {
        "MA_25": data["ma25"], 
        "MA_75": data["ma75"], 
        "buy:sig": data["buy_signal"],
        "sell:sig": data["sell_signal"],
      }

    ctx.regist_signal("_mavg_signal", _mavg_signal)

ただしくは↓のように,変数に入れて扱わなくてはいけません.


    def _mavg_signal(data):

      ##欠損値を埋める
      data["close_price_adj"] = data["close_price_adj"].fillna(method='ffill')
      ma_25 = data["close_price_adj"].rolling(window=25, center=False).mean()
      ma_75 = data["close_price_adj"].rolling(window=75, center=False).mean()
      ratio = ma_25 / ma_75

      buy_signal = (ratio > 1.02) & (ratio < 1.05)
      sell_signal = ratio < 0.95

      return {
        "MA_25": ma_25, 
        "MA_75": ma_75,
        "buy:sig": buy_signal,
        "sell:sig": sell_signal,
      }

    ctx.regist_signal("_mavg_signal", _mavg_signal)

ta-lib使ってみる時は,こんな感じで書けばいいとおもいます.

    def _wma_signal(data):
      TIME_PERIOD = 25
      data["close_price_adj"] = data["close_price_adj"].fillna(method='ffill')

      dwna = dict()
      dwna_roc = dict()
      for symbol in data.minor_axis:
        dwna[symbol] = ta.WMA(data["close_price_adj"][symbol].values.astype(np.double), timeperiod=TIME_PERIOD)
        dwna_roc[symbol] = ta.ROC(dwna[symbol], 1) 

      wma = pd.DataFrame(dwna, index=data.major_axis)
      wma_roc = pd.DataFrame(dwna_roc, index=data.major_axis) 

      buy_sig = wma_roc > 0
      sell_sig = wma_roc< 0
      ctx.logger.info(buy_sig)      

      return {
        "wma_25":wma,
        "wma_roc_25": wma_roc,
        "buy:sig":buy_sig,
        "sell:sig": sell_sig,
      }

    # シグナル登録
    ctx.regist_signal("wma_signal", _wma_signal)

注意点

  1. return に渡す辞書の key 名は,dataの item 名と被ってはいけません.例えば "ma25": data["ma25"]と渡すと,ValueError columns overlap but no suffix specified と怒られます.
  2. 保存ボタンを押さないと,保存されません:sob:.他のページに(誤って)移動してしまった場合でも,警告も出ません :scream:.お気をつけ下さい. ←これは警告が出るように修正されました!

提案

QuantXさん,
もし、functools の import が許されるなら、talib を使うアルゴリズムはこう書けるはずで、もっとすっきりするはずなのですが、いかがでしょうか?(自信ないけど.)


import functools

    def _wma_signal(data):

      TIME_PERIOD = 25
      mywma = functools.partial(ta.WMA,timeperiod=TIME_PERIOD)
      myroc = functools.partial(ta.ROC, timeperiod=1)

      data["close_price_adj"] = data["close_price_adj"].fillna(method='ffill')
      wma = data["close_price_adj"].apply(mywma)
      wma_roc = data["close_price_adj"].apply(myroc)
      buy_sig= wma > 0
      sell_sig = wma_roc < 0

      return {
        "wma_25":wma,
        "wma_roc_25": wma_roc,
        "buy:sig":buy_sig,
        "sell:sig": sell_sig,
      }

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



勉強会

ほぼ,毎週水曜日,SmartTradeさんの会議室で,Pythonアルゴリズム勉強会という会が開かれていて,QuantXの勉強をしたい人や,python でアルゴリズム書きたいとか,その他情報がほしい人などが集まっていますので,気になる方は参加してみてはいかがですか?

私は,だいたい毎回行っています:grinning:

13
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
4