仮想通貨と自動売買bot(python)

プログラミング初心者です。いろんなアドバイスもらいたいのでぜひコメントください。

Aroon indicator (アルーン・インジケーター)について

 ふとあるつぶやきを思い出した。

f:id:bitcoinbot:20180712065802p:plain

 

Aroon? Chop Zone?    .8つくらい知らない
さらに読み進めると・・・

 

f:id:bitcoinbot:20180712070205p:plain

          Aroonとは何か?
  この謎を解明すべく我々スタッフはTradingViewの奥地へと向かった。

 

 

 

f:id:bitcoinbot:20180712070827p:plain

あった!

なぜ最弱の海にいた魚人の名前になっているのかは分かりませんが

確かにありました。

 

どんなものか確認

f:id:bitcoinbot:20180712071527p:plain

もしかしたらこのインジのギザギザ感とやつの鼻が少し似てるせいかもしれません。

f:id:bitcoinbot:20180712071723p:plain

 

 本文

 

こんばんは! 

 茶番が長引きましたが、

今回↑のツイートを思い出してアルーンってインジが気になったので調べてみました。

 

一応ざっと解説してみますが、

詳しくはとても分かりやすい参考サイトさんを参照してください。

(記事の下に貼ってあります)

 

 アルーンについて

(トレンド系テクニカル)

先ほどの画像をもう1度

f:id:bitcoinbot:20180712071527p:plain

 ・2種類の線、アルーンアップとアルーンダウン 
(画像ではup=オレンジ、down=ブルー)

upでは上昇トレンドの

downでは下降トレンドの 発生、持続、消失などを示唆します

 

・計算式  14日間 (n=14)

up = n-n期間中の最高値からの経過日数/n×100

down = n-n期間中の最安値からの経過日数/n×100

 

 計算式からわかるように100%なら強いといった訳ではなく、

100%がトレンドの始まりといった感じになります。

また高い数値が継続されているとトレンド継続中

 upが低い=「上昇トレンドではない」であって「下降トレンドである」ではないので注意

(このup-downで算出した数値を使ったアルーンオシレーターというものもある)

 
 ・主な使い方

 ①2本の線のクロスをエントリーの判断に使う

 ②今はトレンド中(70~100)かどうか、補助的に使う

 

 気づいたこと

 

 どういうものかはわかったけど、結局これ使えるの?

って声が外からも自分からも聞こえてきそうです。

 

自分流に考えてみる

上の方にも書いた通りaroonが100%になったときは「トレンドの始まりを示唆」

トレンドフォローの観点で考えるとそこでエントリーするのは良さそうです。

100%の状況(upの場合)

n日中の最高値から0日経過している=その足が最高値を更新している。

つまり「直近n期間の最高値更新」で入ることになります。

 

これってなんかに似てませんか?、、、

 
ド、ド、ド、ドンチャンチャネルブレイクアウトだ!!!

 

そうなるとエントリーはなかなかよさそうです

 

Aroonは通常n=14で使われるようですが、

この場合だともう少し長いほうがいいかもしれません。

(aroonの特性上期間が長ければ長いほどトレンド持続の判定が緩くなります)

 

次はトレンドの持続(70~100)が損切、利確にうまく機能するか等になりますね。

もしかしたらトレイリングストップなどより上手く機能するかもしれません。

 

今回はこれくらいにします!

もう少し色々してみて良さそうなら「最強のBOT候補①」にしようと思います。

 何か意見などありましたらぜひコメントしてください。 ではまた

 

 

参考サイト

twitter @akagami_v2 

xn--fx-ph4angpet59xn23a.jp

www.g913-jiro.com

 

 

 

個人的なメモ集

同じアカウントで複数のロジック管理する方法

・全部指値で奇数、偶数に分ける。

bitmexは指値で入らなかった場合注文しないみたいなことできた気がする。(要確認)

・idごとに管理?

結構大変そう

0.001単位の注文

