生活/クレジットカード/為替手数料
の編集
https://over.6pb.info/wiki/?&9f72236b49
[
トップ
] [
編集
|
差分
|
履歴
|
添付
|
リロード
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
]
-- 雛形とするページ --
(no template pages)
#contents The official figure of credit card transaction fee for foreign currency transactions (Foreign Transaction Fees) is mostly 1.63%, but the actual figure is somewhat different. Especially, "I feel" the difference between VISA and Master is unexpectedly big. To produce statistically meaningful numbers instead of "I feel" -- to a very limited extent with personal data (The only one who can do that with many sorts of analysis axis is Money Forward, Inc. and so on.) -- I've get them in order as much as we can./カードを外貨建てで使った場合の手数料(海外決済事務取扱手数料/Foreign transaction fees)は公式では1.63%の数字が多いが、実際の数字はなぜか違う。特にVISAとMasterの差が意外と大きい「感触がある」。「感触がある」ではなく、統計的に意味のある数字を出すには――それが可能な切り口は――、個人の手持ちデータではかなり限られるが(縦横無尽の切り口でそれができるのはマネーフォワードなど限られた位置にある者だけ)、できる範囲で整理して見た。 *最新 [#p3cec8e0] -2019年7月1日(月)以降 [[「外貨でのショッピングご利用に伴う事務処理手数料」改定および海外旅行関連サービス拡充のお知らせ|クレジットカードの三井住友VISAカード:https://www.smbc-card.com/mem/cardinfo/cardinfo4010221.jsp]] -「最終画面では、日本円で支払うか米ドル(米国の場合)で支払うかを選べる(図11)。日本円を選んだ場合は表示されている額が適用される。米ドルを選ぶと、カード会社の為替レートが適用される。ただ、どちらも大差があるわけではない。」岡本ゆかり 日経パソコン 2021年4月26日号//確かめたの? *VISA v. Master [#k17faf3d] &htmlinsert(:HTML/クレカ為替手数料集計); -How much added to the TTM / TTMにどれだけ上乗せされているか。 -The value below the table shows the difference when you use 1 million JPY. / 表下は、100万円分使ったときの差額。 -Confidence coefficient/信頼係数 95%。 #hr --換算日が分かるもの(三井住友カード、JCBカード、セゾンカード)と換算日を合理的に推測できるものだけを集計。利用日を単純に換算日と仮定したものは集計に一切含めなかった。換算日の推測は,VISA/Master等のレートに各カード所定の公式手数料を乗せたレートと,カード明細記載のレートとの乖離が0または十分小さい日を換算日と推測した。十分小さい日がなく換算日を合理的に特定できなければ集計から除外。上記観測個数は,実際に最終の計算に使った取引のみの件数。除外取引を含まない。 --TTMは原則として三井住友カードなら三井住友銀行,DCカードなら三菱東京UFJ銀行を使った。ただし,三井住友銀行は台湾のTTMを公開していないなどの場合は適宜,日本の他行を使った。VISA/Master等のレートはそれ自体がTTMより悪いので,基準はあくまでもTTMとした。 --DCカードのMasterは持っているがVISAは持っていない。DCカードは手数料が上がってからは海外のショッピングで使うのをほぼ止めた。(キャッシングにはDCカードを専ら使っている。)Cf. [[外貨でのショッピングご利用代金を円貨へ換算するための事務処理手数料改定のお知らせ(Visa・Mastercardをお持ちのお客さまへ)|クレジットカードなら三菱UFJニコス:http://www.cr.mufg.jp/member/new/20161101_01.html]] ---もっとも、最近のデータを見ていて気付いたのだが、DCカードは公式の手数料率より実際の料率はかなり低いようだ。しかし、為替リスクが大きい傾向もある(実際の換算日(推測)が利用日からかなり離れている)ので痛し痒しだ。一概に有利なカードとは言えないようだ。 --実際は発行会社その他の要因も影響しているようだが,分析するにはサンプルの多様性が全然足りない。 --この表は原本からリアルタイム更新なのでたまに実験中の異常値が表示されることもある。 -三井住友カード、JCBカード、セゾンカードは換算日(三井住友カードが何日のレートを使ったか)が明細に表示されるのでデータを分析する上で重宝している。換算日が営業日でない場合,実際に適用されているのは翌営業日のレートみたいだ。(私個人のデータしかないのでサンプルサイズが圧倒的に不足するのだが。)MasterやVISAのウェブでは営業日以外の換算レートも見られるけど,そのレートはTTMより上乗せがあるので,カードの実質手数料を比較する上でよい基準とは言えない。 -換算日が書いてないカードでも推測は立つ。VISAまたはMasterのレートから実質手数料を計算して1.67%(あるいは各カードによる公式値)に一番近い日が換算日だろう。 -各社公式情報 --[[海外でのご利用範囲|セゾンカードご利用ガイド|クレジットカードは永久不滅ポイントのセゾンカード:http://www.saisoncard.co.jp/guide/gu009.html]] --[[換算レートや海外事務手数料について教えてください。 | 楽天カード:よくあるご質問:https://support.rakuten-card.jp/faq/show/15344?category_id=14&site_domain=guest]] --[[ご利用明細のご説明|クレジットカードの三井住友VISAカード:https://www.smbc-card.com/mem/oshiharai/pop/wm_setsumei.jsp]] --[[外貨でのショッピングご利用代金を円貨へ換算するための事務処理手数料改定のお知らせ(Visa・Mastercardをお持ちのお客さまへ)|クレジットカードなら三菱UFJニコス:http://www.cr.mufg.jp/member/new/20161101_01.html]] *同日同店で競争 [#p8f4c262] There is another way to compare. I tried to use multiple cards at the same time at the same store to evaluate each other. I charged my gift cards on Amazon USA. This makes it easy to increase the number of observations./もう一つ、比較方法がある。同じ時刻に同じ店で複数のカードを使って相対評価する方式を試した。米国amazonでギフトカードをチャージして試している。これなら観測個数を増やすのが簡単だ。 &htmlinsert(:HTML/クレカ為替手数料集計2); Right: Comparison with TTM (In other words, absolute evaluation. Conversion date basis). Left: A relative evaluation with ANA Master. Compared with "Exchange Rate" on each card's invoice. (This is always there.)/右はTTMとの比較(いわば絶対評価。換算日基準)。左はANA Masterとの相対評価。各カードの請求書記載の「換算レート」(これは必ず載っている)を比較している。 -見ての通り、JAL DC Masterの誤差が非常に大きく、統計的に意味がない。(その結果、JAL DC Masterを加えて「Master, VISA, JCB」という比較をすると統計的に意味がなくなってしまう。)JAL DC Masterの誤差が大きいのは、換算日(これは非公開)が利用日から(大きめに)離れているか、(そもそも)一定しないか、その両方か、だと推測する。ANA Masterとブランドは同じであるから、換算日が同じであればレートも同じになるはずだが、この通り全然同じにならない。 とりあえず、ANA MasterとANA VISA Suicaの比較では、VISAの方が手数料が高いと言える。どちらも三井住友カードで、換算日が明記されているので、TTM比で比べても無理がないカードだ。JCBの数字は誤差がまだ大きめであり、何とも言えない。 -TTMと比べる方式には課題がある。いつのTTMと比べるかだ。「換算日」は一つの基準になるが「換算日」が非公開のカードの方が多いだろう。また換算日のTTMが休業日で取得できないことも少なくない。そもそも、比較する日が利用日から離れれば離れるほど、為替変動のリスクが大きくなり、ブランドやカード会社の手数料なのか、それとも為替変動による偶然なのか、区別が難しくなりそうだ。では利用日のTTMで比べたらどうか。それなら為替変動リスクを排除できそうだ。もちろん、利用日のTTMが手に入らないこともあるし、どの銀行のTTMを使うか、その他の課題はある。しかしそれは決めの問題であり致命的ではない。さて、実際に計算してみると、「そうだ」の通りには行かないようだ。 -3つの方法には以下の差があるようだ。 |換算日のTTMで比較する(絶対評価)|カード発行会社の上乗せ分を見る。| |利用日のTTMで比較する(絶対評価)|カード発行会社とブランドの上乗せ分を見る。しかし誤差が大きく(為替変動や料率の変動や、その他未知の要因など全ての変動が一緒くたになっているためだろう)、カード毎の差も小さいため、解釈が難しい。| |相対評価|為替変動リスクを含む消費者の負担を見る。誤差は為替変動リスクを見るのに適する。| -相対比較の誤差の大小は、主に為替変動リスクを示している。利用日と換算日(公開非公開問わず)との間の日数が主に左右しているはずだ。 --しかしその他に、換算レートが為替変動のトラッキング以外の要因に左右されている要素もあるだろう。根拠は、TTM比の誤差のANA PASMO JCB(換算日が明記されているカード)の値が特に小さいことだ。JCBの自社発行カードであり、VISAやMasterブランドのような中抜きする人が、他にいない(JCB単独のルールで換算レート=上乗せ率が決まっている)ことを示しているという推測が立つ。 -TTM比の誤差が小さいことは、カード会社が上乗せする率のルールに、消費者にとって未知の要因がないことを意味する。特に換算日を明記しているカードに妥当する。この点で、ANA PASMO JCB(換算日を明記)が特に小さいのは、JCBの自社発行カードであり、VISAやMasterブランドのような中抜きする人が、他にいないことを示しているのかもしれない。 -ちなみに、実験開始当初は間隔を空けずに連続的に複数のカードを使ったが、8順目でカードブランド(Master)から承認拒否された。拒否したのはamazonや日本のカード会社ではない。カード会社に自分から電話して照会したら、カード会社側にはデータが来ておらず、従って拒否もしていないし、何も情報がない、とのことだった。Masterのカード(発行会社は違う)だけ拒否されたので、Master側(Master段階というべきか)の拒否判定だと推測できる。Masterが拒否するとカード発行会社にも情報が(少なくとも利用日前後の時点では)行かないようだ。(一定期間でまとめて報告されることはあるかも。) --やり過ぎるとamazonからbanされるかも。[[アマゾンがアカウントを閉鎖する客とは - WSJ:http://jp.wsj.com/articles/SB11252457003671273998304584241121630753840]] -JAL DC Masterの分散を人為的に小さくすることもできそうな感じ。利用日と換算日(早ければ翌日)が、日本と米国いずれの休日にもかからないように利用すればよい。しかし、実際の買い物行動とは離れてしまう。ここではそういう操作はしていない。 *自動化 [#k070fe2d] **カード明細取得自動化 [#v51103ac] 自動化しないと誤記する。また、自動化し、巡回精度を保たないと統計精度を保証できない。 速報はCSVでダウンロードできないカードが意外とある。そういうのは[[勝手にボタンを付ける>情報管理#table2csv]]。Amexは単純なスクレイプでは取得できない(ページがJavaScriptで動的に作られる)ので、[[headless Chrome + Puppeteer (Node.js)>NET/www/webプログラミング#puppeteer]]で取得している。 ***Amex自動化 [#amex] #pre{{ const puppeteer = require('puppeteer'); const fs = require('fs'); (async() => { const browser = await puppeteer.launch({ //headless: false, args: [ '--no-sandbox', ] }); const page = await browser.newPage(); await page.setViewport({width: 1024, height: 768}); await page.goto('https://global.americanexpress.com/myca/logon/japa/action/LogonHandler?request_type=LogonHandler&Face=ja_JP&inav=jp_utility_login', { waitUntil: 'networkidle2'}); await page.waitForSelector('input#lilo_userName', {waitUntil: 'networkidle2', timeout: 10000}); await page.focus("input#lilo_userName"); await page.type("input#lilo_userName", 'your ID'); await page.focus("input#lilo_password"); await page.type("input#lilo_password", 'your passwd'); await page.click('#lilo_formSubmit'); await page.waitForNavigation({waitUntil: 'load'}); await page.waitForSelector('#balance-summary-table', {waitUntil: 'networkidle2', timeout: 2500}); // カードによって違うので要修正 await page.click('#balance-summary-table tr.recent-debits > td.description > a'); await page.waitForNavigation({waitUntil: 'load'}); await page.waitForSelector('#transaction-table', {waitUntil: 'networkidle2', timeout: 7000}); //tr要素のidを取得。transaction id let tid = await page.$$eval('#transaction-table tr[id]', list => { return list.map(date => date.id); }); let lines = []; // transaction id毎に // 各決済のtrは2段からなる。 // クリックによる展開前と展開後の詳細 // idが違う。 for (let i in tid) { await page.click("#transaction-table tr#" + tid[i] + " td.date"); await page.waitForSelector("#transaction-table tr#" + tid[i] + " + tr p.amount.ng-binding", {waitUntil: 'networkidle2', timeout: 7000}); // 詳細欄のtransaction id取得 // 例: #etd-details-content-AT181580... let dom = '#transaction-table tr#' + tid[i] + ' + tr[id]'; let tidd = await page.$eval(dom, e => e.id); // dateと請求額は1段目のtr dom = 'tr#' + tid[i] + ' td.date span.ng-binding'; let date = await page.$eval(dom, e => e.innerText); //#trans-... > td.date > div > span.ng-binding let shop = await page.$eval("tr#" + tidd + " p.header.ng-binding", e => e.innerText); //#etd-details-content-AT1815... > div > div.etdContent.ng-scope > div.etdBlock.ng-scope > p.header.ng-binding let local = await page.$eval("tr#" + tidd + " p.amount > span:nth-child(1)", e => e.innerText); //#etd-details-content-AT1815... > div > div.etdDetails.ng-scope > div > div:nth-child(2) > p.amount > span:nth-child(1) let curr = await page.$eval("tr#" + tidd + " p.amount > span:nth-child(2)", e => e.innerText); //#etd-details-content-AT181... > div > div.etdDetails.ng-scope > div > div:nth-child(2) > p.amount > span:nth-child(2) dom = 'tr#' + tid[i] + ' td.amount > div > span'; let jpy = await page.$eval(dom, e => e.innerText); //#trans-AT18158... > td.amount > div > span let rate_date = await page.$eval("tr#" + tidd + " div.etdContent.ng-scope > div:nth-child(2) > div > p.ng-binding.ng-scope", e => e.innerText); //#etd-details-content-AT18156... > div > div.etdContent.ng-scope > div:nth-child(2) > div > p.ng-binding.ng-scope let rate = await page.$eval("tr#" + tidd + " p.amount.ng-binding", e => e.innerText); // #etd-details-content-AT181... > div > div.etdDetails.ng-scope > div > div:nth-child(3) > p.amount.ng-binding let line = [date,shop,local,curr,jpy,rate_date,rate].join(','); console.log(line); lines.push(line); } fs.writeFile('amex.csv', lines.join("\n"),(err) => { if (err) throw err; }); //ログアウト await page.click('#jp_utility_login'); await browser.close(); })(); }} **TTM [#r7e6fc06] TTMの入手先: -[[外国為替情報 : 三井住友銀行:http://www.smbc.co.jp/market/backnumber/fixing/]] -[[三菱UFJリサーチ&コンサルティング | 外国為替相場 | 1990年以降の為替相場:http://www.murc-kawasesouba.jp/fx/past_3month.php]] -TTM(仲値)というわけではないが、[[Pacific Exchange Rate Service - Database Retrieval System:http://fx.sauder.ubc.ca/data.html]] 自動化しないと、誤記する。 -三井住友銀行(なお、私は同行からbanされた。403 Forbidden。やり過ぎに注意。) #pre{{ #!/usr/bin/perl use utf8; use strict; use warnings; my $url = 'http://www.smbc.co.jp/market/backnumber/fixing/'; # 今月 my $thisMonth = '//*[@id="tabbox1"]/div//li/a/@href'; # 前月 my $lastMonth = '//*[@id="tabbox2"]/div//li/a/@href'; use URI; my $u = URI->new($url); use HTML::TreeBuilder::XPath; my $tree = HTML::TreeBuilder->new_from_url($url); my @href = $tree->findvalues($lastMonth); push(@href, $tree->findvalues($thisMonth)); use LWP::UserAgent (); my $ua = LWP::UserAgent->new; for my $pdfpath (@href) { my $uri = sprintf qq(http://%s%s),$u->host,$pdfpath; my $response = $ua->get($uri); if ($response->is_success) { my $pdfbody = $response->decoded_content; my $tmpfile = "/tmp/msbcrate.$$"; open(my $fh, '>', "$tmpfile") or die "$tmpfile:$!"; print $fh $pdfbody; close $fh; open($fh, "pdftotext -layout $tmpfile - |") or die "pipe:$!"; my @content = <$fh>; close $fh; unlink $tmpfile; if (my ($date, %rate) = &msbcrate_pdf(@content)) { my $ttm = ($rate{'usd'}->{'tts'} + $rate{'usd'}->{'ttb'})/2; printf qq(%s\t%.2f\n),$date,$ttm; #my $insert = #"INSERT IGNORE INTO usd VALUES ('$date','SM','$ttm')"; #$db->do($insert) or die $db->errstr; } else { print STDERR "failed in $pdfpath\n"; } } } #$db->disconnect; exit; sub msbcrate_pdf { my @lines = @_; my $date = ''; my %rate = (); my %month = qw( Jan 1 Feb 2 Mar 3 Apr 4 May 5 Jun 6 Jul 7 Aug 8 Sept 9 Sep 9 Oct 10 Nov 11 Dec 12 ); for (@lines) { # Date: May.25, 2018 if (my @temp = (/Date:\s+([a-zA-Z]+)\D+(\d+)\D+(\d+)/)) { my $month = $month{$temp[0]} // 'fail'; $date = "$temp[2]/$month/$temp[1]"; next; } if (/U\.S\.A\.\s+USD\s+1\s+([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)/) { $rate{'usd'}->{'tts'} = $1; $rate{'usd'}->{'ttb'} = $3; next; } } if ($date eq '' || !defined $rate{'usd'}->{'tts'}) { return; } else { return $date, %rate; } } }} -三菱UFJリサーチ&コンサルティング #pre{{ #!/usr/bin/perl use utf8; use strict; use warnings; use Time::Piece; use Time::Seconds; my $t = localtime; my $days = 20; # 過去○日分取得する。 use LWP::UserAgent (); use HTML::TreeBuilder::XPath; my $baseurl = 'http://www.murc-kawasesouba.jp/fx/past/index.php'; # http://www.murc-kawasesouba.jp/fx/past/index.php?id=180419 for (1..$days) { my $date = sprintf qq(%02d%02d%02d),$t->yy,$t->mon,$t->mday; my $url = $baseurl . '?id=' . $date; my $ua = LWP::UserAgent->new; # 営業日以外は「本日の為替相場」に転送される。 # http://www.murc-kawasesouba.jp/fx/index.php $ua->max_redirect(0); my $response = $ua->get($url); my $root = HTML::TreeBuilder->new(); if ($response->is_success) { $root->parse_content($response->decoded_content); my $tts = $root->findvalue('//*[@id="main"]/table[1]/tr[2]/td[4]'); my $ttb = $root->findvalue('//*[@id="main"]/table[1]/tr[2]/td[5]'); my $ttm = ($tts+$ttb)/2; my $date = $t->ymd("/"); printf qq(%s\t%.2f\n),$date,$ttm; #my $insert = #"INSERT IGNORE INTO usd VALUES ('$date','MU','$ttm')"; #$db->do($insert) or die $db->errstr; } $t -= ONE_DAY; } #$db->disconnect; exit; }} *Amexの意外な競争力 [#a7ef8fc5] Amexの決済インフラは他社に比べ圧倒的に強いかもしれない。Amexの自社発行カード(日本法人)は、試した範囲では、他のイシュアー(発行会社。三井住友カードや楽天カード、DCカードなど)やブランド(VISA、Master、JCBなど)に比べ、カードを利用してから明細に出るまでの時間が、圧倒的に速い。(今回、明細の確認はロボットで自動化しているので、傾向を統計的に把握できる。)クレジットカードの仕組みはもう何十年も前に作られたもので、本来リアルタイム決済を想定したものでは全くない。時代の趨勢に答えてリアルタイムで処理するには、多大なシステム投資が必要だ。しかも、自社だけの投資で終わらず、販売店との連携も必要になる。また、クロスボーダーの決済はどんどん増えるだろう。Amexでは、日本発行カードでも日本の営業時間に制約されないことも見て取れる。 Amexの他では、三井住友カード(VISA、Master)が結構健闘していた。それでも、日曜はデータが動かないことが見て取れるなど、システム設計の古さを推知できる。日本時間の午前中か否かで処理のバッチが切り替わる(Master)ことも推知できる。VISAかMasterかでバッチの挙動も異なる。自社ブランドでないので自分でコントロール出来ないのだろう。今回のカードでは、JCBは自社ブランド・自社発行のカードだが、速度に特に目立った特徴はない。三井住友トラストクラブ株式会社(三井住友信託銀行の100%子会社。旧、シティカードジャパン株式会社)のDinersは、今回、システム更新後のみで試しているが、かなり遅い。 こうしたことも、個人で調べるのは時間も金もかかるが、マネーフォワードなら簡単に分析できる。研究者には垂涎の的だろう。 *このページのアーカイブ [#d66bc322] -[[このページの2018年6月12日6時時点のPDF:http://over.6pb.info/wiki/pdf/creditcard_foreignfee20180612.pdf]]のハッシュ値(md5) 6ef6eecdf31b8111b6c175d968be5354 at [[Twitter:https://twitter.com/7PB/status/1006287426346610688]] -[[このページの2018年 5月12日時点のPDF:http://over.6pb.info/wiki/pdf/creditcard_foreignfee20180512.pdf]]のハッシュ値(md5) 4436db3ae118bf23f5e77b3b53456b2bdeb25b1e at [[Twitter:https://twitter.com/7PB/status/995148194467074048]] --ちなみに、ハッシュ値はWindows標準のコマンドで求めることができる。
タイムスタンプを変更しない
#contents The official figure of credit card transaction fee for foreign currency transactions (Foreign Transaction Fees) is mostly 1.63%, but the actual figure is somewhat different. Especially, "I feel" the difference between VISA and Master is unexpectedly big. To produce statistically meaningful numbers instead of "I feel" -- to a very limited extent with personal data (The only one who can do that with many sorts of analysis axis is Money Forward, Inc. and so on.) -- I've get them in order as much as we can./カードを外貨建てで使った場合の手数料(海外決済事務取扱手数料/Foreign transaction fees)は公式では1.63%の数字が多いが、実際の数字はなぜか違う。特にVISAとMasterの差が意外と大きい「感触がある」。「感触がある」ではなく、統計的に意味のある数字を出すには――それが可能な切り口は――、個人の手持ちデータではかなり限られるが(縦横無尽の切り口でそれができるのはマネーフォワードなど限られた位置にある者だけ)、できる範囲で整理して見た。 *最新 [#p3cec8e0] -2019年7月1日(月)以降 [[「外貨でのショッピングご利用に伴う事務処理手数料」改定および海外旅行関連サービス拡充のお知らせ|クレジットカードの三井住友VISAカード:https://www.smbc-card.com/mem/cardinfo/cardinfo4010221.jsp]] -「最終画面では、日本円で支払うか米ドル(米国の場合)で支払うかを選べる(図11)。日本円を選んだ場合は表示されている額が適用される。米ドルを選ぶと、カード会社の為替レートが適用される。ただ、どちらも大差があるわけではない。」岡本ゆかり 日経パソコン 2021年4月26日号//確かめたの? *VISA v. Master [#k17faf3d] &htmlinsert(:HTML/クレカ為替手数料集計); -How much added to the TTM / TTMにどれだけ上乗せされているか。 -The value below the table shows the difference when you use 1 million JPY. / 表下は、100万円分使ったときの差額。 -Confidence coefficient/信頼係数 95%。 #hr --換算日が分かるもの(三井住友カード、JCBカード、セゾンカード)と換算日を合理的に推測できるものだけを集計。利用日を単純に換算日と仮定したものは集計に一切含めなかった。換算日の推測は,VISA/Master等のレートに各カード所定の公式手数料を乗せたレートと,カード明細記載のレートとの乖離が0または十分小さい日を換算日と推測した。十分小さい日がなく換算日を合理的に特定できなければ集計から除外。上記観測個数は,実際に最終の計算に使った取引のみの件数。除外取引を含まない。 --TTMは原則として三井住友カードなら三井住友銀行,DCカードなら三菱東京UFJ銀行を使った。ただし,三井住友銀行は台湾のTTMを公開していないなどの場合は適宜,日本の他行を使った。VISA/Master等のレートはそれ自体がTTMより悪いので,基準はあくまでもTTMとした。 --DCカードのMasterは持っているがVISAは持っていない。DCカードは手数料が上がってからは海外のショッピングで使うのをほぼ止めた。(キャッシングにはDCカードを専ら使っている。)Cf. [[外貨でのショッピングご利用代金を円貨へ換算するための事務処理手数料改定のお知らせ(Visa・Mastercardをお持ちのお客さまへ)|クレジットカードなら三菱UFJニコス:http://www.cr.mufg.jp/member/new/20161101_01.html]] ---もっとも、最近のデータを見ていて気付いたのだが、DCカードは公式の手数料率より実際の料率はかなり低いようだ。しかし、為替リスクが大きい傾向もある(実際の換算日(推測)が利用日からかなり離れている)ので痛し痒しだ。一概に有利なカードとは言えないようだ。 --実際は発行会社その他の要因も影響しているようだが,分析するにはサンプルの多様性が全然足りない。 --この表は原本からリアルタイム更新なのでたまに実験中の異常値が表示されることもある。 -三井住友カード、JCBカード、セゾンカードは換算日(三井住友カードが何日のレートを使ったか)が明細に表示されるのでデータを分析する上で重宝している。換算日が営業日でない場合,実際に適用されているのは翌営業日のレートみたいだ。(私個人のデータしかないのでサンプルサイズが圧倒的に不足するのだが。)MasterやVISAのウェブでは営業日以外の換算レートも見られるけど,そのレートはTTMより上乗せがあるので,カードの実質手数料を比較する上でよい基準とは言えない。 -換算日が書いてないカードでも推測は立つ。VISAまたはMasterのレートから実質手数料を計算して1.67%(あるいは各カードによる公式値)に一番近い日が換算日だろう。 -各社公式情報 --[[海外でのご利用範囲|セゾンカードご利用ガイド|クレジットカードは永久不滅ポイントのセゾンカード:http://www.saisoncard.co.jp/guide/gu009.html]] --[[換算レートや海外事務手数料について教えてください。 | 楽天カード:よくあるご質問:https://support.rakuten-card.jp/faq/show/15344?category_id=14&site_domain=guest]] --[[ご利用明細のご説明|クレジットカードの三井住友VISAカード:https://www.smbc-card.com/mem/oshiharai/pop/wm_setsumei.jsp]] --[[外貨でのショッピングご利用代金を円貨へ換算するための事務処理手数料改定のお知らせ(Visa・Mastercardをお持ちのお客さまへ)|クレジットカードなら三菱UFJニコス:http://www.cr.mufg.jp/member/new/20161101_01.html]] *同日同店で競争 [#p8f4c262] There is another way to compare. I tried to use multiple cards at the same time at the same store to evaluate each other. I charged my gift cards on Amazon USA. This makes it easy to increase the number of observations./もう一つ、比較方法がある。同じ時刻に同じ店で複数のカードを使って相対評価する方式を試した。米国amazonでギフトカードをチャージして試している。これなら観測個数を増やすのが簡単だ。 &htmlinsert(:HTML/クレカ為替手数料集計2); Right: Comparison with TTM (In other words, absolute evaluation. Conversion date basis). Left: A relative evaluation with ANA Master. Compared with "Exchange Rate" on each card's invoice. (This is always there.)/右はTTMとの比較(いわば絶対評価。換算日基準)。左はANA Masterとの相対評価。各カードの請求書記載の「換算レート」(これは必ず載っている)を比較している。 -見ての通り、JAL DC Masterの誤差が非常に大きく、統計的に意味がない。(その結果、JAL DC Masterを加えて「Master, VISA, JCB」という比較をすると統計的に意味がなくなってしまう。)JAL DC Masterの誤差が大きいのは、換算日(これは非公開)が利用日から(大きめに)離れているか、(そもそも)一定しないか、その両方か、だと推測する。ANA Masterとブランドは同じであるから、換算日が同じであればレートも同じになるはずだが、この通り全然同じにならない。 とりあえず、ANA MasterとANA VISA Suicaの比較では、VISAの方が手数料が高いと言える。どちらも三井住友カードで、換算日が明記されているので、TTM比で比べても無理がないカードだ。JCBの数字は誤差がまだ大きめであり、何とも言えない。 -TTMと比べる方式には課題がある。いつのTTMと比べるかだ。「換算日」は一つの基準になるが「換算日」が非公開のカードの方が多いだろう。また換算日のTTMが休業日で取得できないことも少なくない。そもそも、比較する日が利用日から離れれば離れるほど、為替変動のリスクが大きくなり、ブランドやカード会社の手数料なのか、それとも為替変動による偶然なのか、区別が難しくなりそうだ。では利用日のTTMで比べたらどうか。それなら為替変動リスクを排除できそうだ。もちろん、利用日のTTMが手に入らないこともあるし、どの銀行のTTMを使うか、その他の課題はある。しかしそれは決めの問題であり致命的ではない。さて、実際に計算してみると、「そうだ」の通りには行かないようだ。 -3つの方法には以下の差があるようだ。 |換算日のTTMで比較する(絶対評価)|カード発行会社の上乗せ分を見る。| |利用日のTTMで比較する(絶対評価)|カード発行会社とブランドの上乗せ分を見る。しかし誤差が大きく(為替変動や料率の変動や、その他未知の要因など全ての変動が一緒くたになっているためだろう)、カード毎の差も小さいため、解釈が難しい。| |相対評価|為替変動リスクを含む消費者の負担を見る。誤差は為替変動リスクを見るのに適する。| -相対比較の誤差の大小は、主に為替変動リスクを示している。利用日と換算日(公開非公開問わず)との間の日数が主に左右しているはずだ。 --しかしその他に、換算レートが為替変動のトラッキング以外の要因に左右されている要素もあるだろう。根拠は、TTM比の誤差のANA PASMO JCB(換算日が明記されているカード)の値が特に小さいことだ。JCBの自社発行カードであり、VISAやMasterブランドのような中抜きする人が、他にいない(JCB単独のルールで換算レート=上乗せ率が決まっている)ことを示しているという推測が立つ。 -TTM比の誤差が小さいことは、カード会社が上乗せする率のルールに、消費者にとって未知の要因がないことを意味する。特に換算日を明記しているカードに妥当する。この点で、ANA PASMO JCB(換算日を明記)が特に小さいのは、JCBの自社発行カードであり、VISAやMasterブランドのような中抜きする人が、他にいないことを示しているのかもしれない。 -ちなみに、実験開始当初は間隔を空けずに連続的に複数のカードを使ったが、8順目でカードブランド(Master)から承認拒否された。拒否したのはamazonや日本のカード会社ではない。カード会社に自分から電話して照会したら、カード会社側にはデータが来ておらず、従って拒否もしていないし、何も情報がない、とのことだった。Masterのカード(発行会社は違う)だけ拒否されたので、Master側(Master段階というべきか)の拒否判定だと推測できる。Masterが拒否するとカード発行会社にも情報が(少なくとも利用日前後の時点では)行かないようだ。(一定期間でまとめて報告されることはあるかも。) --やり過ぎるとamazonからbanされるかも。[[アマゾンがアカウントを閉鎖する客とは - WSJ:http://jp.wsj.com/articles/SB11252457003671273998304584241121630753840]] -JAL DC Masterの分散を人為的に小さくすることもできそうな感じ。利用日と換算日(早ければ翌日)が、日本と米国いずれの休日にもかからないように利用すればよい。しかし、実際の買い物行動とは離れてしまう。ここではそういう操作はしていない。 *自動化 [#k070fe2d] **カード明細取得自動化 [#v51103ac] 自動化しないと誤記する。また、自動化し、巡回精度を保たないと統計精度を保証できない。 速報はCSVでダウンロードできないカードが意外とある。そういうのは[[勝手にボタンを付ける>情報管理#table2csv]]。Amexは単純なスクレイプでは取得できない(ページがJavaScriptで動的に作られる)ので、[[headless Chrome + Puppeteer (Node.js)>NET/www/webプログラミング#puppeteer]]で取得している。 ***Amex自動化 [#amex] #pre{{ const puppeteer = require('puppeteer'); const fs = require('fs'); (async() => { const browser = await puppeteer.launch({ //headless: false, args: [ '--no-sandbox', ] }); const page = await browser.newPage(); await page.setViewport({width: 1024, height: 768}); await page.goto('https://global.americanexpress.com/myca/logon/japa/action/LogonHandler?request_type=LogonHandler&Face=ja_JP&inav=jp_utility_login', { waitUntil: 'networkidle2'}); await page.waitForSelector('input#lilo_userName', {waitUntil: 'networkidle2', timeout: 10000}); await page.focus("input#lilo_userName"); await page.type("input#lilo_userName", 'your ID'); await page.focus("input#lilo_password"); await page.type("input#lilo_password", 'your passwd'); await page.click('#lilo_formSubmit'); await page.waitForNavigation({waitUntil: 'load'}); await page.waitForSelector('#balance-summary-table', {waitUntil: 'networkidle2', timeout: 2500}); // カードによって違うので要修正 await page.click('#balance-summary-table tr.recent-debits > td.description > a'); await page.waitForNavigation({waitUntil: 'load'}); await page.waitForSelector('#transaction-table', {waitUntil: 'networkidle2', timeout: 7000}); //tr要素のidを取得。transaction id let tid = await page.$$eval('#transaction-table tr[id]', list => { return list.map(date => date.id); }); let lines = []; // transaction id毎に // 各決済のtrは2段からなる。 // クリックによる展開前と展開後の詳細 // idが違う。 for (let i in tid) { await page.click("#transaction-table tr#" + tid[i] + " td.date"); await page.waitForSelector("#transaction-table tr#" + tid[i] + " + tr p.amount.ng-binding", {waitUntil: 'networkidle2', timeout: 7000}); // 詳細欄のtransaction id取得 // 例: #etd-details-content-AT181580... let dom = '#transaction-table tr#' + tid[i] + ' + tr[id]'; let tidd = await page.$eval(dom, e => e.id); // dateと請求額は1段目のtr dom = 'tr#' + tid[i] + ' td.date span.ng-binding'; let date = await page.$eval(dom, e => e.innerText); //#trans-... > td.date > div > span.ng-binding let shop = await page.$eval("tr#" + tidd + " p.header.ng-binding", e => e.innerText); //#etd-details-content-AT1815... > div > div.etdContent.ng-scope > div.etdBlock.ng-scope > p.header.ng-binding let local = await page.$eval("tr#" + tidd + " p.amount > span:nth-child(1)", e => e.innerText); //#etd-details-content-AT1815... > div > div.etdDetails.ng-scope > div > div:nth-child(2) > p.amount > span:nth-child(1) let curr = await page.$eval("tr#" + tidd + " p.amount > span:nth-child(2)", e => e.innerText); //#etd-details-content-AT181... > div > div.etdDetails.ng-scope > div > div:nth-child(2) > p.amount > span:nth-child(2) dom = 'tr#' + tid[i] + ' td.amount > div > span'; let jpy = await page.$eval(dom, e => e.innerText); //#trans-AT18158... > td.amount > div > span let rate_date = await page.$eval("tr#" + tidd + " div.etdContent.ng-scope > div:nth-child(2) > div > p.ng-binding.ng-scope", e => e.innerText); //#etd-details-content-AT18156... > div > div.etdContent.ng-scope > div:nth-child(2) > div > p.ng-binding.ng-scope let rate = await page.$eval("tr#" + tidd + " p.amount.ng-binding", e => e.innerText); // #etd-details-content-AT181... > div > div.etdDetails.ng-scope > div > div:nth-child(3) > p.amount.ng-binding let line = [date,shop,local,curr,jpy,rate_date,rate].join(','); console.log(line); lines.push(line); } fs.writeFile('amex.csv', lines.join("\n"),(err) => { if (err) throw err; }); //ログアウト await page.click('#jp_utility_login'); await browser.close(); })(); }} **TTM [#r7e6fc06] TTMの入手先: -[[外国為替情報 : 三井住友銀行:http://www.smbc.co.jp/market/backnumber/fixing/]] -[[三菱UFJリサーチ&コンサルティング | 外国為替相場 | 1990年以降の為替相場:http://www.murc-kawasesouba.jp/fx/past_3month.php]] -TTM(仲値)というわけではないが、[[Pacific Exchange Rate Service - Database Retrieval System:http://fx.sauder.ubc.ca/data.html]] 自動化しないと、誤記する。 -三井住友銀行(なお、私は同行からbanされた。403 Forbidden。やり過ぎに注意。) #pre{{ #!/usr/bin/perl use utf8; use strict; use warnings; my $url = 'http://www.smbc.co.jp/market/backnumber/fixing/'; # 今月 my $thisMonth = '//*[@id="tabbox1"]/div//li/a/@href'; # 前月 my $lastMonth = '//*[@id="tabbox2"]/div//li/a/@href'; use URI; my $u = URI->new($url); use HTML::TreeBuilder::XPath; my $tree = HTML::TreeBuilder->new_from_url($url); my @href = $tree->findvalues($lastMonth); push(@href, $tree->findvalues($thisMonth)); use LWP::UserAgent (); my $ua = LWP::UserAgent->new; for my $pdfpath (@href) { my $uri = sprintf qq(http://%s%s),$u->host,$pdfpath; my $response = $ua->get($uri); if ($response->is_success) { my $pdfbody = $response->decoded_content; my $tmpfile = "/tmp/msbcrate.$$"; open(my $fh, '>', "$tmpfile") or die "$tmpfile:$!"; print $fh $pdfbody; close $fh; open($fh, "pdftotext -layout $tmpfile - |") or die "pipe:$!"; my @content = <$fh>; close $fh; unlink $tmpfile; if (my ($date, %rate) = &msbcrate_pdf(@content)) { my $ttm = ($rate{'usd'}->{'tts'} + $rate{'usd'}->{'ttb'})/2; printf qq(%s\t%.2f\n),$date,$ttm; #my $insert = #"INSERT IGNORE INTO usd VALUES ('$date','SM','$ttm')"; #$db->do($insert) or die $db->errstr; } else { print STDERR "failed in $pdfpath\n"; } } } #$db->disconnect; exit; sub msbcrate_pdf { my @lines = @_; my $date = ''; my %rate = (); my %month = qw( Jan 1 Feb 2 Mar 3 Apr 4 May 5 Jun 6 Jul 7 Aug 8 Sept 9 Sep 9 Oct 10 Nov 11 Dec 12 ); for (@lines) { # Date: May.25, 2018 if (my @temp = (/Date:\s+([a-zA-Z]+)\D+(\d+)\D+(\d+)/)) { my $month = $month{$temp[0]} // 'fail'; $date = "$temp[2]/$month/$temp[1]"; next; } if (/U\.S\.A\.\s+USD\s+1\s+([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)/) { $rate{'usd'}->{'tts'} = $1; $rate{'usd'}->{'ttb'} = $3; next; } } if ($date eq '' || !defined $rate{'usd'}->{'tts'}) { return; } else { return $date, %rate; } } }} -三菱UFJリサーチ&コンサルティング #pre{{ #!/usr/bin/perl use utf8; use strict; use warnings; use Time::Piece; use Time::Seconds; my $t = localtime; my $days = 20; # 過去○日分取得する。 use LWP::UserAgent (); use HTML::TreeBuilder::XPath; my $baseurl = 'http://www.murc-kawasesouba.jp/fx/past/index.php'; # http://www.murc-kawasesouba.jp/fx/past/index.php?id=180419 for (1..$days) { my $date = sprintf qq(%02d%02d%02d),$t->yy,$t->mon,$t->mday; my $url = $baseurl . '?id=' . $date; my $ua = LWP::UserAgent->new; # 営業日以外は「本日の為替相場」に転送される。 # http://www.murc-kawasesouba.jp/fx/index.php $ua->max_redirect(0); my $response = $ua->get($url); my $root = HTML::TreeBuilder->new(); if ($response->is_success) { $root->parse_content($response->decoded_content); my $tts = $root->findvalue('//*[@id="main"]/table[1]/tr[2]/td[4]'); my $ttb = $root->findvalue('//*[@id="main"]/table[1]/tr[2]/td[5]'); my $ttm = ($tts+$ttb)/2; my $date = $t->ymd("/"); printf qq(%s\t%.2f\n),$date,$ttm; #my $insert = #"INSERT IGNORE INTO usd VALUES ('$date','MU','$ttm')"; #$db->do($insert) or die $db->errstr; } $t -= ONE_DAY; } #$db->disconnect; exit; }} *Amexの意外な競争力 [#a7ef8fc5] Amexの決済インフラは他社に比べ圧倒的に強いかもしれない。Amexの自社発行カード(日本法人)は、試した範囲では、他のイシュアー(発行会社。三井住友カードや楽天カード、DCカードなど)やブランド(VISA、Master、JCBなど)に比べ、カードを利用してから明細に出るまでの時間が、圧倒的に速い。(今回、明細の確認はロボットで自動化しているので、傾向を統計的に把握できる。)クレジットカードの仕組みはもう何十年も前に作られたもので、本来リアルタイム決済を想定したものでは全くない。時代の趨勢に答えてリアルタイムで処理するには、多大なシステム投資が必要だ。しかも、自社だけの投資で終わらず、販売店との連携も必要になる。また、クロスボーダーの決済はどんどん増えるだろう。Amexでは、日本発行カードでも日本の営業時間に制約されないことも見て取れる。 Amexの他では、三井住友カード(VISA、Master)が結構健闘していた。それでも、日曜はデータが動かないことが見て取れるなど、システム設計の古さを推知できる。日本時間の午前中か否かで処理のバッチが切り替わる(Master)ことも推知できる。VISAかMasterかでバッチの挙動も異なる。自社ブランドでないので自分でコントロール出来ないのだろう。今回のカードでは、JCBは自社ブランド・自社発行のカードだが、速度に特に目立った特徴はない。三井住友トラストクラブ株式会社(三井住友信託銀行の100%子会社。旧、シティカードジャパン株式会社)のDinersは、今回、システム更新後のみで試しているが、かなり遅い。 こうしたことも、個人で調べるのは時間も金もかかるが、マネーフォワードなら簡単に分析できる。研究者には垂涎の的だろう。 *このページのアーカイブ [#d66bc322] -[[このページの2018年6月12日6時時点のPDF:http://over.6pb.info/wiki/pdf/creditcard_foreignfee20180612.pdf]]のハッシュ値(md5) 6ef6eecdf31b8111b6c175d968be5354 at [[Twitter:https://twitter.com/7PB/status/1006287426346610688]] -[[このページの2018年 5月12日時点のPDF:http://over.6pb.info/wiki/pdf/creditcard_foreignfee20180512.pdf]]のハッシュ値(md5) 4436db3ae118bf23f5e77b3b53456b2bdeb25b1e at [[Twitter:https://twitter.com/7PB/status/995148194467074048]] --ちなみに、ハッシュ値はWindows標準のコマンドで求めることができる。
テキスト整形のルールを表示する