株式会社エフのブログ

株式会社エフのブログ

金融ITソリューションのコンサルティング システム導入、開発

Amebaでブログを始めよう!
大容量メモリーの活用方法として、
「断面形式での約定履歴の保存」を構想&設計してみました。



■構想に至った背景

過去データと比較する場合、
 ・前日
 ・前月
 ・前四半期
 ・前年度末
これらのデータと比較する必要があるのですが、

新規、償還、キャンセル、リセットといった操作データが相関しているので、
過去の断面にロールバックするのには、大変な手間と苦労がかかります。

そこで、
過去の断面をメモリーに丸ごと展開出来れば、
過去データとの比較が容易になるのではと思い及びました。



■設計時の課題

設計をしていて、
シリアライズ、デシリアライズに時間が掛かるという、
不測の落とし穴があることが分かりました。

この状態では実用出来ないので、メンバーと解決策を思考中です。


【案1:マップに書いてバイナリで落とす】

 →効果なし
  (ディスクIOより早くはならない。10GBのコピーに掛かる時間位は必要。)


【案2:裏で自身を永続化するようなオブジェクトを作成】

 →効果あり&実装可能
  永続化を一斉にやる必要性は無い。
  全員にその仕組み組み込ませるのは面倒なので、
  クラスを一個作成。(規約として継承必須にする。)

プロトシステムの商品に金利スワップションを追加しました。

 

 

スワップションの条件は

 5into10SA100万件

 

約定生成処理時間は

 通常for165

 Parallel.For179

 

PV計算時間は

 通常for 151 

 Parallel.For 17

 

上記の数値が正しいとすると、

全約定を毎分計算するという、驚きの計算速度が実現することになります。

 

想定よりも簡単に実現出来てしまったので、

計測ミスしているのでは、という疑念を抱いてしまいます。

今回はSwap100万件の計算処理においてPV(現在価値)の計算まで行ってみました。

 

以下のような条件で約定(仮想)があったものとしています。

SPOTスタート、10年満期、SA、固定vs変動(JPY LIBOR)

 

前回と同様に2つの方法で実行すると、

通常のFor文でのトータル計算時間 105.501秒 (1件辺り= 1055マイクロsec

Parallel.For文でのトータル計算時間 6.838秒 (1件辺り = 68マイクロsec

でした。

 

前回、2ヶ月程掛けてCore22GBメモリをかなりチューニングした際の結果が

200マイクロsecであったのに対し、今回あっさりとその計算処理のパフォーマンス

を抜いてしまいました。

 

ただ、、前回の計算ロジックはオブジェクトコピーが走らないようにクラス構成も

かなり気を付けていた上で2GB内で収まるように開発していたのですが、この差は

一体どこから出てくるのだろうか・・・との疑問が浮上。

 

推測ながらこのあたりの差異の発生は、

1)使用している.NET Frameworkのバージョン差によるParallelを使えるか使えないかどうか、

2)コア数が2個と16(仮想32)個の違い、

あたりが一番大きいのではないかと思っています。 

当初は10万件を想定していましたが、10万件ではベンチマークの計測すら
出来なかったので、仮想取引として5年~10年のSwapを100万件生成してみました。

オブジェクトの構成は、TRADEの下にLEG、LEGの下に、CASHFLOW情報
CASHLETのコレクションとして存在する良くある形です。
ここで、

1) 通常のfor文での負荷の掛り方


2) parallel for 文での負荷の掛り方
 


の2つの実行方法があるのですが、

処理時間は、
通常のfor文で36秒。(1件辺り36マイクロ秒)
Parallel for文で13秒。(1件辺り13マイクロ秒)
でした。


処理時間は、
通常のfor文で36秒。(1件辺り36マイクロ秒)
Parallel for文で13秒。(1件辺り13マイクロ秒)
でした。

ただ、ここで気になったのが生成されたオブジェクトをListに追加すると、
約38秒程、処理時間が増加しているのです。

オブジェクトを生成し、日付をシフトさせて・・・という処理よりも、
Listへの追加の方が負担が掛っていることになります。

全体が高速なため、取るに足らない負担かもしれませんが、
生成そのものよりもこちらの方がロードが掛るとなれば、
それが今後の課題になるのかも。

ちなみに、100万件でのメモリ使用量は約7.6GBでした。(余裕!)

プロトシステムを設計する上でいくつかの検討課題が浮上。

 

PVを算出する過程で必要になる「ゼロカーブ」、「期間年率換算値」、「DF」、「フォワードレート」これらの中間値をどうやって持たせるか、また計算のトリガーをどうするか…。

 

プロパティで再計算をする形にすれば、準リアルに近い形に出来る反面、場合によっては無駄な計算が走る可能性や最悪無限ループになる可能性もあります。

 

メソッドで用意すれば個々に再計算をしなければなりませんが、バッチ的に動かせるのでパフォーマンス検証は行いやすくなります。

 

前者はフロント、リアル向き、後者はミドル、バッチ向きとも言えるでしょう。

 

また、計算ロジックを「取引」、「カーブ」、「計算用のオブジェクト」のどこに持たせるかでその性質が変わります。

 

加えて、中間値自体を使い回せる形にするかも、一単位辺りの計算負荷や個別に回したいか、あるいはポートフォリオとして回すかで最適な形が変わります。

 

これはOTC物に対する話で、上場物の場合はまた別の視点になります。

 

この作業をしていてふと思うのは、PVを求めると一言で表現しても、どの様に求めたいかでクラス構成が全く変わる訳ですが、他のシステムは、そこまで織り込んで設計しているだろうか?

 

過去の経験上、スワップの固定を債券の計算に使ったりするなど、計算出来れば良いと言う物が余りに多い気がします。

 

そんな事をするから、オンオフの一体管理すら出来なくなってしまう・・・・・。

そもそもの商品の取引手法(頻度や取引量)が違うので、同じコードを使うと要件が満たせなくなってしまうのです。