以前紹介した「取得時収入円表示スクリプト」をupdateしました。
取引履歴をCSVファイルで出力する方法で取得したCSVファイルでは、Poolでブロック報酬が当たると、0.25 XCHのほかに1.75 XCH分も記録されているようです。この分を削除するようにしました。そうしないと累積金額が大きくなりすぎてしまうので・・・
あと細かいですが、CSVファイルはShift-JISで保存するようにしました。確定申告の時などExcelなどWindowsツール使うと思うので、Shift-JISの方が便利でしょう。
スクリプトはこちらです。
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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# import import numpy as np import pandas as pd import datetime as dt from urllib import request import urllib.error import urllib.request from bs4 import BeautifulSoup # 必要なら $ conda install beautifulsoup4 # coingecko の XCH price table を表示。start, end の日時を指定できる start_date='2020-05-04' end_date ='2021-11-14' url = f'https://www.coingecko.com/en/coins/chia/historical_data/usd?end_date={end_date}&start_date={start_date}#panel' # ブラウザの真似しないと HTTP Error 403: Forbidden にされる。 headers = { "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0" } # 追加 request = urllib.request.Request(url, headers=headers) # headers を追加 try: with urllib.request.urlopen(request) as web_file: urldata = web_file.read() except urllib.error.URLError as e: print(e) # urldata の欲しいところを抽出 soup = BeautifulSoup(urldata, 'html.parser') body = soup.select('.table') # テキスト抽出して、'$'を削除して、リスト化 l = body[0].get_text().replace('$', '').split() # column名を削除 del l[:6] # numpy 使って、2次元化 n2 = np.array(l).reshape(-1,5) # pandas DataFrameに変換 xdf = pd.DataFrame(n2, columns=['Date','MarketCap','Volume','Open','Close']) # 【暫定】MarketCapで0.000000000000 は 0 に置き換える xdf.loc[xdf['MarketCap']=='0.000000000000', 'MarketCap'] = '0' # CSV fileとして保存 xdf.to_csv('xch-price.csv', index=False) # 一度 csv で保存して、thousands=',' をつけて read_csv すると、いい感じに文字列数値変換してくれる。便利! xdf = pd.read_csv('xch-price.csv', thousands=',') # 【暫定】最新日CloseがNaN(オリジナルでは'N/A')の場合にはOpenの値を入れておく xdf.loc[np.isnan(xdf['Close']), 'Close'] = xdf['Open'] # いらない列を削除 xdf.drop(['MarketCap', 'Volume', 'Open'], axis=1, inplace=True) # 辞書を作る。mapで一度に適用できて便利 keys = xdf['Date'] values = xdf['Close'] date2xch = dict(zip(keys, values)) mizuho_url = 'https://www.mizuhobank.co.jp/market/quote.csv' # ブラウザの真似しないと HTTP Error 403: Forbidden にされる。 headers = { "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0" } # 追加 request = urllib.request.Request(mizuho_url, headers=headers) # headers を追加 try: with urllib.request.urlopen(request) as web_file: urldata = web_file.read() except urllib.error.URLError as e: print(e) # 一度CSVファイルとして書き込み with open('mizuho_hist.csv', 'wb') as f: f.write(urldata) # シフトJISで読み込み直し。thousands=','はたぶんいらない mdf = pd.read_csv('mizuho_hist.csv', thousands=',', encoding="SHIFT-JIS") # 列名を整数で振り直し sh = mdf.shape mdf.columns = range(sh[1]) # 1列目(日付)、2列目(米ドル)のみ抽出 mdf = mdf.loc[:,[0,1]] # 最初の2行を削除 mdf.drop([0, 1], axis=0, inplace=True) # 列名ふりなおし mdf.columns = ['Date', 'JPY/USD'] # 一度 datetime 型にして mdf['Date'] = pd.to_datetime(mdf['Date']) # 日付datetime型をつかいやすい文字列に mdf['Date'] = mdf['Date'].dt.strftime('%Y-%m-%d') # JPY/USD の数値が文字列なのでfloatに変換 mdf['JPY/USD'] = mdf['JPY/USD'].astype(float) #################################################### # 日本円 Wallet 表作成 #################################################### # 16進数文字列を10進数に変換する関数, map関数でDataFrameに適用できる def func(value): return int(value, 16) # CSV ファイルを読み込み df = pd.read_csv('wallet.csv', names=['入出', '宛先', '日時(str)', '金額(16進)']) # 日付文字列を datetime型に変換。pandasのpd.to_datetimeが使える df['日時']=pd.to_datetime(df['日時(str)']) df['月日(str)'] = df['日時'].dt.strftime('%Y-%m-%d') # 16進数文字列を整数にして、入出が0のときは正の数(入金)、1のときは負の数(出金)とする df['金額(mojo)']=df['金額(16進)'].map(func) * ((-1)**df['入出']) # 使っている宛先名と最初数文字のaddress16進数文字列(Pool名やPlot NFT名)を辞書型で登録してください add2name = { 'SpacePool' : '238f', 'HDDMining' : '938e', 'ブロック報酬' : '3cab', 'サブアカ' : '1baa', 'HDDM-dummy' : '0e48', 'Space-dummy' : 'c8e0'} # 戦闘数文字で引っかけているので、残念ながらmapは使えない for n in add2name.keys(): df.loc[df['宛先'].str.startswith(add2name[n]), '取引相手'] = n # 特殊条件 # '2021-10-21 12:00:00' 以前の SpacePoolはPoolChia df.loc[(df['日時']< dt.datetime.strptime('2021-10-21 12:00:00', '%Y-%m-%d %H:%M:%S'))&(df['取引相手']=='SpacePool'), '取引相手']= 'PoolChia' # dummy 1.75 XCHを削除 df = df[~df['取引相手'].str.contains('dummy', na=False)] # 累積してからwalj作成 df['累積金額(mojo)']=df['金額(mojo)'].cumsum() # 余計な列を削ってWallet表ののひな形とする walj = df.drop(['入出', '宛先', '日時(str)', '金額(16進)'], axis=1) # ★★★ XCH価格を埋め込み walj['XCH価格'] = walj['月日(str)'].map(date2xch) ##################### # みずほデータには日本の休日など抜けている日がある。 # wallet_dfから足りない日付を加えて、為替値は前後値から補間 ##################### # みずほ銀行の古すぎるデータは除外 ndf = mdf[mdf['Date'] >= '2021-04-30'] # Dateからそれぞれの就業をつくる n_set = set(ndf['Date']) w_set = set(walj['月日(str)']) # 集合の引き算で xdf に存在しない日にちを見つける sub = w_set - n_set # ndf のindexをDateにして、存在しないDateで行を作れるようにする ndf = ndf.set_index('Date') # 存在しないDateで新しい行を作る for d in sub: ndf.loc[d] = np.nan # index でソート ndf = ndf.sort_index() # NaN値のあるところを前日の値で補間 ndf = ndf.fillna(method='ffill') ndf = ndf.reset_index() # 変換辞書をつくる。mapで使う。 keys = ndf['Date'] values = ndf['JPY/USD'] date2jpy = dict(zip(keys, values)) # ★★★ 円/ドル相場埋め込み walj['JPY/USD'] = walj['月日(str)'].map(date2jpy) icchou = 1000000000000 # 一兆 1兆mojo = 1 XCH # 日本円取得価格計算 walj['収入(円)'] = walj['金額(mojo)'] * walj['XCH価格'] * walj['JPY/USD'] / icchou walj['収入(円)str'] = walj['収入(円)'].apply(lambda x: '{:.2f}'.format(x)) walj['税法上収入(円)'] = walj['収入(円)'].cumsum() walj['所持金(円)'] = walj['累積金額(mojo)'] * walj['XCH価格'] * walj['JPY/USD'] / icchou walj.to_csv('wal-jpy.csv', index=False, encoding='shift-jis') |
このようなバッチで使ってください。
1 2 3 4 5 6 7 |
c:\sqlite3\sqlite3 -readonly C:\Users\<ユーザー名>\.chia\mainnet\wallet\db\blockchain_wallet_v1_mainnet_XXXXXXXXXX.sqlite ".mode csv" ".output wallet.csv" "SELECT sent, to_puzzle_hash , datetime(created_at_time, 'unixepoch', 'localtime'), hex(amount) FROM transaction_record;" rem Anaconda Virtual Environment activate call C:\Users\<ユーザー名>\anaconda3\Scripts\activate.bat call activate p38 python C:\python\to-jpy.py |