Created
November 15, 2017 23:31
-
-
Save sousk/44089c32d9e188adec2c223e8c26f1a5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import krakenex | |
import fx | |
import time | |
import urllib.request | |
import urllib.parse | |
import json | |
from pprint import pprint | |
##Kraken パブリックapiのキー | |
apikey = | |
apisec = | |
##Kraken シークレットAPIのキーです | |
zako = | |
zako2 = | |
CANDIDATE = {"EUR":["XBT","REP","ETH","LTC","XLM","XRP","DASH","ETC","XMR","ZEC"],"JPY":["XBT","ETH","XRP"],"GBP":["XBT","ETH"],"CAD":["XBT","ETH","XRP"],"USD":["XBT","REP","ETH","LTC","XLM","XRP","DASH","ETC","XMR","ZEC"]} | |
#ALTS = ["DASH/XBT","ETC/XBT","ETH/XBT","GNO/XBT","ICN/XBT","LTC/XBT","MLN/XBT","REP/XBT","XDG/XBT","XLM/XBT","XMR/XBT","XRP/XBT","ZEC/XBT",] | |
k = krakenex.API(apikey, apisec) | |
k2 = krakenex.API(zako, zako2) | |
#####通貨コードの雑用的操作です###### | |
def initialX(d): | |
if len(d)<4: | |
return "X"+d | |
else: | |
return d | |
def lastZ(d): | |
if len(d)<4: | |
return "Z" | |
else: | |
return "" | |
###APIでオーダーを出す関数です | |
def order(pair,buy_or_sell,v,price): | |
v = str(v) | |
price = str(price) | |
if price=="MARKET": | |
res = k2.query_private("AddOrder",{"pair":pair,"ordertype":"market","type":buy_or_sell,"volume":v}) | |
else: | |
res = k2.query_private("AddOrder",{"pair":pair,"ordertype":"limit","type":buy_or_sell,"volume":v,"price":price}) | |
return res.get("result"),pair | |
###オーダーがまだあることを確認しています | |
def check_order_done(): | |
for i in range(5): | |
try: | |
orders = k2.query_private("OpenOrders") | |
return orders["result"]["open"] | |
except: | |
pass | |
###売り板・買い板のデータを取得します | |
def check_depth(pair): | |
for i in range(5): | |
try: | |
h = k2.query_public("Depth",{"pair":pair}) | |
return h["result"] | |
except: | |
pass | |
###オーダーキャンセルします | |
def cancel_order(txid): | |
k2.query_private("CancelOrder",{"txid":txid}) | |
def cancel_all(): | |
for key in check_order_done(): | |
cancel_order(key) | |
###今の資産状況を取得します | |
def check_balance(): | |
for i in range(5): | |
try: | |
orders = k2.query_private("Balance").get("result") | |
except: | |
orders = False | |
if orders: | |
return orders | |
def check_history(): | |
orders = k2.query_private("TradesHistory")["result"] | |
return orders | |
def check_asset(): | |
orders = k2.query_private("Ledgers",{"ofs":"1"})["result"] | |
return orders | |
def check_position(): | |
positions = k2.query_private("OpenPositions")["result"] | |
return positions | |
### v(フィアットのボリューム)と買い板データを入れるといくらコインをもらえるか返します | |
def sum_orders_market(v,lst): | |
sum_m = 0 | |
sum_p = 0 | |
for i in lst: | |
i0 = float(i[0])#price | |
i1 = float(i[1])#amount | |
p = i0*i1 | |
if v<sum_p+p: | |
res = sum_m + (v-sum_p)/i0 | |
print(res) | |
return res | |
else: | |
sum_m += i1 | |
sum_p += p | |
### vの通貨が一体いくらのフィアットになるか計算します | |
def sum_sell_market(v,lst): | |
sum_m = 0 | |
sum_p = 0 | |
for i in lst: | |
i0 = float(i[0])#price | |
i1 = float(i[1])#amount | |
p = i0*i1 | |
if v<sum_m+i1: | |
res = sum_p + (v-sum_m)*i0 | |
print(res) | |
return res | |
else: | |
sum_m += i1 | |
sum_p += p | |
### どの変換ルートが利益になるか判別します | |
###(元の法廷通貨、変換先の法廷通貨、いくら動かすか、最低何%儲かって欲しいか)が引数です | |
def chose(currency,currency0,DOLLAR,limitrate): | |
first = currency0[0] | |
common_coin = list(set(CANDIDATE[currency])&set(CANDIDATE[currency0])) | |
print(common_coin) | |
sell_list = [i+currency for i in common_coin] | |
buy_list=[i+currency0 for i in common_coin] | |
pairs = ",".join(sell_list+buy_list) | |
print("通信中") | |
ticks = k.query_public('Ticker',{'pair':pairs})['result'] | |
print("終了") | |
go_score = []#USD to EUR | |
###fxのレートを取得します | |
fx_rate = float(return_rate(currency+currency0)) | |
print(fx_rate) | |
candidate = CANDIDATE[currency] | |
for i in common_coin: | |
pair1 = initialX(i)+lastZ(i)+currency0 | |
pair2 = initialX(i)+lastZ(i)+currency | |
step1 = float(ticks[pair1]["a"][0]) | |
dic1 = ticks[pair1]["a"] | |
step1c = float(ticks[pair1]["c"][0]) | |
step1d = float(ticks[pair1]["b"][0]) | |
step1d = (step1*4+step1d*6)/10 | |
if step1d<step1c: | |
step1c = step1d | |
step2 = float(ticks[pair2]["b"][0]) | |
dic2 = ticks[pair2]["b"] | |
step2c = float(ticks[pair2]["c"][0]) | |
step2d = float(ticks[pair2]["a"][0]) | |
step2d = (step2*4+step2d*6)/10 | |
if step2d>step2c: | |
step2c = step2d | |
###ここの部分は重要です | |
###フィアットに売り抜けないといけないので売りは成り行きを想定します | |
go_score.append((i+":なりゆき なりゆき",step2/step1,step1,step2,pair1,pair2,2)) | |
go_score.append((i+":指値 なりゆき",step2/step1c,step1,step2,pair1,pair2,4)) | |
#スコアをソートします | |
go_score.sort(key=lambda x:-float(x[1])) | |
print("ランキング") | |
for i in go_score[:30]: | |
print(currency0+"→ "+i[0]+"→ "+currency+": 利益"+str((i[1]*fx_rate-1)*100)+"%"+" "+str(i[2])+" "+str(i[3])) | |
###ここからが本番です | |
###板の厚さを無視したシュミレーション結果であるgo_scoreを板の厚さ込でシュミレーションします | |
###Krakenは板がすごく薄いので300ドルか300ユーロの入力を想定します | |
all_dic = {} | |
for i in go_score[:5]: | |
if not all_dic.get(i[4]): | |
dic1 = check_depth(i[4])[i[4]]["asks"] | |
all_dic[i[4]] = dic1 | |
else: | |
dic1 = all_dic[i[4]] | |
if not all_dic.get(i[5]): | |
dic2 = check_depth(i[5])[i[5]]["bids"] | |
all_dic[i[5]] = dic2 | |
else: | |
dic2 = all_dic[i[5]] | |
if i[-1]==2: | |
first = sum_orders_market(DOLLAR,dic1) | |
second = sum_sell_market(first,dic2) | |
if not (first and second): | |
continue | |
rate = 100*(second*fx_rate-DOLLAR)/DOLLAR | |
print(currency0+"→ "+i[0]+"→ "+currency+": 利益"+str(rate)+"%"+" "+str(i[2])+" "+str(i[3])) | |
if rate>limitrate: | |
return {"pair":i[4],"buy_or_sell":"buy","v":DOLLAR/i[2],"price":"MARKET"},{"pair":i[5],"buy_or_sell":"sell","v":False,"price":"MARKET"} | |
elif i[-1]==3: | |
first = sum_orders_market(DOLLAR,dic1) | |
if not first: | |
continue | |
rate = 100*(first*i[3]*fx_rate-DOLLAR)/DOLLAR | |
print(currency0+"→ "+i[0]+"→ "+currency+": 利益"+str(rate)+"%"+" "+str(i[2])+" "+str(i[3])) | |
if rate>limitrate: | |
return {"pair":i[4],"buy_or_sell":"buy","v":DOLLAR/i[2],"price":"MARKET"},{"pair":i[5],"buy_or_sell":"sell","v":False,"price":i[3]} | |
elif i[-1]==4: | |
second = sum_sell_market(DOLLAR/i[2],dic2) | |
if not second: | |
continue | |
rate = 100*(second*fx_rate-DOLLAR)/DOLLAR | |
print(currency0+"→ "+i[0]+"→ "+currency+": 利益"+str(rate)+"%"+" "+str(i[2])+" "+str(i[3])) | |
if rate>limitrate: | |
return {"pair":i[4],"buy_or_sell":"buy","v":DOLLAR,"price":i[2]},{"pair":i[5],"buy_or_sell":"sell","v":False,"price":"MARKET"} | |
print("まだダメです") | |
return False,False | |
###シュミレーションを利用して、実際に取引を行うコードです | |
###法廷通貨→ 仮想通貨 → もうひとつの法廷通貨 の変換を行います | |
def commit_plan(cur0,cur1,rate,amount="All"): | |
timeout1=10;timeout2=100 | |
if amount=="All": | |
amount = float(check_balance()["Z"+cur0]) | |
print([cur0,cur1,rate,amount]) | |
print("====発射====") | |
timeout = 0 | |
quest1,quest2 = chose(cur1,cur0,amount,rate) | |
if quest1==False: | |
return False | |
while True: | |
o1 = order(**quest1) | |
if o1[0]: | |
o1id = o1[0].get("txid") | |
print(o1) | |
print("is ordered") | |
break | |
print(o1) | |
time.sleep(0.5) | |
flag = True | |
while flag: | |
if timeout>timeout1: | |
cancel_order(o1id) | |
print("キャンセルしました"+o1[1]) | |
return "DONE" | |
res= check_order_done() | |
if res !={}: | |
flag=True | |
time.sleep(1) | |
timeout +=1 | |
else: | |
flag=False | |
b = check_balance() | |
b = b[o1[1][:4]] | |
print("途中経過") | |
print(b) | |
quest2["v"]=b | |
timeout =0 | |
while True: | |
o2 = order(**quest2) | |
if o2[0]: | |
o2id = o2[0].get("txid") | |
break | |
time.sleep(0.5) | |
print(o2) | |
flag = True | |
while flag: | |
res= check_order_done() | |
if res !={}: | |
flag=True | |
time.sleep(1) | |
timeout += 1 | |
else: | |
flag=False | |
b = check_balance() | |
b = b[o2[1][-4:]] | |
print("結果") | |
print(b) | |
return "DONE" | |
###最高位の関数です。資産状況をみながらcommit_planを実行します | |
def operation(): | |
balance = check_balance() | |
eur = float(balance["ZEUR"]) | |
usd = float(balance["ZUSD"]) | |
result = False | |
if eur>usd: | |
if eur>270 : | |
result = commit_plan("EUR","USD",3,270) | |
elif usd>300: | |
result = commit_plan("USD","EUR",3,300) | |
elif usd>eur: | |
if usd>300: | |
result = commit_plan("USD","EUR",3,300) | |
elif eur>270: | |
result = commit_plan("EUR","USD",3,270) | |
return result | |
def return_rate(pair="EURUSD"): | |
url = "https://query.yahooapis.com/v1/public/yql" | |
params = { | |
"q": 'select * from yahoo.finance.xchange where pair in ("{0}")'.format(pair), | |
"format": "json", | |
"env": "store://datatables.org/alltableswithkeys" | |
} | |
url += "?" + urllib.parse.urlencode(params) | |
res = urllib.request.urlopen(url) | |
# 結果はJSON形式で受け取ることができます | |
result = json.loads(res.read().decode('utf-8')) | |
#pprint(result) | |
rate = result["query"]["results"]["rate"]["Rate"] | |
return rate | |
if __name__=="__main__": | |
while True: | |
res = False | |
try: | |
res = operation() | |
except Exception as exp: | |
print(exp) | |
if res == "DONE": | |
print("オペレーションが完了しました") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment