![見出し画像](https://assets.st-note.com/production/uploads/images/5925356/rectangle_large_4a78bab92d2936b28c27728308a55a54.jpg?width=1200)
Coincheck、自動売買bot BTC/JPY Python DO IT YOURSELF..
こんにちは。。暗号通貨の自動売買プログラムです(現物取引)。。Python で書かれています。。移動平均のクロスを見て売買を決めています。。このプログラムをたたき台にして自分独自のアルゴリズムを組み込んでいただけたらと思っています。。(儲かる可能性は大いにあると思います。。ただこのままじゃあまり儲かりません)。。
いま自分は ubuntu や CentOS 上で動かしています。。(ご要望があれば ubuntu や CentOS でプログラムを動かす方法を別記事で書くこともできます)。。(たぶん Windows でも動くと思います。。あるいは VirtualBOX に ubuntu を入れれば確実に動きます)。。
Python のほうは今回書くまでほとんど触ったことがなく自分もひたすらググりながら書きました。。おかしなところは多々あると思います。。ご指摘いただけると嬉しいです(勉強になります)。。
以下ソースがベタに貼ってあるだけですが、ログをとったりデータの保存をしたりしているばかりで自動売買の本質部分はそう多くありません。。ある程度ソースが読めて改造ができる方、あるいはチャレンジしたい方向けの記事です。。 このコードをコピペしてエディタに貼り付けて適当な名前を付けて実行してください。。
なお現在は売り買いとも 0.005(BTC) づつになっています。。本来ならほぼ全額買いほぼ全額売りのアルゴリズムですが様子がわわかるまではこのまま少額づつ取引をしたほうが良いでしょう。。
なお Coincheck 用のライブラリを使用しています。。ここからダウンロードして Setup しておいてください。。https://github.com/coincheckjp/coincheck-python
わからないことがありましたらお気軽にお問い合わせください。。(できる範囲でですが)お答えさせていただきます。。メール:hot@chilipepper.red。。なお取引や Python などについては詳しくなくお答えできません。。(暗号通貨の取引は自分も初心者です。。専門用語は全然わかりません)。。あくまでこのプログラムの内容に関してのみお答えできます。。
何万円も出して高いツールを使うのはもったいないです。。DO IT YOURSELF..の精神で頑張りましょう。。1万円を1億円にしましょう。。
貴方の暗号通貨ライフがハッピーなものであるようお祈りさせていただきます(^^)v。。
なおこのプログラムによっていかなる損害が発生しても責任は取りかねますのでご了承ください。。
2018/04/04 無料公開しました。。
# -*- coding: utf-8 -*-
import datetime
import time
import os, json
import random
from coincheck.coincheck import CoinCheck
import logging
CC_API_KEY = 'API_KEY'
CC_API_SECRET = 'API_SECRET'
DATA_NAME = "ShioriCcIdouBTCJPYData.txt"
LOGALL_NAME = "ShioriCcIdouBTCJPYAll.log"
LOGTRADE_NAME = "ShioriCcIdouBTCJPYTrade.log"
MAX_RATE = 8
MAX_MEANDIFF4 = 2
MAX_MEANDIFF8 = 2
def GetRateA(repeat=1) :
# Coincheck
rateNow = 0.0
rateBuy = 0.0
rateSell = 0.0
for i in range(repeat) :
# Rate
res = Cc.ticker.all()
rate = json.loads(res)
rateNow += (float(rate["bid"]) + float(rate["ask"])) / 2.0
rateBuy += float(rate["ask"])
rateSell += float(rate["bid"])
rateNow /= repeat
rateBuy /= repeat
rateSell /= repeat
return rateNow,rateBuy,rateSell
def GetBalanceA() :
# Coincheck
# Balance
res = Cc.account.balance()
balance = json.loads(res)
if (balance["success"] == False) :
raise Exception(balance["error"])
else :
return balance["jpy"],balance["btc"]
def BuyA(rate,amount) :
# Coincheck
params = {
'rate': "{0:.8f}".format(rate),
'amount': amount,
'order_type': 'buy',
'pair': 'btc_jpy'
}
res = Cc.order.create(params)
order = json.loads(res)
if (order["success"] == False) :
raise Exception(order["error"])
def SellA(rate,amount) :
# Coincheck
params = {
'rate': "{0:.8f}".format(rate),
'amount': amount,
'order_type': 'sell',
'pair': 'btc_jpy'
}
res = Cc.order.create(params)
order = json.loads(res)
if (order["success"] == False) :
raise Exception(order["error"])
def OpensA() :
# Coincheck
params = {
}
res = Cc.order.opens(params);
orders = json.loads(res)
if (orders["success"] == False) :
raise Exception(orders["error"])
if (orders['orders'] != []) :
return orders['orders'][0]["id"]
else :
return 0
def CancelA(orderid) :
# Coincheck
params = {
'id': orderid
}
res = Cc.order.cancel(params)
cancel = json.loads(res)
if (cancel["success"] == False) :
raise Exception(cancel["error"])
def GetFile() :
global Count,CcRateNow,MeanDiff4,MeanDiff8,BalanceBought
# タイムスタンプ
now = datetime.datetime.today();
d = now.strftime("%Y/%m/%d %H:%M:%S")
if (os.path.isfile(DATA_NAME) == False) :
# 【重要】プログラム初回起動時前にデータファイルを削除しておくこと。
Count = 0
msg = "データファイルが存在しません。"
toLog(d, msg, "TA")
print (d+" "+msg)
return True;
else :
# データファイル読み込み
try :
h = open(DATA_NAME,"r")
x = json.load(h)
h.close()
except Exception as e :
msg = "データファイルの読み込みに失敗しました。("+str(e.args)+")\n"
toLog(d, msg, "A")
print (d+" "+msg)
return False
# 代入
Count = x["Count"]
BalanceBought = x["BalanceBought"]
Rate = x["Rate"]
MeanDiff4 = x["MeanDiff4"]
MeanDiff8 = x["MeanDiff8"]
# シフト
for i in range(MAX_RATE-1) :
Rate[i] = Rate[i+1]
Rate[MAX_RATE-1] = CcRateNow
for i in range(MAX_MEANDIFF4-1) :
MeanDiff4[i] = MeanDiff4[i+1]
for i in range(MAX_MEANDIFF8-1) :
MeanDiff8[i] = MeanDiff8[i+1]
# カウント
Count += 1
# ログ
y = json.dumps(x)
msg = "File Read:" #+y
toLog(d, msg, "A")
print (d+" "+msg)
return True
# Coincheck から情報を取得する
# 戻り値: TRUE 成功
# FALSE 失敗
def GetCoincheck() :
global CcRateNow,CcRateBuy,CcRateSell,BalanceJPY,BalanceBTC
global F_Buy,F_Sell,F_Non
global BalanceBought
# タイムスタンプ
now = datetime.datetime.today();
d = now.strftime("%Y/%m/%d %H:%M:%S")
try :
# Rate
CcRateNow,CcRateBuy,CcRateSell = GetRateA(1)
except Exception as e :
msg = "CcRate の取得に失敗しました。("+str(e.args)+")\n"
toLog(d, msg, "TA")
print (d+" "+msg)
return False
try :
# Balance
BalanceJPY,BalanceBTC = GetBalanceA()
except Exception as e :
msg = "Balance の取得に失敗しました。("+str(e.args)+")\n"
toLog(d, msg, "TA")
print (d+" "+msg)
return False
# ログ
if (F_Buy == True) :
msg = "RateBuy:"+"{0:.8f}".format(CcRateBuy)+"(JPY) BalanceJPY:" \
+str(BalanceJPY)+"(JPY) BalanceBTC:"+str(BalanceBTC)+"(BTC) BalanceAll:" \
+"{0:.8f}".format(float(BalanceJPY) + float(BalanceBTC) * float(CcRateBuy))+"(JPY)"
elif (F_Sell == True) :
msg = "RateSell:"+"{0:.8f}".format(CcRateSell)+"(JPY) BalanceJPY:" \
+str(BalanceJPY)+"(JPY) BalanceBTC:"+str(BalanceBTC)+"(BTC) BalanceAll:" \
+"{0:.8f}".format(float(BalanceJPY) + float(BalanceBTC) * float(CcRateSell))+"(JPY)"
# profits は厳密に計算しない。参考程度に。。
profits = (float(BalanceJPY) + float(BalanceBTC) * float(CcRateNow)) - float(BalanceBought)
msg2 = "Profits:"+"{0:.8f}".format(profits)+"(JPY)"
toLog(d, msg2, "TA")
print (d+" "+msg2)
else :
msg = "RateMean:"+"{0:.8f}".format(CcRateNow)+"(JPY) BalanceJPY:" \
+str(BalanceJPY)+"(JPY) BalanceBTC:"+str(BalanceBTC)+"(BTC) BalanceAll:" \
+"{0:.8f}".format(float(BalanceJPY) + float(BalanceBTC) * float(CcRateBuy))+"(JPY)"
toLog(d, msg, "TA")
print (d+" "+msg)
return True
def Calcurate() :
global Count,MeanDiff4,MeanDiff8,Amount,Rate
global CcRateBuy,CcRateSell,CcRateNow
global BalanceJPY,BalanceBTC
if (Count < MAX_RATE) :
# タイムスタンプ
now = datetime.datetime.today()
d = now.strftime("%Y/%m/%d %H:%M:%S")
msg = "Calcurate はキャンセルされました。"
toLog(d, msg, "A")
print (d+" "+msg)
return
# 移動平均を計算している (必要に応じて修正)
# 移動平均1回
Mean1= Rate[MAX_RATE-1]
# 移動平均4回
sum = 0.0
for i in range(4) :
sum += Rate[i]
Mean4 = sum / 4.0
MeanDiff4[MAX_MEANDIFF4-1] = Mean1 - Mean4
# 移動平均8回
sum = 0.0
for i in range(8) :
sum += Rate[i]
Mean8 = sum / 8.0
MeanDiff8[MAX_MEANDIFF8-1] = Mean4 - Mean8
# タイムスタンプ
now = datetime.datetime.today()
d = now.strftime("%Y/%m/%d %H:%M:%S")
Amount = 0.0
# 買い条件を決めているところ(要修正)
# 買い注文
if ((Amount == 0.0)\
and (MeanDiff4[MAX_MEANDIFF4-1] >= 0 and MeanDiff4[MAX_MEANDIFF4-2] < 0)) :
Amount = 0.005 #round (float(BalanceJPY) * 0.999999 / float(CcRateBuy) - 0.0005,4)
if (Amount < 0.005) : # Coincheck の最小売買単位
Amount = 0.0
msg = "Calcurate Amount(Buy):"+str(Amount)
toLog(d, msg, "A");
print (d+" "+msg)
# 売り条件を決めているところ(要修正)
# 売り注文
if ((Amount == 0.0) \
and (Rate[MAX_RATE-1] < Rate[MAX_RATE-2])) :
Amount = -0.005 #float (BalanceBTC)
if (-Amount < 0.005) : # Coincheck の最小売買単位
Amount = 0.0
msg = "Calcurate Amount(Sell):"+str(Amount)
toLog(d, msg, "A");
print (d+" "+msg)
# 何もしない
if (Amount == 0.0) :
msg = "Calcurate Amount(Non):0.0";
toLog(d, msg, "A");
print (d+" "+msg)
def PutCoincheck() :
global Count,Amount,CcRateBuy,CcRateSell,CcRateNow
global BalanceJPY,BalanaceBTC,BalanceBought
global F_Buy,F_Sell,F_Non,F_Cancel,RateNow
if (Count < MAX_RATE+3) :
# タイムスタンプ
now = datetime.datetime.today()
d = now.strftime("%Y/%m/%d %H:%M:%S")
msg = "PutCoincheck はキャンセルされました。";
toLog(d, msg, "A")
print (d+" "+msg)
return
F_Buy = False
F_Sell = False
F_Cancel = False
# タイムスタンプ
now = datetime.datetime.today()
d = now.strftime("%Y/%m/%d %H:%M:%S")
if (Amount > 0.0) :
try :
# 買い注文
balancebuy = float(BalanceJPY) + float(BalanceBTC) * float(CcRateNow)
BuyA(CcRateBuy,Amount)
msg = "注文(買い)を出しました。"
toLog(d, msg, "TA")
print (d+" "+msg)
except Exception as e :
msg = "注文(買い)に失敗しました。"+str(e.args)
toLog(d, msg, "TA")
print (d+" "+msg)
return False
# 約定待ち (必要に応じて修正、単位は秒)
time.sleep(20)
# タイムスタンプ
now = datetime.datetime.today()
d = now.strftime("%Y/%m/%d %H:%M:%S")
try :
orderid = OpensA()
except Exception as e :
msg = "未約定注文一覧の取得に失敗しました。"+str(e.args)
toLog(d, msg, "TA");
print (d+" "+msg)
return False
if (orderid != 0) :
try :
CancelA(orderid)
msg = "注文をキャンセルしました。"
toLog(d, msg, "TA");
print (d+" "+msg)
F_Cancel = True
return True
except Exception as e :
msg = "キャンセルに失敗しました。"+str(e.args)
toLog(d, msg, "TA")
print (d+" "+msg)
BalanceBought = balancebuy
F_Buy = True
return False
BalanceBought = balancebuy
msg = "Buy "+str(Amount)+"(BTC)"
toLog(d,msg,"TA")
print (d+" "+msg)
F_Buy = True
return True
elif (Amount < 0.0) :
try :
# 売り注文
SellA(CcRateSell,-Amount)
msg = "注文(売り)を出しました。"
toLog(d, msg, "TA")
print (d+" "+msg)
except Exception as e :
msg = "注文(売り)に失敗しました。"+str(e.args)
toLog(d, msg, "TA")
print (d+" "+msg)
return False
# 約定待ち (必要に応じて修正、単位は秒)
time.sleep(20)
# タイムスタンプ
now = datetime.datetime.today()
d = now.strftime("%Y/%m/%d %H:%M:%S")
try :
orderid = OpensA()
except Exception as e :
msg = "未約定注文一覧の取得に失敗しました。"+str(e.args)
toLog(d, msg, "TA");
print (d+" "+msg)
return False
if (orderid != 0) :
try :
CancelA(orderid)
msg = "注文をキャンセルしました。"
toLog(d, msg, "TA");
print (d+" "+msg)
F_Cancel = True
return True
except Exception as e :
msg = "キャンセルに失敗しました。"+str(e.args)
toLog(d, msg, "TA")
print (d+" "+msg)
Pos = 0.0
F_Sell = True
return False
msg = "Sell "+str(Amount)+"(BTC)"
toLog(d,msg,"TA")
print (d+" "+msg)
F_Sell = True
return True
else :
# 何もしない
msg = "non:0.0(BTC)";
toLog(d, msg, "A");
print (d+" "+msg)
F_Non = True
return True
def PutFile() :
global Count,Pos,Rate,MeanDiff4,MeanDiff8,BalanceBought
# タイムスタンプ
now = datetime.datetime.today()
d = now.strftime("%Y/%m/%d %H:%M:%S")
# Json
x = {"Date":d,"Count":Count,"BalanceBought":BalanceBought,"Rate":Rate, \
"MeanDiff4":MeanDiff4,"MeanDiff8":MeanDiff8}
y = json.dumps(x)
try :
h = open(DATA_NAME,"w")
h.write(y)
h.flush()
h.close()
except Exception as e :
msg = "データファイルの書き込みに失敗しました。("+str(e.args)+")\n"
toLog(d, msg, "A")
print (d+" "+msg)
return
msg = "File Write:" #+y
toLog(d, msg, "A")
print (d+" "+msg)
#
# ログファイルへ書き込み
#
def toLog(time, msg, opt) :
x = time + " " + msg
if (opt == "TA" or opt == "AT") :
LogAll(x+"\n");
LogTrade(x+"\n")
elif (opt == "A") :
LogAll(x+"\n");
elif (opt == "T") :
LogTrade(x+"\n")
def LogAll(str) :
try :
h = open(LOGALL_NAME,"a")
h.write(str)
h.flush()
h.close()
except Exception as e :
print ("ログファイル(All)の書き込みに失敗しました。("+str(e.args)+")")
def LogTrade(str) :
try :
h = open(LOGTRADE_NAME,"a")
h.write(str)
h.flush()
h.close()
except Exception as e :
print ("ログファイル(Trade)の書き込みに失敗しました。("+str(e.args)+")")
#
# main
#
def main() :
global BalanceJPY,BalanceBTC
global Count,MeanDiff4,MeanDiff8,Rate
global BalanceBought,F_Buy,F_Sell,F_Non,F_Cancel
global Cc
while True :
# タイムスタンプ
now = datetime.datetime.today()
d = now.strftime("%Y/%m/%d %H:%M:%S")
msg = "Start:"+str(__file__)
toLog(d, msg, "A")
print (d + " " + msg)
Rate = [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0] # MAX_RATE
MeanDiff4 = [0.0,0.0] # MAX_MEANDIFF4
MeanDiff8 = [0.0,0.0] # MAX_MEANDIFF8
BalanceBought = 0.0
F_Buy = False
F_Sell = False
F_Non = False
Cc = CoinCheck(CC_API_KEY, CC_API_SECRET)
# stop というファイルが存在すれば以降の処理をキャンセルする
if os.path.exists('stop') :
# タイムスタンプ
now = datetime.datetime.today();
d = now.strftime("%Y/%m/%d %H:%M:%S")
msg = "stop ファイルが存在するため実行をキャンセルしました。"
toLog(d, msg, "A")
print (d + " " + msg+"\n")
# タイムスタンプ
now = datetime.datetime.today();
d = now.strftime("%Y/%m/%d %H:%M:%S")
msg = "End"
toLog(d, msg+"\n", "A")
print (d + " " + msg+"\n")
continue
# Coincheck から Rate や Balance を取得する
if (GetCoincheck() == False) :
# タイムスタンプ
now = datetime.datetime.today();
d = now.strftime("%Y/%m/%d %H:%M:%S")
msg = "End"
toLog(d, msg+"\n", "A")
print (d + " " + msg+"\n")
continue
# ファイルに保存してあったデータをロードする
if (GetFile() == False) :
# タイムスタンプ
now = datetime.datetime.today();
d = now.strftime("%Y/%m/%d %H:%M:%S")
msg = "End"
toLog(d, msg+"\n", "A")
print (d + " " + msg+"\n")
continue
# 売買条件が成立しているか判断する
Calcurate()
# stop-trade というファイルが存在すれば実際の売買は行わない
if os.path.exists('stop-trade') :
# タイムスタンプ
now = datetime.datetime.today();
d = now.strftime("%Y/%m/%d %H:%M:%S")
msg = "stop-trade ファイルが存在するため PutCoincheck をキャンセルしました。"
toLog(d, msg, "A")
print (d + " " + msg+"\n")
else :
# 実際の売買
for i in range(10) :
F_Buy = False
F_Sell = False
F_Cancel = False
PutCoincheck()
if (F_Cancel == False) :
break
# キャンセルした場合は Rate,Balance を取得し直し売買条件が成立するか判断する
GetCoincheck()
Calcurate()
time.sleep(4)
Cc = CoinCheck(CC_API_KEY, CC_API_SECRET)
# 売買後の Balance を取得する(表示用)
GetCoincheck()
# データをファイルに保存する
PutFile()
# タイムスタンプ
now = datetime.datetime.today();
d = now.strftime("%Y/%m/%d %H:%M:%S")
msg = "End"
toLog(d, msg+"\n", "A")
print (d + " " + msg + "\n")
# 2分30秒のウエイト
time.sleep(150)
if __name__ == "__main__":
main()
この記事が気に入ったらサポートをしてみませんか?