bitcoin自動売買のバックテスト(過去チャートから勝率を算出)のやり方
参考URL
バックテストの評価軸
1. トレード回数を100回以上
いくら儲かる確率が高いアルゴリズムでも、そのチャンスが年に1回しかないと意味ないので
ある程度の頻度でチャンスが訪れないとダメ!
2. 勝率
100回トレードして、利益が出たのは何回か?
60回なら、勝率60%
3. 平均リターン
1回のトレードで、平均何%のリターンがあったか?
1万円で買って、1万300円で売れたら、3%のリターン
4. 総利益額
テストの最初と最後で、原資が何倍になったのか?
5. 最大ドローダウン
テスト中に、軍資金がどのくらい減ったかのマックス値
100万円が70万円になったら、最大ドローダウンは30%(これくらいが限界)
他が良くても、ここが低いとメンタル的に辛い
実際の値を使ったバックテスト。1分足(60秒)で過去1000分(16時間40分)
常に右肩上がりなら、最初に買って、最後に売れば良い戦略。運が良ければ儲かる?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
import requests from datetime import datetime import time # 最初に1度だけCryptowatchから価格データ取得。1分足(60秒)で過去1000分(16時間40分)がもらえる response = requests.get("https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc",params = { "periods" : 60 }) # 指定されたローソク足の価格データ(OHLC)を返す関数 def get_price(min,i): data = response.json() return { "close_time" : data["result"][str(min)][i][0], "open_price" : data["result"][str(min)][i][1], "high_price" : data["result"][str(min)][i][2], "low_price" : data["result"][str(min)][i][3], "close_price": data["result"][str(min)][i][4] } # 時間と始値・終値を表示する関数 def print_price( data ): print( "時間: " + datetime.fromtimestamp(data["close_time"]).strftime('%Y/%m/%d %H:%M') + " 始値: " + str(data["open_price"]) + " 終値: " + str(data["close_price"]) ) # ここからメイン処理の部分 data = response.json(); max_index = len(data["result"]['60']) # # 取得した一番最初の値段で、1ビットコイン買う first_data = get_price(60,0) print_price( first_data ) buy_price = first_data['open_price'] print("買った値段:" + str(buy_price)) # 取得した一番最後の値段で、1ビットコイン売る last_data = get_price(60,max_index-1) print_price( last_data ) sell_price = last_data['open_price'] print("売った値段:" + str(sell_price)) # 結果 print("損益:" + str(sell_price - buy_price)) |
さすがに運否天賦すぎるので、もうちょい判断を入れよう。
一番最初に買って、少しでも高値になったら売るだと、利益は確実に出そうだけど、少なすぎるので0.1%以上(300万円なら3千円)値上げしたら売るとか?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
import requests from datetime import datetime import time # 最初に1度だけCryptowatchから価格データ取得。1分足(60秒)で過去1000分(16時間40分)がもらえる response = requests.get("https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc",params = { "periods" : 60 }) # 指定されたローソク足の価格データ(OHLC)を返す関数 def get_price(min,i): data = response.json() return { "close_time" : data["result"][str(min)][i][0], "open_price" : data["result"][str(min)][i][1], "high_price" : data["result"][str(min)][i][2], "low_price" : data["result"][str(min)][i][3], "close_price": data["result"][str(min)][i][4] } # 時間と始値・終値を表示する関数 def print_price( data ): print( "時間: " + datetime.fromtimestamp(data["close_time"]).strftime('%Y/%m/%d %H:%M') + " 始値: " + str(data["open_price"]) + " 終値: " + str(data["close_price"]) ) # ここからメイン処理の部分 data = response.json(); max_index = len(data["result"]['60']) # 取得した一番最初の値段で、1ビットコイン買う first_data = get_price(60,0) print_price( first_data ) buy_price = first_data['open_price'] print("買った値段:" + str(buy_price)) # 全ループ処理 i = 0 while i < max_index: data = get_price(60,i) # 1%以上値上がったら売る。 if buy_price*1.01 < data['open_price']: print_price(data) sell_price = data['open_price'] print("売った値段:" + str(sell_price)) # 結果 print("損益:" + str(sell_price - buy_price)) break i+=1 # 取得した一番最後の値段 last_data = get_price(60,max_index-1) print_price( last_data ) |
う~ん、290万→270万みたいな超下げ相場だと、まったく売れない(苦笑)
時間: 2022/06/16 08:06 始値: 2923110 終値: 2917892
買った値段:2923110
時間: 2022/06/17 00:56 始値: 2714612 終値: 2715498
損切を考えないとダメだな。
3%上がったら利確。3%下がったら損切みたいにしてみよう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
import requests from datetime import datetime import time # 最初に1度だけCryptowatchから価格データ取得。1分足(60秒)で過去1000分(16時間40分)がもらえる response = requests.get("https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc",params = { "periods" : 60 }) # 指定されたローソク足の価格データ(OHLC)を返す関数 def get_price(min,i): data = response.json() return { "close_time" : data["result"][str(min)][i][0], "open_price" : data["result"][str(min)][i][1], "high_price" : data["result"][str(min)][i][2], "low_price" : data["result"][str(min)][i][3], "close_price": data["result"][str(min)][i][4] } # 時間と始値・終値を表示する関数 def print_price( data ): print( "時間: " + datetime.fromtimestamp(data["close_time"]).strftime('%Y/%m/%d %H:%M') + " 始値: " + str(data["open_price"]) + " 終値: " + str(data["close_price"]) ) # ここからメイン処理の部分 data = response.json(); max_index = len(data["result"]['60']) # 取得した一番最初の値段で、1ビットコイン買う first_data = get_price(60,0) print_price( first_data ) buy_price = first_data['open_price'] print("買った値段:" + str(buy_price)) # 全ループ処理 i = 0 while i < max_index: data = get_price(60,i) # 3%以上値上がったら売る。 if buy_price*1.03 < data['open_price']: print_price(data) sell_price = data['open_price'] print("売った値段:" + str(sell_price)) # 結果 print("損益:" + str(sell_price - buy_price)) break # 3%以上値下がったら損切 if buy_price*0.97 > data['open_price']: print_price(data) sell_price = data['open_price'] print("売った値段:" + str(sell_price)) # 結果 print("損益:" + str(sell_price - buy_price)) break i+=1 # 取得した一番最後の値段 last_data = get_price(60,max_index-1) print_price( last_data ) |
ビットコインの過去データを引っ張ってこないとダメだな、こりゃ~
時間: 2022/06/16 08:16 始値: 2898796 終値: 2896768
買った値段:2898796
時間: 2022/06/16 09:34 始値: 2811498 終値: 2806801
売った値段:2811498
損益:-87298
時間: 2022/06/17 01:06 始値: 2725926 終値: 2723220
時間を置いて実行すると+3%で利確できた。
いつエントリー(買い・売り)して、いつ利確するかの(%やチャートで)判断を自動化するのがポイントか…。
やっぱ機械学習しか無いよな~。
時間: 2022/06/20 05:03 始値: 2676242 終値: 2679287
買った値段:2676242
時間: 2022/06/20 08:34 始値: 2759334 終値: 2750593
売った値段:2759334
損益:83092
時間: 2022/06/20 23:13 始値: 2749986 終値: 2744938