はじめに
Tezosを買って、それをwalletに入れてbakerさんにdelegateすると、(受け取れるようになるまでには少々時間を要しますが、)ステーキング報酬を受け取ることができます。
ステーキング報酬が受け取れるようになるまでの間はwalletに入れたTezos(XTZ)は自由に出し入れ可能ではありますが、ステーキング報酬自体はほぼ定期的に受け取ることができますので、仮にある時点でwalletへ/からの出し入れを止めてしまってwalletの存在自体を忘れかけたりしているような状態になると…
#Tezos で割とありがちな残高の推移。📈#lifeinyokohama pic.twitter.com/LVW09xeVjM
— pandanote.info (@Pandanote_info) June 6, 2021
のように、横軸を時刻、縦軸をwalletにあるXTZの残高としてグラフを描くと上図のような階段状のグラフになります。
※上記の段落につき、Twitter経由でご指摘をいただき、修正をいたしました。[2021/06/21]
ステーキング報酬はbakerさんから振り込まれますが、bakerさん自体が得るベーキング報酬等自体の量がサイクルごとに異なります。さらに、その他諸々の事情により、時々bakerさんからの振込のタイミングが前後したり、振込額が上下したりすると…
のように、いまいちきれいな階段状のグラフにならないことがあります。
そこで、Tezos APIから自分のwalletについてのデータを取得することにより、ステーキング報酬の年率換算の利回りを計算し、その結果をグラフ化するPython3のプログラムを書いてみることにしました。
計算の方法
計算の対象となる期間
ものすごくざっくりとした説明ですが、bakerさんがもらえる報酬の額は4096ブロックが生成されるごとに確定し、bakerさんはその報酬をもとにdelegatorに対するステーキング報酬の額を決め、delegatorに振込を行います。
よって、ステーキング報酬はbakerさんの方で特別な取り決めをしていない限り、8192ブロックを生成するために要するおおよその時間(=最短で4096分、8192ブロックを生成するのに要した時間または期間を1サイクルといいます。)ごとに振り込まれてきます。
※[2021/12/04 補足] Granada以前のプロトコルでは1ブロックがおおむね60秒で生成され、4096ブロックを生成するのに要した時間または期間を1サイクルといっていましたが、Granada以降のプロトコルで1ブロックがおおむね30秒で生成され、8192ブロックを生成するのに要した時間または期間を1サイクルと呼ぶように変更されています[1]。
その一方で、ステーキング報酬の利回りを計算するには1日分のデータを単に使っただけでは期間が短すぎるために、利回りの推移がつかみにくくなりそう(ステーキング報酬がない日(=利回りが0の日)が頻出してしまう。)な気がするので、数サイクル分のステーキング報酬の振込の状況を用いて利回りの計算を試みることにします。
「数サイクル」といってもその決め方が難しかったりするのですが、指定の日から直近20日分(指定の日を含みます。)の期間(以下、単に「期間」と書きます。)のデータを使って利回りを計算することにします。
スポンサーリンク
なぜ20日間なのかといいますと、20*1440/4096=7.03125で20日がほぼ7サイクルに相当することと、1サイクルは4096分よりわずかに長くなる(1ブロックを生成するための所要時間が1分より長くなることが時々あります。)ことがあるので、1サイクルの平均値は4096分よりも(おそらく)大きくなります。したがって、20日の期間をとることで7サイクルのステーキング報酬を受け取った場合の利回りを計算できると予想できます。
なお、1サイクルの平均値が4096分よりも大きくなりすぎて20日<7サイクルになったときのことは考えないことにします。
期間中の残高
計算の対象となる期間が決まったので、次は期間中の残高について考えます。
なぜ残高について検討しなければならないかといいますと、walletにあるXTZ自体は(delegationしているかどうかにかかわらず)walletから簡単に出し入れができてしまうからです。
そこで、指定の日から20日前の午前0時(UTCとします。以下同じ)から、指定の日の次の日の午前0時までにwalletに入っているXTZの残高の平均値を期間中の残高とします。
ただし、上記期間中に振り込まれたステーキング報酬は上記残高から除きます。
報酬利回り(年利換算)の計算
ここまでの考察より、報酬利回り$y$は、期間中の残高$a$、期間中に振り込まれたステーキング報酬の合計を$a_s$とすると、(\ref{eq:staking})式のように計算できます(パーセント表示とする場合は両辺を100倍します)。
y &= \frac{a_s}{a}\cdot\frac{365.24219}{20}\label{eq:staking}
\end{align}
計算及び描画結果
(\ref{eq:staking})式の計算を20日分の残高についての情報が得られる範囲で一日ごとに求めた結果をSeabornを使って描画したものが以下のグラフになります。
かなり意外なことに右肩上がり感がありますが、2021年の6月10日あたりに急に利回りが跳ね上がっているのは、たぶんこいつのせいです(下図の赤矢印)。
上記のようにステーキング報酬が急に増減するといったようなイレギュラーなことが起こらない限り、報酬利回りは4-5%あたりで当面の間推移しそうです。
まとめ
残高とステーキング報酬の金額についてはステーキングの開始当初からGROWIで表形式で管理をしていたのですが、振込の回数が増えてくると可読性が下がるので、適切な指標を定義して視覚化して大まかな傾向をつかむのも大事なことのように感じました。(`・ω・´)
この記事は以上です。
おまけ
本記事を書いている最中にPython3のプログラムが以下のようなエラーを出力するようになったので、ちょっと調べてみたところ、tzstats.comの証明書(Let’s encrypt謹製のようです。)がexpireしていたようです(その後すぐに証明書が更新されたようです)。
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1076)
今後も似たような事態が発生する可能性がありそうですので、ご参考にしていただけると幸いです。