Hatena::ブログ(Diary)

日常メモ

2016-04-12

SMAの変化について

(追記 2016/4/13)間違っていたので、修正(削除)。単純移動平均の差については以前書いた「単純移動平均とモーメンタムの関係について」に説明がある。

何故かこんなことを説明しなければならなかったので少々メモ・・・。

ある時点nの単純移動平均SMA(n)と書く。そこからk後の単純移動平均SMA(n+k)を考える。

ある時点nの価格のn平均をSMA(n)と書く。そこからk後の価格の(n+k)平均SMA(n+k)を考える。

ある時点nの価格をP(n)と書くと、

SMA(n)<SMA(n+k)となるのは、SMA(n)<{P(n+i)}/kとなる時。

ただし、i=1,2,…,kについて瑤鮗茲襦

つまり、

ある時点nからk日後の単純移動平均SMA(n+k)が、ある時点nの単純移動平均SMA(n)より大きくなるのは、(n+1)日後から(n+k)日後までの価格の平均が、SMA(n)より大きくなる場合

導出過程は書かないけど、たぶんあっている。

明日のSMAが今日のSMAより大きくなるのは、今日のSMAより明日の価格が大きくなった場合。

2016-04-05

【Java】doubleを使用した計算による誤差

既存アプリバグに遭遇した際のメモ。

【問題】

次のような変数があった場合、それらの積はいくつになるだろうか。

double d1=558.3
int i1=100

期待値は言うまでもなく、55830.0でしょう。

しかし、55829.99999999999になっているケースがあったという話。

【原因】

結論から述べると下記2つ。

2つ目で多少ハマった。

1.doubleではなくBigDecimalを使用する(基本中の基本)

2.valが少数の場合、new BigDecimal(val)とすると数値誤差が発生しうる

【検証】

検証コードは次の通り。

package numtest;

import java.math.BigDecimal;

public class NumericalTest {
	public static void main(String[] args){
		double d1=558.3;
		int i1=100;

		System.out.println("d1="+d1);
		System.out.println("i1="+i1);

		System.out.println("単純にdoubleの積だと数値誤差が発生する場合がある");
		System.out.println("【バグ】d1*i1="+d1*i1);

		/**
		 *
		 */
		System.out.println("BigDecimalを使用してみる");
		BigDecimal d1bd = new BigDecimal(d1);
		BigDecimal i1bd = new BigDecimal(i1);

		BigDecimal r1bd = d1bd.multiply(i1bd);
		System.out.println("【バグ】r1bd="+r1bd.doubleValue());

		/**
		 * BigDecimalコンストラクタの引数にString.valueOf()を使用
		 * この表現は 1 つの引数を持つ Double.toString メソッドによって返されるものとまったく同じ。
		 */
		d1bd = new BigDecimal(String.valueOf(d1));
		r1bd = d1bd.multiply(i1bd);
		System.out.println("【修正案1】r1bd="+r1bd.doubleValue());

		/**
		 * BigDecimalコンストラクタの引数にDouble.toString()を使用
		 */
		d1bd = new BigDecimal(Double.toString(d1));
		r1bd = d1bd.multiply(i1bd);
		System.out.println("【修正案2】r1bd="+r1bd.doubleValue());

		/**
		 * BigDecimalコンストラクタを使用せずにBigDecimal.valueOf()を使用する・
		 * BigDecimalコンストラクタの引数に文字列を使用する場合と同じ
		 */
		d1bd = BigDecimal.valueOf(d1);
		r1bd = d1bd.multiply(i1bd);
		System.out.println("【修正案3】r1bd="+r1bd.doubleValue());
	}
}

検証結果は次の通り。

d1=558.3

i1=100

単純にdoubleの積だと数値誤差が発生する場合がある

バグd1*i1=55829.99999999999

BigDecimalを使用してみる

バグ】r1bd=55829.99999999999

【修正案1】r1bd=55830.0

【修正案2】r1bd=55830.0

【修正案3】r1bd=55830.0

下記ブログが非常に参考になりました。

◎参考ブログ

floatをもとにBigDecimalオブジェクトを作成する

2016-04-01

Rでヒストリカルボラティリティの計算

Rでヒストリカルボラティリティを計算してみた。

# Calculate HV
getHV <- function(stockPrice, hvLength){
  # 株価前日比
  roc <- stockPrice/lag(stockPrice, k=1)
  
  #HVを20日間計算
  hv<-rollapply(roc, hvLength, sd)*sqrt(250)
  
  return(hv)
}

ロイターの端末での計算結果と比較して小数点第2位を四捨五入して同じ数値になったので、多分あっている。

補足)

zoo Quick Reference」。

https://cran.r-project.org/web/packages/zoo/vignettes/zoo-quickref.pdf

2016-03-31

現物価格と先物価格 〜 3月末

2016年3月末の日経225現物と先物の価格をグラフにしてみた。

具体的には、2016年3月25日(金)、3月28日(月)、3月29日(火)、3月30日(水)、3月31日(木)の一部の価格をグラフにした。

赤線が現物、黒線が先物の価格である。

f:id:graySpace:20160401004714p:image

現物価格(赤線)に注目すると、左から順に2016年3月25日(金)、3月28日(月)、3月29日(火)、3月30日(水)、3月31日(木)の価格である。

グラフを見ると、2016年3月25日(金)、3月28日(月)は現物価格の方が高いが、3月29日(火)からはほぼ同じ価格となっている。

これを図に纏めた。

f:id:graySpace:20160401010652p:image

マイナス金利のため短期金利(例えば無担保コール翌日物金利)はマイナスで、更に配当の分だけ先物理論価格は現物価格より小さくなる。

その差額は権利落ち日にはほぼ解消される。

Rで行列とベクトルの積

Rで行列とベクトルの積を計算しようと思ったら期待通りにならなかったのでメモ。

知らなかったーw。

◎やりたいこと

1行2列のベクトルを、2行2列の行列に左から掛けた結果を得たい。そして、最後にその結果に1行2列の転置ベクトルを掛けてスカラー値を得たい。

◎やり方

結論から述べると次のようにする。

内積演算子は「%*%」であることがポイント。

# 2 factor exp
factor.exp <- matrix(c(0.5, 0.75), nrow=1, ncol=2, byrow=T)
factor.cov.matrix<-matrix(c(0.625,0.0225,0.0225,0.1024), nrow=2, ncol=2,byrow=T)
stock.a.return<-(factor.exp%*%factor.cov.matrix)%*%t(factor.exp)

上記やり方では、ベクトルc(0.5, 0.75)をmatrixで行列に変換してから実行している。

ベクトルのままやるには次のようにする。

factor.cov.matrix<-matrix(c(0.625,0.0225,0.0225,0.1024), nrow=2, ncol=2,byrow=T)
stock.a.return<-(c(0.5, 0.75)%*%factor.cov.matrix)%*%t(t(c(0.5, 0.75)))

ベクトルをt演算子を使用して一度行列にしてから、更にt演算子を使用することで転置する箇所がポイント。