日付の用語と概念とそれらにまつわる話(2)
次は、settlementである(図右下)。
■settleDate
いままでが取引、契約側の概念だったのに対して、ここはその結果契約が履行され受渡が行われる側の概念になる。このグループに存在するのは一つしかない。settlementDateあるいは省略してsettleDateだけである。これは、取引側のvalueDate={spotDate, forwardDate}と何も変わらない。valueDateが価値基準日であるのに対して、settleDateは実際のお金を自分と相手の口座間で受け渡す(交換する)日であることを明示する言葉である。settleとは“決着する”ということである。
こうした概念上の整理をしても、実際にはそれらがごちゃごちゃに使われている事実は否めない。しかし使っている側もそれを見る・聞く側も概念としてのベースがちゃんとしていれば、それが使われている前後の文脈を正しく理解することで、この図のどの部分の話をしているかはちゃんと理解できる。特にシステムを開発する人同士で会話するときは要注意の用語であり概念である。
■accrueDate
発生日と訳す。キャッシュフローが生まれたときの取引日やそのデータがデータベースに書き込まれた時の時間を記録するエンティティ。発生日というニュアンスならaccrueDate。経理的な用語である。データベースに登録したというニュアンスを強くしたいなら、entryDate(入力日)。さらにそれらに実際の時間を記録するエンティティを持ちたければ、accrueDatetime, entrydatetimeとなる。どちらでもいいし、これ以外でもいい。ただし、transactionで使った、tradeDate, valueDateは使わない。特にvalueDateは使わない。これはセンスの問題。受渡に価値基準日は概念として矛盾している。だが、中に入っている情報としてvalueDate=settleDateはこのビジネスにおいては正しい。なので私はこれをセンスの問題という。tradeDateはあってもいい。その受渡が発生した時の取引日はいつであったかという意味ではaccrueDate=tradeDateになる。ならばtradeDateだけでaccrueDateは不要ではないかと言えばその通りである。
■spotDate(直物受渡日)の見つけ方。
用意する材料:
(1)通貨ごとの銀行祝日(CurrencyHoliday)
これは、12月頭にでも翌年の祝日を各国の政府のホームページで確認できる。気を付けるべきは、その祝日が“銀行”の祝日であること。国によっては宗教ごととか、学校は休みだが銀行はあいているとかいろいろあるので注意してほしい。一般に”National Holiday”と書いてあったらまずもって銀行も祝日である。
(2)通貨ごとに決める受渡日(CurrencySettleDate / CurrrencySpotDaysCount)
通貨ごとに取引が履行されたのちのお金や債券等の受渡する日(settlement date)は取引成立(あるいは満期日到来)の何日後と決めている。それをここではsettleDateと呼ぶ。USDはT+2であるが、外国為替の通貨ペア取引における直物受渡日の計算に限ってはT+1とする(これは私のルール)。そのようにマスターテーブルをセットする。ほかにトルコリラ、カナダドル、フィリピンペソなどT+1ルールの通貨はある。主に新興国や途上国など国としての通貨の信用力に乏しい“イメージ”のある通貨に多いのでご注意。
以上、必要な材料はこれらのみ。
では、計算。通貨ペアがCy1&Cy2であったとき、
ルール1:週末は飛ばす
ルール2:当該通貨の祝日は飛ばす
ルール3:その前提でCy1、Cy2のそれぞれのSettleDateを探す
ルール4:settleDate(Cy1)<>settleDate(Cy2)であったときは、大きいほうを取る-
> settleDate(Cy1Cy2)=max(settleDate(Cy1), settleDate(Cy2))
ルール5:もう一度、settleDate(Cy1Cy2)がCy1の休日祝日でもなく、Cy2のそれらでもないこと。そうである場合はさらに一日繰り延べる。そしてまた同じ休日祝日確認をする。それをどちらも休日祝日でない状態になるまで繰り返す。
ルール6:ルール5を潜り抜けたsettleDate(Cy1Cy2)がUSDの祝日かどうか。祝日だったらさらに一日繰り延べてルール5に戻る。Cy1 or Cy2がUSDであった場合は、ルール6をやる必要はない(やっても無害無反応)。
VBAあたりでコードを書くなら上記のルールの流れできれいに書けるだろう。
■よりプログラマー目線で
もっと具体的な説明を言葉を変えて説明する。
受渡日を決定するstrategyには業界を俯瞰すると3種類ある。まず対顧顧客では、リアルタイム決済(T+0)、インターバンク通り(spotDate)、それとspotDateにさらにその日が日本の祝日の場合は翌営業日(さらに日本の祝日でもなくドルの祝日でもない)、これを個々ではspotNDate ルールと呼ぶことにしよう。一方インターバンク側はリアルタイムというのは現実的に採用している業者はいないので、以下のような仕様になる。これら3つをそれぞれstragtegyとして宣言する。
Strategy:RealTime
リアルタイムは、約定した時のfrontDateをそのままtransaction.tradeDateとtransaction.valueDateにコピーしてしまうだけとなる。それが決済取引だった場合は同時に売買損益も確定するのでキャッシュフローが生まれる。キャッシュフローに対しては、cashflow.accrueDate とcashflow.settleDateに入れてしまう。全部同じ日付が入る。
Strategy: SpotDate
Step1
spotDateは、curpair(Cy1,Cy2)がある。それぞれについて、マスター情報のspotDaysCount(cy1), spotDaysCount(Cy2)を探し出す。また、同時に、curHoliday(Cy1), cuyrHoliday(Cy2)もリストで持ってくる。これに今現在のfrontDateも持ってくる。
それぞれのvalueDateを計算する。これにより
spotDate(cy1)とspotDate(cy2)が算出される。そしてspotDate(Cy1)<>spotDate(Cy2)だった場合は、どちらか大きいほうを採用する。
Instanace : spotDaysCount(Cy1), spotDaysCount(Cy2), frontDate(もしくはtradeDate)
List : curHoliday(Cy1), curHoliday(Cy2)
spotDate(curPair)=max(spotDate(Cy1), spotDate(cy2))
これで終わりではない。
Step2
spotDate(curPair)で決められた日は最低限この日という状態。これに対して、その日が、Cy1,Cy2,USDのどれの祝日でもないのであればそれで確定する。特にstep1でspotDate(Cy1)<>spotDate(Cy2)だったときに、spotDate(Cy1)>spotDate(Cy2)であった場合は、spotDate(curPair)はspotDate(Cy1)になっており、この時点ではまだ、新たなspotDate(curPair)がcy2にとって祝日かどうかの判定がされていない。
もしもStep1によって決定されたspotDate(curPair)が、それら3つの通貨のどれかの祝日であった場合は、さらに一営業日進めて、step2.IsthisDateHolidayOfTheCurrency(cur)を3通貨分繰り返す。一つでもtrueが返ってきたら、ここでさらに次の営業日を探す。このときに frontDateCalendarも参照することになる。それにより次の営業日がいつかがわかる。frontDateCalendarは元旦しか祝日として登録していないのが世界的な常識であるが、業者によってそれ以外の平日を非営業日にしたいならここで登録をすることになる。
Instance :frontDate
List :frontDateCalendar, curHoliday(USD)
Strategy:SpotNDate
Step1
Strategy:spotDateと同じ
Step2
Strategy: spotDateに、
「その日が、Cy1, Cy2, USD, JPYのどれの祝日でもない・・・」と、JPYも受渡日としない条件に含める
※Cy1,Cy2にUSDもしくはJPYが含まれているとしても、step2をそのままやっても無害
■Macroっぽく書くとこんな感じになる。
くどいとは思うが、あえて違う目線で説明をする。オブジェクトの型宣言等コーディングのお約束は省かせていただいている。
今現在の(あるいは新しい取引日の)受渡日を探す前提なので取引日は“今”の取引日を表すfrontDateを使う。
frontDateはtradeDateでも構わないが、tradeDate=frontDateが前提。オブジェクトをコピーする前か後かの違い。
全ての通貨は元旦を祝日としている前提。
受渡日を決める(見つける)ルールは3種類ある。
settleDateStrategy ={spotDateRule, spotNDateRule, RealTimeRule}
通貨と通貨ペアのobject名
cy1=left(curPair,3)
cy2=right(curPair,3)
Holiday(cur)=通貨ごとの祝日を返す
spotDaysCount(cur)=通貨ごとに定められた受渡日までのカウント日数。原則1か2しかない。
Sub Factory_FindValueDateByStrategy() ‘/Cy1の暫定スポットデートを見つける spotDate(cy1)=frontDate+spotDaysCount(cy1) repeart1: if spotDate(cy1)IsWeekendOrHoliday(Cy1) then spotDate(c1)=spotDate(cy1)+1 goto repeat1 ‘/Cy2の暫定スポットデートを見つける spotDate(cy2)=frontDate+spotDaysCount(cy2) repeart2: if spotDate(cy2)IsWeekendOrHoliday(cy2) then spotDate(cy2)=spotDate(cy2)+1 goto repeat2 ‘/Cy1&Cy2=curPairのスポットデートを見つける spotDate(curPair)=max(spotDate(cy1), spotDate(cy2)) repeart3: select case settleDateStrategy ’/どれか一つでもtrueを返したらさらに1日足す。ただしRealTimeの時は繰り返す必要がない。 ‘/すべての通貨は元旦を祝日としている前提で書いているが、それを絶対としないならIf分において 十分条件としてOrHoliday(frontDate)を付け加える case spotDate if spotDate(curPair)isEitherWeekendOrHoliday(Cy1)OrHoliday(cy2)OrHoliday(USD) then case spotNDate if spotDate(curPair)isEitherWeekendOrHoliday(Cy1)OrHoliday(cy2)OrHoliday(USD) OrHoliday(JPY) then case RealTime spotDate(curpair)=frontDate goto skipRepeat3 case end spotDate(curPair)=spotDate(curpair)+1 goto repeart3 skipRepeat3: end sub
SpotDaysCountを使うのは最初だけであとは1日ずつ進む。
Step1
最低限当日から離さなくてはならない受渡日を通貨ごとに見つける。
大きいほうを取る。
Step2
取った日を改めて検証。
まずは、週末ではないこと
Cy1の祝日ではないこと
Cy2の祝日ではないこと
USDの祝日ではないこと
(SpotNDateRuleの場合のみ)JPYの祝日ではないこと
どんなルールであろうとドルの祝日に受渡はしない。ましてSpotNDateルールが日本で生まれる背景は、CPカバー取引によって発生する決済受渡をその業者(証券会社か銀行)はネッティングしないでSWIFT等でダイレクトに受渡(settle)している場合、日本の祝日にそのオペレーションを行うスタッフが出勤しないので避けたいという条件が生まれる。そのためである。米国はもともとドルの祝日は受け渡さないというルールなのでこういう問題が起きない。では他のユーロとかはどうかと言えば、そういう時は誰かが出勤してくるだけのこと。日本も早くそうなればいいと思う。そうすればこういう面倒なメソッドを考えなくていい。どうせ週末もATMは動く時代である。“何をかいわんや、バック業務をや!”である。その辺もそろそろ柔軟になっていいのではないかと思う。これはメガバンクや大手証券の既知の弱点であるのでここでも私は言ってはばからない。
そもそも、外為証拠金取引においては、カバー側の理屈や立てつけがどうであれ、基幹システムの制約がどうであれ、受渡はリアルタイムでいいのである。あえてそれをT+2にする理由が私にはとんと不明である。差金決済=先物取引は全部リアルタイム決済である。実現益を出金できるかどうかはT+0だったり+2だったりと業者でまちまちになるのは構わない。少なくともシステムの仕様として、決済取引が執行され売買損益が確定したら速やかにその額を取引口座内で受渡し、残高に反映するのが合理的なのである。「取引口座」で生まれる決済をT+2にしたところで実際のお金が対外的に(SWIFTとか全銀ネットを使ってのように)動くわけではないのだから。ましてや信託法上実預託額(純資産)を日々仕切るのだから、取引口座内の現金残高と評価損益の区別すらないのである。信託と決済(日々の実預託額の差額のやり取り)はすべて現金である。つまり業者は対顧客で持つ評価損(業者側の損、客の評価益)までも現金で用意し信託口座に送金しなくてはならないのである。T+0かT+2かなどなんら関係ない。時価評価(額を現金で担保するルール)なのである。
▼尾関高のFXダイアリーをご覧のみなさまへ
このFXダイアリーで取り上げて欲しい話題、また尾関さんに書いてもらいたいテーマなどあれば業界内外問いませんので、「件名:FXダイアリーへの要望」として info@forexpress.com までご連絡ください(コラムへの感想でも勿論結構です)。