指値0.011BUY,0.01SELLでできるか確認する。

pythonのローカル関数はマジックミラー号

・関数内から外の変数を参照することはできるけど外から中は見えない。

 

     

最強のBOTは何か?

 

f:id:bitcoinbot:20180708043941j:plain

 

こんばんは 

pythonを使って色々記事を書いていく中で

骨組みのような感じのコードを共有しながら

各記事の内容に応じて書き換えたりしたほうが読んでる方的にも良いのかなぁ

と思ってるんですが、関数とかクラスとか使ってキレイに書けないです。Orz

 

 

さて、次回からはツイッターの有名な人やFX(為替)サイトなどに紹介されている手法で気になったものを記事ごとにまとめて、何個か実装したら軽く比較したりしてみます!

 

 

 

            最強のBOTは何か⁉ 

           

 

          その答えの一端がこのブログで・・・・

 

 

              

 

             

 

 

内容のレベルは低いので読み物として楽しんで頂けたら幸いです。ではまた

 

 

 (追記

 エンベロープは期待していましたがナイスな使い方思いつきませんでした泣

 

 

 

RSI 取得 (python)

 

RSIの取得が上手くいったっぽいので忘れないうちに自分用に説明を書きます、

よければ参考にしてください。

RSIの種類

単純移動平均を使って求めるもの(カトラー作)
②α=1/期間の指数移動平均指数平滑移動平均、指数加重移動平均)を使って求めるもの(j.w.ワイルダー作)
③指数移動平均を使って求めるもの(α=2/(n+1))

 

(③についてはネットにほとんど書いてなかったので稀だと思いますが一応そういう算出方法をあるようなので注意)

 

自分は「指数移動平均って直近の値だけ2倍するやり方」ってイメージが強かったので

「クソ!何度やり直してもRSIの数値がおかしくなっちまう」って感じでした。

 

f:id:bitcoinbot:20180708005316p:plain

正しくは②です(というよりtradingviewなどは②)

 具体的な計算式については記事の下に参考サイトを貼ってあるのでそちらで確認してください。

過去データを使った1時間足のRSIを算出するコード

 

 

f:id:bitcoinbot:20180708012338p:plain

f:id:bitcoinbot:20180708022707p:plain

f:id:bitcoinbot:20180708012005p:plain

(※ コードの乗せ方がいまだにわからないので画像ですみません。)

 

1枚目の画像の部分のコードはhttps://ryota-trade.com/ さんの記事中のものを一部使わせてもらってます。

なので2、3枚目の画像の部分を説明していきます。

 

・まず3枚目のメイン処理について

 

upper =  値上がり幅

lower =  値下がり幅

を入れるリストを作ります。

差分の計算は一番古いデータからはできないので

i = 0ではなく1にしています

*1

 

now_range = price[i]["close_price"]-price[i-1]["close_price"

]で今の足と前回の足の値幅を計算しています。

 

if 前回より値が上がっているとき

elif 前回より下がっているとき

else 前回とまったく一緒のとき

と処理にしています 

(一応確認したらまったく同じときも稀にあるようなのでこうしました。)

具体的にいうと、

ifのとき 値上がり幅のリストに値上がり分を追加して、値下がり幅のリストにはマイナスではなく0を追加します。

 

最後の if文でiがRSI算出期間の2倍以上のときにRSIを求める処理をします。

(なんで2倍なのかあとで説明)

 

 

・ 2枚目のRSIを求める関数について

 RSIの平均値上がり幅、値下がり幅は指数移動平均で求めるので、

今回の平均値上がり幅を求めるのに前回の平均値上がり幅が必要になり

前回の平均値上がり幅を求めようとすると前々回の平均値上がり幅が必要になる

 前々回の平均値上がり幅を求めるためには当然前々々回の平均値上がり幅が・・・

 

なのでRSIの期間が6だとしたら

11足前までさかのぼって

11~6足前までの6足でまず単純移動平均を出し、

