BitMEXのトレード損益をグラフにする
https://gyazo.com/bd59ba115fac03de72586263e57b5d13
環境
MacOSX
python3
pandas
ccxt
インストール
code:sh
pip install plotly
ソース
code:mexhistory.py
# -*- coding: utf-8 -*-
import argparse
import dateutil.parser
import ccxt
import pandas as pd
import plotly.offline as offline
import plotly.graph_objs as go
def store_datetime(str):
dt = dateutil.parser.parse(str)
return dt.strftime('%Y-%m-%dT%H:%M:%S')
parser = argparse.ArgumentParser(description="")
parser.add_argument("--symbol", type=str, default='BTC/USD')
parser.add_argument("--apiKey", type=str, default='')
parser.add_argument("--secret", type=str, default='')
parser.add_argument("--pine", action="store_true")
parser.add_argument("--since", type=store_datetime)
parser.add_argument("--plotly", action="store_true")
args = parser.parse_args()
exchange = ccxt.bitmex({
'apiKey': args.apiKey,
'secret': args.secret,
})
def fetch_trade_history(symbol=args.symbol, since=None, limit=None):
exchange.load_markets()
market = None
request = {}
if symbol is not None:
market = exchange.market(symbol)
if since is not None:
if limit is not None:
if 'filter' in request:
response = exchange.privateGetExecutionTradeHistory(request)
df = pd.DataFrame(response)
return df
if args.pine:
print(
'//@version=3\n'
'study("Bitmexトレード", overlay=true)\n'
'exec_time(transactTime) =>\n'
' result = false\n'
' delta = time - time1\n' ' if time < transactTime and transactTime < (time + delta)\n'
' result := true\n'
' result\n'
'pnl = 0\n'
'buy_price = close\n'
'buy_price := na\n'
'sell_price = close\n'
'sell_price := na\n'
)
else:
print('transactTime,symbol,execType,side,lastQty,lastPx,execCost,commission,execComm,ordType,orderQty,leavesQty,price,text,orderID,execCost_sum,execComm_sum,lastQty_sum,unrealizedPnl_sum')
count = 100
since = args.since
execCost_sum = 0
execComm_sum = 0
lastQty_sum = 0
unrealizedPnl_sum = 0
chartIndex = []
lastPx = []
execComm = []
unrealizedPnl = []
while True:
df = fetch_trade_history(since=since, limit=count)
for index, row in df.iterrows():
execComm_sum = execComm_sum + row.execComm
if row.execType == "Trade":
execCost_sum = execCost_sum + row.execCost
if row.side == "Buy":
lastQty_sum = lastQty_sum + row.lastQty
else:
lastQty_sum = lastQty_sum - row.lastQty
unrealizedPnl_sum = -(execCost_sum + int(lastQty_sum / row.lastPx * 100000000))
chartIndex.append(row.transactTime)
lastPx.append(row.lastPx)
execComm.append(execComm_sum)
unrealizedPnl.append(unrealizedPnl_sum)
if args.pine:
d = {
'transactTime': row.transactTime,
'side': row.side,
'lastQty': row.lastQty,
'price': row.price,
'buy_price': row.price if row.side == 'Buy' else 'na',
'sell_price': row.price if row.side == 'Sell' else 'na',
'pnl': unrealizedPnl_sum,
'timestamp': int(row.transactTime.timestamp())*1000,
}
print(
'// {transactTime} {side} {lastQty} {price}\n'
'if exec_time({timestamp})\n'
' pnl:={pnl}\n'
' buy_price:={buy_price}\n'
' sell_price:={sell_price}\n'.format(**d)
)
else:
print('{transactTime},{symbol},{execType},{side},{lastQty},{lastPx},{execCost},'
'{commission},{execComm},{ordType},{orderQty},{leavesQty},{price},"{text}",'
'{orderID},{execCost_sum},{execComm_sum},{lastQty_sum},{unrealizedPnl_sum}'.format(**row))
since = row.timestamp
if len(df.index) < count:
break
if args.pine:
print(
'plot(buy_price, color=green, linewidth=2)\n'
'plot(sell_price, color=red, linewidth=2)\n'
'//plot(pnl<0?-pnl:pnl, color=pnl>=0?green::orange, linewidth=4, style=area, transp=80)\n'
'plotshape(buy_price, style=shape.arrowup, location=location.belowbar, size=size.large)\n'
'plotshape(sell_price, style=shape.arrowdown, location=location.abovebar, size=size.large)\n'
)
if args.plotly:
price_line = go.Scatter(
x = chartIndex,
y = lastPx,
mode = 'lines',
name = 'rice'
)
pnl_area = go.Scatter(
x = chartIndex,
y = unrealizedPnl,
yaxis='y2',
fill='tozeroy',
mode= 'none',
name='Profit and Loss')
# 2軸グラフレイアウト作成
layout = go.Layout(
title='Price vs Volume',
yaxis=dict(
title='Price'
),
yaxis2=dict(
title='Profit and Loss',
overlaying='y',
side='right'
)
)
fig = go.Figure(data=data, layout=layout)
offline.plot(fig, filename='sample.html', auto_open=False)
使い方
code:sh
python mexhistory.py --apiKey xxxx --secret xxxx --since 2018/4/5 --plotly
コマンドを実行したディレクトリに sample.html が出力されるのでこれをウェブブラウザで開くとグラフが表示されれる。
ビットコインアドレス
3MtsP5ZKAuVA5pH2mDTFpHxHPG2JWC4Kop