GASを使ってBTCBOXの取引履歴をCryptactのフォーマットに整形する【仮想通貨損益計算】
Posted: 2018-03-06

確定申告の期限が近づいている。暗号通貨ホルダーの皆はもう申告を済ませた人がほとんどだろうが、ギリギリになって慌てている人も多いのではないだろうか。何を隠そう俺もその一人だ。
今回の申告のための損益計算には Cryptact というツールを使用するつもりでいる。
計算自体はどのツールでやっても同じになるはずなのだが、Cryptact は対応している取引所の取引履歴フォーマットが豊富なことが選んだ理由だ。
しかし残念ながら、昔使っていた BTCBOX の取引履歴フォーマットには対応していなかったので、Google Apps Script(GAS)を使ってカスタムファイルのフォーマットの形に整形することにした。
https://tax.cryptact.com/help/custom.html
Google スプレッドシート上に貼り付けて編集する。ちなみに BTCBOX のファイルは BTC/JPY の取引のみだった。ソースは末尾に記載する。
参考にしたもの
Google Apps Script を実例交えて基礎からざっくり学ぶ Advent Calendar 2017
流れ
- BTCBOX のデータを二次元配列で読み込む
- データの中身を"整形したり"、"付け足したり"、"入れ替えたり"、して新しい二次元配列を作る
- データ書き出し
以上
BTCBOX のデータを二次元配列で読み込む
var inputsheet = SpreadsheetApp.getActive().getSheetByName('元データ');
var values = inputsheet.getRange("A1:I500").getValues();
今回は読み込み範囲をとりあえず手動で指定してしまった。
データの中身を"整形したり"、"付け足したり"、"入れ替えたり"、して新しい二次元配列を作る
項目名は BTCBOX のフォーマットと全く違うので新しく付ける必要がある。
//項目名を先頭行に付ける adjusted_data[0] = ['Timestamp','Action','Source','Base','Volume','Price','Counter','Fee','FeeCcy'];
元のフォーマットは日付が分割されている(なぜ?)ので'YYYY/MM/DD HH:mm:ss'になるように結合する。シート上のデータの表示形式を"書式なしテキスト"にしておく。
function adjustdate(input_data,output_data) {
for(var i = 0; i<input_data.length -1; i++){ output_data[i+1] = []; //半角スペースを挟む output_data[i+1][0] = input_data[i+1][0] + ' ' + input_data[i+1][1]; } return output_data; }
あとは必要な部分は必要な項目を列に配置して、列の入れ換えをすれば完了。特に変なことはしていない(はず)。
データ書き出し
function outputdata(outputsheet,data){ outputsheet.getRange(1,1,data.length,data[1].length).setValues(data); }
配列の長さで範囲を決めて書き出す。
ソース
以下ソース。汚いけど晒す。
function myFunction() { //変換元データのシートを読み込む var inputsheet = SpreadsheetApp.getActive().getSheetByName('元データ'); //変換後の結果データを出力するシートを読み込む var outputsheet = SpreadsheetApp.getActive().getSheetByName('結果データ');
//データを二次元配列にインプットする var trade_data = inputdata(inputsheet);
var adjusted_data = adjustdata(trade_data);
//データを出力する outputdata(outputsheet,adjusted_data); }
function inputdata(inputsheet) { /** 「元データ」からデータを読み込む 読み込み範囲は確認して直接指定 **/ var values = inputsheet.getRange("A1:I578").getValues(); //読み込んだ二次元配列を返す return values; }
//データを整形する function adjustdata(data) { //整形後データを入れる二次元配列を定義する var adjusted_data = [[]]; //項目名を先頭行に付ける adjusted_data[0] = ['Timestamp','Action','Source','Base','Volume','Price','Counter','Fee','FeeCcy'];
//日付を合わせて 1 行目に配置 adjusted_data = adjustdate(data,adjusted_data);
////任意の単語を列に配置 //Source var source_name = 'BTCBOX'; var source_column = 2; adjusted_data = inputword(source_name,source_column,data,adjusted_data); //Base var base_name = "BTC"; var base_column = 3; adjusted_data = inputword(base_name,base_column,data,adjusted_data); //Counter var counter_name = "JPY"; var counter_column = 6; adjusted_data = inputword(counter_name,counter_column,data,adjusted_data);
///元データを列の順番を入れ替えて結果データに入れる。 ///出力列、入力列、元データ、結果データを指定して結果データを返す //Action adjusted_data = sort(2,1,data,adjusted_data); //Volume adjusted_data = sort(4,4,data,adjusted_data); //Price adjusted_data = sort(3,5,data,adjusted_data); //Fee adjusted_data = sort(6,7,data,adjusted_data); //FeeCcy adjusted_data = sort(7,8,data,adjusted_data);
return adjusted_data; }
function sort(input_column_num,output_column_num,input_data,output_data) { //input_data の任意の列要素を output_data の任意の列要素に入れる。 //1 行目が項目欄のため入力開始行を 2 行目からとし、それに伴い入力回数を減らした。 for(var i = 0; i<input_data.length-1; i++){ output_data[i+1][output_column_num] = input_data[i+1][input_column_num]; } return output_data; }
//任意の単語を指定の列に入力する function inputword(word,column_num,input_data,output_data){ for(var i = 0; i<input_data.length-1; i++){ output_data[i+1][column_num] = word; } return output_data; }
//二次元配列データをシートに出力する function outputdata(outputsheet,data){ outputsheet.getRange(1,1,data.length,data[1].length).setValues(data); Logger.log(data); }
/** BTCBOX と cryptact では日付の形式が異なっているので整形を行う。 日付の文字列を結合する。 変換前の書式'YYYY/MM/DD' 'HH:mm:ss' 変換後の書式'YYYY/MM/DD HH:mm:ss' データ例'2016/12/23 12:23:34' あらかじめ元データの表示形式を「書式なしテキスト」に変更しておく。 **/ function adjustdate(input_data,output_data) {
//1 行目が項目欄のため入力開始行を 2 行目からとし、それに伴い入力回数を減らした。 for(var i = 0; i<input_data.length -1; i++){ output_data[i+1] = []; //半角スペースを挟む output_data[i+1][0] = input_data[i+1][0] + ' ' + input_data[i+1][1]; } return output_data; }