6足前のときの平均値上がり幅を

(現在の値上がり幅+上で出したSMA)÷期間(6)

で5足前の平均値上がり幅を求められます。

for i in range(value-1):

期間6なのでここではiに0~4までの数字を繰り返し入れていきます。

(※range(n)は0からnの1つ前までの数字 という意味なので注意)

このループで4足前、3足前、2足前、1足前、と繰り返されていき、

現在足の平均値上がり幅が求められます

(値下がり幅の方もまったく同じやり方です)

最後にRSIの公式 

平均値上がり幅÷(平均値上がり幅+平均値下がり幅)×100

 

かなり分かりづらくてすみません 

リストからのスライスが[-1]で一番新しいやつになるのでかなりややこしくて頭が爆発しそうになりました。いまいちわかんなかったら自分で考えてみて下さい。

 

 検証

実際に合ってるか確かめます。

・今回のコードで出したRSI

f:id:bitcoinbot:20180708022859p:plain

(一番下の数値は現在足のもの)

・TradingView

f:id:bitcoinbot:20180708024037p:plain

4つ前の46は一致しています

正直この画像じゃ全然検証できませんでした;;

 

 計算自体は合ってると思います(強引)

ただ、TVにより近い数値にしたい場合はRSIをどんどん引き継いで求めるやり方がいいです。

 

以上です、いろいろ意見ください。

 

参考にさせてもらったサイト

https://fxcashback.info/rsi-calculation/

https://ryota-trade.com/?p=5175

 

*1:

priceは1時間足の過去データ500足が入ったリスト。

price[0]が一番古いデータ 

price[-1]で一番新しいデータ

テクノファンダさんの「クロコダイル」のpineスクリプトを翻訳

pineが書けないので自分用に翻訳として書きます。

が、間違ってたら教えてくれたらうれしいです。

up = rma(max(change(hlc3), 0), 6)
down = rma(-min(change(hlc3), 0), 6)
hlc3  #(高値+安値+終値)/3  平均値
 
change(hlc3) 現在の足の平均値と前回の足の平均値の差
max( x,y )  # xとyで大きい方を返す max(平均上り幅,0)
rma(x,y) # upの場合 過去(6期間の)平均値上がり幅を指数移動平均を使って出す
(※自分で作る場合6期間前の値上がり幅を求めるために7期間前の足まで取得する必要があるかも ここらへんいまいちわからない・・・)
  
udCal = up_down_calculate

udCal(up, down) =>

      if down == 0

          100

n期間上がりっぱなしだったら100%

  if up == 0

    0
n期間下がりっぱなしだったら0%
else
 100 - (100 / (1 + up / down))  
 
例)過去6期間の平均値上がり幅60 平均値下がり幅30 
 =100-(100/(1+60/30))
=100-33=67  
67%

 

fastrsi = udCal(up, down) #平均値を使ったRSI完成

エントリー条件

Buy_IN = close<open and abs(close - open) > ema(abs(close - open), 5)*1.1 and sma(fastrsi,4)<20

 

 

close<open

①(最新の確定足の)終値始値より低い

abs(close - open) > ema(abs(close - open), 5)*1.1

②(最新の確定足の)値幅が期間5の指数移動平均値幅(高値-安値)の1.1倍より大きい

sma(fastrsi,4)<20

③直近4足分のRSIの平均値が20%より低い

(※直近の確定足から3つ前の足まで)

(※3つ前のRSIを求めるには過去10足必要)

 

決済条件

( positionsize>0 and fastRSI>20 ) or ( positionsize<0 and fastRSI<80 )
position_size は買いを持っていたら正の値に、売りを持っていたら負の値になる

上のコードだと ←が買いポジションのとき →が売りポジションのときです。

条件は「RSIが20より上がったら(買いポジションを)売る。

    RSIが80より下がったら(売りポジションを)買い戻す。」

 

要約すると

「直近4本の「ローソク足の平均値を使ったRSI」の平均が20以下で買い(80以上で売り)、20以上(80以下)になったら決済する」手法のようです。

 

独自のRSIの出し方と直近のRSIの平均を使うというアプローチが参考になります。

 

自分で再現したかったので、ひとによってはコードを見ればわかることだと思いますがpineを調べながら文字に起こしてみました。

初歩的なことかもしれませんが参考になれば幸いです、

また間違いとかあったら是非コメントで教えてください

 

追記

pythonで実装してみたんですが、なんかものすごく結果が悪かったです 

どこかしら間違ってると思われます。。。

 

追記

RSI正常に実装するのに3日掛かりました。

 

あと記事内で修正移動平均と解釈してましたが正しくはRSIを計算するときに使う指数平滑平均をpineだとrmaと表記してるだけだと思います(記事修正済み) よってEMAで自分は計算しました。

 

 再々追記

RSIの計算に使う指数移動平均のα=1/期間です。

詳しくは下の記事で書いてます。

bitcoinbot.hatenablog.com

 

 

 

ドンチャンブレイクアウトをオープニングレンジブレイクアウトに変えてバックテストしてみる。

この検証では(https://ryota-trade.com/?p=1942)さんの記事内のコードを勝手に使わせて頂こうと思います!(初心者の自分にはこちらのサイトは恩師のような存在です、また不都合があれば即座に消したいと思います。)

 

大まかな手法の説明については上記サイト内の「オープニングレンジ~」の所を見て下さい。

具体的なルール

① 直近の足の始値が過去N期間の平均値幅(高値-安値)のx%動いたらその方向にその足の終値で注文、決済

② 直近の足が①の条件を上にも下にも満たしてるとき、終値がある方向に注文

(※②は自分が勝手にやってるだけなのでしないほうが良いかもしれません)

 

条件

時間足 1、2時間

期間N 3、5

で固定して

変動率xを探ってみて、その結果どうなのかを見ていこうと思います。

 

# 平均ボラティリティを計算する関数

def calculate_volatility( last_data ):
high_sum = sum(i["high_price"] for i in last_data[-1 * volatility_term :])

low_sum  = sum(i["low_price"]  for i in last_data[-1 * volatility_term :])

volatility = round((high_sum - low_sum) / volatility_term)

       return volatility        これをコピー  (他の記事から参照)

 

def donchian(data, last_data ): 

これを

# レンジブレイクを判定する関数

def range_break( data,last_data ):

 volatility = calculate_volatility(last_data)*R

 if (data["high_price"]-data["open_price"]) > volatility and (data["open_price"]-data["low_price"]) > volatility :

    if data["close_price"] > data["open_price"] :

    return {"side": "BUY" ,"price":0}

          else:

               return {"side": "SELL" , "price":0}

    if (data["high_price"]-data["open_price"]) > volatility :

          return {"side":"BUY","price":0}

    if (data["open_price"]-data["low_price"]) > volatility :

          return {"side":"SELL","price":0}

return {"side" : None , "price":0}   

 

あとはentry_signalとclose_position内のdonchianの部分も変えてあげて、

設定値の項目にvolatility_term = 3 #(5)   , R = 好きな数値 (変動率)を追加

ピンと来る名前が思い浮かばなかったので適当にRにしました。

 

結果 (以下ある程度良かったもの いずれも1LOT固定) 

(1時間足,期間3,R=2)    

f:id:bitcoinbot:20180627134010p:plain

 

(2時間足,期間5,R=2)

f:id:bitcoinbot:20180627134833p:plain

 

 ドンチャンと比べてみる

 左:期間20のドンチャン1H    真ん中: 期間20のドンチャン2H   右:期間6のレンジブレイクアウト2H

f:id:bitcoinbot:20180627140341p:plain

 

 以上です、ありがとうございました! 

初心者ですのでもしかしたら根本から間違っている可能性があるため何かありましたら是非コメントで教えてください。