FX, USDJPY(ドル円), 2018/04/03

【メモ】

4時間足の高値切り下げ、安値更新が見えつつある場面で、1時間足の直近安値割れの位置に逆指値の売り注文を入れて就寝。

夜間に注文が通って、1時間足・4時間足の短期移動平均が共に水平から下向きに。

起床したときには、利益を確保した状態で損切が移動していた。

そのあと大きく戻して、含み益をごっそり吐き出して決済。

勝ちだが、小さい利益。

日足が押し目買いのポイントに見え得るのに注意して決済を早めるべきだったかもしれない。

就寝前でチャートを見れないということも考えると、直近の上昇トレンドのブレイクラインに指値注文を入れておけば良かった。

FX, GBPUSD(ポンドドル), 2018/03/21

【メモ】

週足は、上昇中の短期移動平均と水平の節目ラインに支えられて上昇中。

日足の短期移動平均は上昇から一旦下降して水平気味。

4時間足の短期移動平均は上向き。水平の節目ラインに支えられて 安値切り上げが見えつつある状況。

1時間足で、安値切り上げ、高値更新して、短期移動平均が水平から上向きに確定したところでロング。

直後に強い陽線。VPSで動かしている決済用の自作プログラム(EA)が建値の少し上に損切りを移動させる。

さらに大きな上昇を期待していたし、するかもしれないが、頭が節目に引っ掛かったので利益確定。

毎月資金の追加がある場合の複利計算をするプログラム

投資をするときに、初期資金・月利・毎月追加する資金を固定すると、nヶ月後の資金がどうなるか、様々なパターンでシミュレーションするプログラムが欲しかったので書いてみました。

例として、初期資金200万円、月利10%、毎月20万円を追加することにしてシミュレーションすると、3年で1億円を超えました。税金は考慮に入れていないです。

Reactで作ったアプリにFirebase Authenticationでログインを実装

結論から言うと、index.jsでonAuthStateChangedを実行して、コールバックが返ってきてからReactDOM.renderを実行です(詳細は後述)。

はじめはcomponentWillMountでfirebaseのonAuthStateChangedを実行しようと思いました。

調べてみると、そのようにしている情報ばかりが出てきます。

しかし、少し試してみると、問題に気づきました。認証されてコールバックが返ってくるのがReact Componentのライフサイクルが終わってからになってしまうのです。

設計がFluxになっている場合、これは大きな問題になります。

Fluxの場合、Storeが更新されたらViewも更新するという流れなのですが、React Componentのライフサイクルの後に認証情報が返ってきてしまうと、その認証情報でStoreを更新した後に、もう一度React Componentのライフサイクルが始まるということになります。

componentWillMountやcomponentWillReceivePropsでたいした処理をしていないのなら、ちょっと無駄なことをしてるけどまあいいかで済みますが、大きな容量のデータを取得する処理を入れていれば、無駄なデータ転送をした上に、(目で見て分かるレベルで)表示の遅延も起きます。

さらに、認証が通っていないと表示してはいけないページがあった場合にどうしようか悩みます。ちょっと微妙ですが、認証情報がpropsに渡ってこなかったら、一旦render() { return null; }としておいて、認証情報が渡ってきてから表示するという手があります。しかし、認証が通っていなかったらリダイレクトさせたいという場合に困ってしまいます。また、そのページのcomponentWillMountやcomponentWillReceivePropsが認証が通っていなくても実行されてしまうのも良い気がしないですね。

キレイにFluxで設計しきることを諦めて、認証情報とそれに関する処理だけ別で実装することで解決することも可能かもしれませんが、そういうイレギュラーなことをするとバグの元凶になり得ますし、メンテナンス性が悪化してしまいます。

そこで、そもそもReactDOM.renderするのを、認証が通った後にすれば良いという結論に至りました。

firebaseに関しては、

/src/services/firebase.js

import * as firebase from 'firebase';


if (!firebase.apps.length) {
  const config = {
    apiKey: API_KEY,
    authDomain: AUTH_DOMAIN
  };

  firebase.initializeApp(config);
}

const auth = firebase.auth();

export {
  auth
};

こんな感じで準備をしておき、

/src/index.js

import React from 'react';
import ReactDOM from 'react-dom';

import { auth } from './services/firebase';


auth.onAuthStateChanged((authUser) => {
  // ここで
  // store.dispatch(setAuthUser(authUser));
  // のように、storeの認証情報を更新する

  ReactDOM.render((
      // ここにルートとなるcomponentを書く
  ), document.getElementById('root'));
});

とすれば、storeに認証情報が保持されてからReact Componentのライフサイクルが始まるので問題は起きません。

認証が通っていないと表示してはいけないページは、componentWillMountでstoreを参照し、認証情報がなければログインページにリダイレクトすればいいだけです。

JavaScriptでnullなどが入った配列をソートする

JavaScriptで配列をソートするとき、nullなどが入っていると、うまくソートされないことがあります。

そこで、ソートするための関数を作りました。

var compare = (a, b, desc = true) => {
    if (a !== a && b !== b) return 0;
    if (a !== a) return 1;
    if (b !== b) return -1; 
    
    if (a == null && b == null) return 0;
    if (a == null) return 1;
    if (b == null) return -1;
    
    if (a === '' && b === '') return 0;
    if (a === '') return 1;
    if (b === '') return -1;
    
    var sig = desc ? 1 : -1;
    return a < b ? sig : (a > b ? -sig : 0);
}

用途としては、テーブルをカラムごとにソートするような場合を想定しているので、降順であろうと、昇順であろうと、NaN, null, undefined, 空文字は後に持ってくるようにしています。

これを使って、

arr.sort((a, b) => compare(a, b)); // 降順
arr.sort((a, b) => compare(a, b, false)); // 昇順

のようにします。

JupyterでGo言語とJavaScript(Node.js)を使う

以前、

仮想マシンでJupyterを使うときの初期設定

を書いたのですが、さらに設定を追加しました。

Jupyterの拡張機能が結構充実しているので、どうせならPython以外の言語も使えるようにしておきたいところです。

今回はGo言語とJavaScript(Node.js)を使えるようにしました。R言語やRubyも使えるようにしたいのですが、目下の課題で使う予定がないので、また必要になった時に設定しようと思います。

JupyterでGo言語

Go言語を使うためには、gophernotesをインストールします。

まずはOSのバージョンを確認します。

$ cat /etc/os-release 

バージョンは14.04でした。他のバージョンで検証していないので、以下このバージョンを前提にします。

また、Go言語のバージョンは1.9.2でやりました。

gophernotesをインストールするためにZeroMQ 4.X.Xが必要なので、インストールします。

$ sudo apt-get update
$ sudo apt-get install -y libtool pkg-config build-essential autoconf automake uuid-dev

$ wget http://download.zeromq.org/zeromq-4.0.5.tar.gz
$ tar xvzf zeromq-4.0.5.tar.gz
$ cd zeromq-4.0.5
$ ./configure
$ sudo make install
$ sudo ldconfig

あとは、

$ go get -u github.com/gopherdata/gophernotes
$ mkdir -p $(jupyter --data-dir)/kernels/gophernotes
$ cp $GOPATH/src/github.com/gopherdata/gophernotes/kernel/* $(jupyter --data-dir)/kernels/gophernotes

としてkernelを追加すれば、ノート新規作成時にGoを選択できるようになります。

JupyterでJavaScript(Node.js)

ijavascriptをインストールします。

npmは入っている前提(自分の場合、5.6.0)で、

$ npm install -g ijavascript
$ ijsinstall

とすればいいだけです。

ES2015 (ES6)が普通に使えて感動します。

仮想マシンでGo言語を使うときの初期設定

以下のようなシェルスクリプトを用意しました。

引数でバージョンを指定できます。デフォルトは1.9.2です。

レポジトリ管理のためのghqと、パッケージ管理のためのglideもインストールします。

#!/bin/bash

echo '# goenv' >> ~/.bash_profile
git clone https://github.com/syndbg/goenv.git ~/.goenv
echo 'export GOENV_ROOT="$HOME/.goenv"' >> ~/.bash_profile
echo 'export PATH="$GOENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(goenv init -)"' >> ~/.bash_profile

echo '# go' >> ~/.bash_profile
echo 'export GOPATH="$HOME/dev"' >> ~/.bash_profile
echo 'export PATH="$GOPATH/bin:$PATH"' >> ~/.bash_profile

source ~/.bash_profile

go_version=${1:-1.9.2}
goenv install $go_version
goenv global $go_version

go get github.com/motemen/gore
go get github.com/nsf/gocode
go get github.com/k0kubun/pp
go get golang.org/x/tools/cmd/godoc

go get github.com/motemen/ghq
git config --global ghq.root '~/dev/src'
mkdir -p ~/dev/src/github.com
cd; ln -fs ~/dev/src/github.com github.com

curl https://glide.sh/get | sh