Twitter Facebook github

Archive for 1月, 2016

RDS上のMySQLでKILLは使えない

軽い内容だけど備忘録として。

要はRDSのMySQLでは、プロセスを殺すためのKILLが使えないよーっておはなし。

KILLできない

例えばSleepプロセスを、root以外の管理ユーザーから殺したいと思ってKILLコマンドを許可する SUPER 権限をそのユーザーに与えたかったのだけど、それができない。

今の設定がどうなってるか確認してみると、そもそもroot(※インスタンス起動時に登録したマスターユーザー)にSUPER権限が与えられていない。

試しに他のユーザーのプロセスをKILLしてみる

 
やっぱりダメぽい…。

どうするか

AWS公式のドキュメントでこんなのを見つけた。

mysql.rds_kill – Amazon Relational Database Service

どうやらKILLが使えない代替策で mysql.rds_kill を使えってことらしい。

うまくいった。
これを一般ユーザーで使えるようにするためには、一般的なストアドプロシージャの許可と同じようにする。

補足

上表のユーザーリストで rdsadmin となっているのはAWSがRDSインスタンスの監視に使うユーザーであり、私たちはログインできない。
推測になるが、これらRDS管理系のシステム仕様上SUPER権限はユーザーに与えられていないのだろう。そういった類の特権処理について、AWS側の制約により実行できないものは別途ストアドプロシージャが提供されていて、これを介して使うことができるようだ。

それらのストアドプロシージャーはこのRDSのリファレンスページに纏められている。

所感

シェルからKILLを流し込むスクリプトなど、他の環境で使っていたものを流用するときは十分注意したいです。こういった制約とその代替策がいかにもAWSらしいような、そんな気がします。

CloudWatchのアラームをSlackに通知する

以前から挑戦したかったAWSの課題のひとつを解決してみようと思います。

AWS EC2やRDSなどのステータスを監視してアラームを上げてくれる、大変便利なCloudWatchですが、管理コンソール以外からアラームを確認する方法としては、SNSトピックに通知した後に自分でSNS連携のアプリケーションを作るなどして対応する必要がありました。

今回はこのアラームを、Slackの任意のチャンネルにポストすることをゴールにしてみます。

Read More »

はじめてのgit

gitについて話すときにこの記事をたたき台にしたい。はじめてgitに触れる人の理解の助けになれば。

個別のgitコマンドについては、「頻出gitコマンド入門」で紹介しているのでリファレンス的に使ってください。ここでで紹介しているコマンドに関してはさらっと流して、できるだけシンプルに。

Read More »

頻出gitコマンド入門

最近、gitの使い方を人に説明することが多くなってきたので、頻出コマンドの使い方をリファレンス的に纏めておこうと思います。

なお、対象読者はgithubを用いてチーム開発をしているプログラマーです。
一人で開発するのであれば、例えばリモートサーバーへのpushやpullなどは無視してよいでしょう。

応用的なコマンドは分量を考えてまた別の記事にするかもしれません。適当にアップデートしていきます。

Read More »

VagrantのゲストOSから名前解決できない件

昔の記事「Vagrant+Chef-Zero入門」でprovisionを行おうと思い、vagrant upしたところ、次のエラーでプロビジョニングがコケました。

よく見るとinline scriptとchef両方でコケてる

inline script はゲストOSにchefをインストールするスクリプトで、opscode.comからダウンロードしてくるのですが、3行目でこれが失敗しています。
原因はホストアドレスの名前解決ができなかったようですね。

chefがインストールできていないので、chef provisionがコケるのは当然なのですが、14行目でも network is unreachable ということで、ゲストOSから名前解決が正しくできていないために、インターネットに出て行けなかったのではないかと推測できます。

解決策

ゲストOSから名前解決がうまくいかないとき、ホストOSで名前解決するようプロキシする設定にすることが可能なようで、VirtualBoxの NAT Networking settings に詳細が記載されていました。

https://www.virtualbox.org/manual/ch08.html#idp46608649138592

今回はこの設定の中の natdnshostresolver をVagrantfileから有効にします。

vagrant up でVMを立ち上げ直すと、正しく名前解決が行われるようになります。

このオプションを有効化することによる副作用はなさそうなので、配布する場合は付けておいたほうがよさそうです。

所感

この原因が解明できておらず曖昧なのですが、Vagrantを使っているとネットワーク周りの問題にはよく遭遇します。
自分の中でネットワークに関しては知識面において弱点でもあるので、克服できるように精進したいと思います。

余談ではありますが、本記事内や以前の記事で書いた opscode.com は chef.io に引っ越しが行われており、古いドメインでもリダイレクトされますが、DNSルックアップが2度走ることになるので気になる方は新しい方を参照するように修正すると良いでしょう。

git-secretsでAWSの不正利用を防ぐ

最近、アプリケーションなどから利用するAWSの認証情報(credentials)をgithubなどの公開リポジトリに誤ってコミットしてしまい、不正利用され高額な使用料を請求されるケースが増えています。
いくらルートアカウントを無効化してIAMユーザーを使おうが、2段階認証を導入しようが、認証情報をヒューマンミスで公開してしまっては意味がありません。

万が一、認証情報を公開してしまった場合は、一刻も早くAWSの管理コンソールから公開してしまった認証情報のアクセス権限を取り消しましょう。もしそれが会社で使っている認証情報だとしたら本当に1分1秒を争いますので、深夜だろうが構わずにAWSを管理しているエンジニアを電話で叩き起こして助けを求めてください。放置すると高確率で首が飛びます。

こういった大事故を防ぐためにAWSが公開している git-secrets というgitのプラグインがあります。

https://github.com/awslabs/git-secrets

インストールする

つい先月末までは、インストールするためにソースをローカルにクローンしてきた後で make install する必要がありました。しかし、先月の26日にformulaがHomebrewのmasterにマージされ、brew経由でより簡単にインストールできるようになりました。

昔からhomebrewを使っていた人は、formulaの一覧を更新しないとインストールできないため、まずupdateしてからinstallします。

git secrets コマンドが使えるようになっているはずです。

リポジトリへ設定

git-secretsはまだ有効になっていません。

リポジトリ単位で有効化する必要があるので、ここでは適当に新しいリポジトリを作ることにします。

リポジトリの中にcdしたら –install で有効化。

見ての通り、pre-commitをフックして実現しています。

拒否ルールの設定

次にどのルールにマッチしたとき、コミットを拒否するか指定します。AWSの認証情報については、 --register-aws パラメータを使えます。

設定された拒否ルールは、 --list パラメータで確認できます。

上の出力3行目では、大文字英数20文字にマッチして拒否しているようですね。乱暴じゃないかと思いましたが、実際プログラミングをしていて大文字固定で20文字も打ちませんからね。

6,7行目はAWSの公式ドキュメントなどでも使われている、サンプルのアクセスキー/シークレットキー(Allowed patterns for example AWS keys)だそうです。

実際に使ってみる

ちゃんと弾いてくれるか確認してみます。

適当にそれっぽいのを書いて、これでコミット。

弾いてくれました!

まとめ

実際の運用では、認証情報やパスワードなど本当に外部に漏れてマズいものは、環境変数にセットするのが個人的にはオススメです。そもそもファイルに書かない運用であれば、ファイルの取扱い不備でリークする可能性がゼロになり、セキュリティリスクを減らせます。

とはいえ、実情そんなこと言ってられないケースも多いですので、ファイル+.gitignoreで気をつけて運用するのが一般的でしょうか…。万が一のためにAWS内外問わず、トークンごとに権限設定ができるものは必要最小限の付与に留めるようにしましょう。AWSの場合、ルートキーでないと使えないAPIがあったりもするみたいですが……。

今回のgit secretsは他にも、既にインデックスされているファイルの中にキーが混ざっていないかどうかをスキャンしたりすることもできます。詳しく知りたい方は公式のドキュメントをどうぞ。

所感

AWSなんかは凄い勢いで請求額が増えていくサービスが山ほどあります。ルートキーなんかが漏洩したと思うとゾッとしますね……。従量課金制のクラウドサービスを使う際には、そのセキュリティにはより一層の注意を払って取り扱いたいですね。

FT2用インジケーターを作る(C++編)

この記事はPascal編の内容をC++向けに書き換えたものです。

Forex Tester 2で読み込める、一目均衡表のテクニカルインジケーターを描画するDLLを作成することをゴールにします。

Pascal編と同様の部分は省略していますので、先にそちらの記事をお読みなることをお勧めします。

Read More »

FT2用インジケーターを作る(Pascal編)

こんにちは

わたしは為替のバックテストと検証に、ForexTester 2(以下FT2)という有料のソフトウェアを使っていて、
実際のトレードはMetaTrader 4(以下MT4)を使っています。

これらのソフトウェアは、プログラムの知識があれば、テクニカル分析に用いることのできるインジケーターや、自動売買用のプログラム(EA; Expert Advisor)を自作することができます。
MT4の場合は、本体インストール時にコンパイラも同時にインストールされ、プログラミング言語といっても習得が容易なオリジナル言語MQL4でより容易にプログラムすることができ、ソースコードが公開されていることも多いのですが、FT2の場合はC++またはPascalを使って、これらのdllを作る必要があります。

普段Mac使いなこともあって、数年ぶりにこれらの開発環境を整えるときに躓いたことがあったので、備忘録として手順を書き留めようと思います。

ちなみに、言語はPascalでもC++でもどちらでも良いと思います。C++は後で別に記事にするつもりです。プログラミング初学者で、どちらの言語も触れたことがない方であればPascalの方が私は楽だと思います。
ただし、DLLファイルの容量がC++でビルドした方が小さくなります。気になる方はC++が良いかもしれません。

Read More »

バグを減らすためにユニットテストを考える

ユニットテスト基礎

前提として

  • 「バグがある」ことを証明できるが、「バグがない」ことは証明できない
  • バグを限りなくゼロに減らすために有限時間内でチェックを行っている
  • ステートが増える毎にテストケースとテスト時間は指数関数的に増加する
  • ウェブサービスでブラウザを介して行うものは完全なブラックボックステストであるし、仮に誤った出力となるケースを発見しても、そのリクエスト内のどの段階(メソッド)でバグが起きているのか特定することはできない

基礎知識

テストは最低限の品質保証です。

テストを行っていなかったプロジェクトにテストを導入する場合、「この関数の結果は最低限、保証されていなければならない」とする関数を最優先のテスト対象とします。
ただし、テストを実施するためには、テストを行いやすい設計が必要不可欠であるため、既存のコードのままテストを実施しようとは考えない方が良いでしょう。

また、ユニットテストは、リグレッションテスト(デグレードテスト)を行うための最適な方法です。リグレッション(デグレード)というのは、新たに機能を追加したり、既存のコードのバグを修正した際に、新たなバグを生みだしてしまうことです。ユニットテストを正しく行っていれば、常に要求を満たすテストケースによって過去の修正内容も検証され続けることになるためです。

またテストコードを書く習慣のない人が書いたコードは総じてテストしにくいコードを書く傾向にあり、テスト導入を決めたプロジェクトでテストコードに関する知識の無い人にコードを書かせ続けるのはとても非効率です。…それでも、テストコードを書く人が指摘しないといつまでも書けるようにはなりません。

テストコードは誰でも書けるのか

正しいテストコードを書くにはプログラミングの知識だけでなく、テスト工程におけるテストスキルと経験も必須です。

機械的に行うユニットテストなどのソフトウェアテストは、ブラウザを介した出力を人間が目視で行うブラックボックステストと根本的に異なります。たとえば今回取り上げているのはユニットテストですが、その具体的なテストケースには同値分析や境界線分析など多くの手法があり、また適切なテストケースを書くことができないのであれば、テストコードを書かないも同然です。

なにより、実施しようとしているテストの基礎知識がなければ、どの程度テストコード、テストケース、カバレッジを維持すれば十分という判断をすることができないし、そもそもプログラミングの知識がなければテストコードを書くことも出来なければ、テスト対象のコードを読んで適切なテストケースを作ることも不可能です。

ゆえに、テストコードを書くにはテスト対象のコード(つまりビジネスロジック)を書く以上のスキルと経験が必要と言えます。

テストコードを書かないのは悪ではない

ユニットテストはソフトウェアテスト手法の一つですが、これは通常の開発手法(例えばウォーターフォールやアジャイル、スクラム等々)と同様に、適用して効果的なプロジェクトもあれば、むしろ適用した結果マイナスに作用してしまうプロジェクトもあり、すべてのプロジェクトに導入を勧められるものではないことを理解してください。

そのため、事前にユニットテストを導入するのが本当に効果的なのかどうかを検討・判断する必要があります。

ユニットテストが効果的なプロジェクトの条件を次に挙げます。

頻繁にリリースが行われる

例えばリリースが年に数回のように、頻繁にリリースをしない場合、手動テストのコストが相対的に小さくなり、ユニットテストを導入するコストの方が大きくなります。逆にアジャイルで毎日デプロイを繰り返すようなプロジェクトの場合、手動テストだけでは太刀打ちできなくなることでしょう。

長い期間保守される

リリース頻度と同じ考え方ですが、短時間で保守されなくなるプロジェクトでは、トータル的に自動テストが実行される回数が少なくなるため導入コストの方が大きくなります。例えばサービス案を練って試作してみる時のプロトタイプなどに導入するのは不向きということになります。

多くの人数が開発に関わる

例えば1人で開発を継続できる規模のプロジェクトでは、当人がすべてのコード・仕様を把握しているケースが多く、テストコードを導入したとしても成果物の品質に影響を与えないことが多いです。逆に数十人規模の開発チームの場合、一人がすべてのコードを把握するのは不可能でしょうし、初めて触れるコンポーネントの改修を安心して行うことができるようになります。

ただし、頻繁に参加しているメンバーが変動するプロジェクトの場合、テストコードのメンテナンスコストが高まり、テスト自体が破綻することがあるので注意が必要です。

また、ある程度コードの規模が大きくなってきたプロジェクトにおいては、トータルで見たとき「自動テストを導入した後の開発速度」の方が導入前と比べて早いことも多いのですが、その段階以前の小規模なプロジェクトでは、自動テストを導入しない方が開発速度は速くなります。実際のビジネスの世界では品質よりスピードを重視することも多々あるので、開発ステージに応じた選択が必要になります。

「テスト駆動開発」のススメ

テスト駆動開発とは

一般的な開発工程では、機能実装者=その機能のテストコード実装者になります。

ユニットテストは学校のテストに例えると、

  • テストコード=問題(先生が出題する)
  • ビジネスロジック(機能)=解答(生徒が解く)

なので、

  • 「先に答え(機能)を書いてから、問題を出題(テストコードを実装)する」

より、

  • 「先に問題(テストコード)を書いてから、その問題に答える(機能を実装する)」

方が考え方としてはより適切であり、成果物の品質向上を期待できます。

このように、先にテストコードを書いてからビジネスロジックを実装する開発手法をテスト駆動開発(テストファースト)と言います。

テスト駆動開発には、テスト対象のコードを書く前の時点でその全体像を頭の中で設計する必要があり、プログラム初学者が習得するのは困難です。

テスト駆動開発 は開発が遅くなる?

テスト駆動開発を実施すると生産性が下がると主張する人も多いのですが、実際は正しくテストが行えていればトータルで見た生産性は上がります。

何故かというと、実際にコードを書くエンジニアでないと分からない感覚かもしれませんが、エンジニアが「実際にコードを書く時間」より、「処理を頭の中で考えて設計する時間」と、「書いた後の動作チェックの時間」の方が長くなりがちです(そうでないケースを私は知りません)。

特に新人の頃は設計も未熟であり、十分に頭の中でシュミレーションできず、いきなり手を動かしてコードを書く作業に入るために無駄なコードが増えがちです。
しかしその繰り返しによって知見が十分に溜まることにより、手を動かす前に今から書こうとするプログラムの全体像を自然とイメージできるようになります。
経験を積み重ねた熟練者はコードの実行結果を頭の中でシュミレーションできるので、無駄なプログラミングを初めからしなくなります。

従って、テスト駆動開発の導入によりテストコードを先に書くことによって、開発工程で一番時間のかかる「脳内設計工程」と「動作チェック工程」が一体化し生産性が向上します。

結論

何が言いたいのか分からなくなってきました。ここまで書くのに疲れました。また考えておきます。

所感

ここまで語れるほどユニットテストの経験が長いわけではない…はずが、いつの間にか書けるくらいの知識量になっていました。初学者だった頃は「テスト難しそう…書くと遅くなるし要らないや」なんてよく思っていました。懐かしいです。

ボリンジャーバンドを使ったFXトレード考察

最近、過去の値動きを使ったトレーディング検証をひたすらやっているのですが、とても有意な検証ができたので少しご紹介。

画像がない不親切な記事ですが、また気が向いた時にチャートの画像も持ってきます。(→実例書きました!)

通貨ペアはUSD/JPY、データは2013年の値動きで検証しましたが、2015年相場や他の通貨ペアでも勝てています。

 

前提

検証通貨ペア: USDJPY
Lot数: 固定 5Lot (ナンピンなし・両建て無し。一度に1つのポジションのみ。)
使うテクニカルチャート: ボリンジャーバンド1σ/2σ/3σ, 単純移動平均(10/20), 一目均衡表, MACD

実際にはRSIやEnvelopeなども使っていますが、最低限上の4種類だけで大丈夫です。期間はすべてチャートツールのデフォルトで構わないでしょう。

 

エントリーとエグジットのルール

エントリーはシンプルです。いずれもトレンドフォローで、逆張りはしません。これらのルールはいずれも足の確定ベースです。

 

ルール 1「ある一定のレンジ相場が続いたのち、ボリンジャーバンドの1σをはみ出してレンジ相場の高値・安値をブレイクした」

ルール 2「ルール1でエントリーしてエグジットした、またはルール1でエントリーしなかったものの大きなトレンドが出現した際、10本または20本の移動平均線付近で反発した場合」

 

ただし、より精度を高めるために次の執行条件を確認します。

  • 5分足なら1時間足でトレンドが同じ方向を向いているか、もしくはレンジである
    → 調整局面によるダマシを排除します
  • ブレイクした足がボリンジャーバンドの3σに到達していない
    → 3σを超えて伸びた足は既に行き過ぎであることが多く、またロスカットまでの値幅が大きいです
  • エントリー方向に向かって10〜20pips以内の位置に抵抗線がない
    → 例えば意識されやすい移動平均線や一目均衡表の雲、直近の抵抗線があると伸びにくいのでエントリーしません。これは少し長い時間足のチャートでも確認します
  • エントリー後30分の間に重要な指標発表がない
    → 指標発表には賭けない。クロス円の場合は米国指標も大切
  • ボリンジャーバンド±2σの幅が広がりつつある、またはトレンド方向に並行である (ルール2のみ)
    → 狭くなってきている場合はトレンドの終わりが近く、ロスカットになりがちです

これらのルールは、ベースとなる前述のエントリーサインが出現したとき、そのサインを執行するか否かの判断に用いるものです。勝率を向上させるためにはこの判断が鍵で、損益に直結するでしょう。これらの条件は一見複雑なようにも見えますが、要は「ダマシの可能性が高いか、またはトレンド方向に障壁がありトレンドが発生しても継続しにくい」時にエントリーしない、執行時のフィルタリングルールと言えます。上記の執行条件以外にも、個人的にトレンドが伸びなさそうだな、と不安に思う点があればエントリーを見送った方が賢明でしょう。

また、ルール2はルール1でトレンドの当初にエントリーできなかったときのエントリールールです。ルール1でポジションを持っているときに2のシグナルが出てもスルーです。買い増し、売り増しはしないスタイルです。

 

損切りのエグジットは、終値ベースでレンジ相場の高値安値を割り込んで戻ったときです。大体5〜10pipsくらいの損切りが多いです。

 

利確のエグジットが難しいのですが、大体このような考えでエグジットしています。

  • ボリンジャーバンドの3σを超えたとき
  • 上下どちらかのボリンジャーバンドの傾きが緩やかになるか、もしくは反転したとき
  • ボリンジャーバンドの2σでバンドウォークしていたところ、内側に乖離してしまったとき
  • 2本続けてナローレンジ(十字架)が出現したとき

上記のいずれかで利確せず、見送った場合は10本の移動平均線まで戻ってきたときを利確ラインにしています。移動平均線付近まで戻ってきてしまった場合は反発して値幅を更に取れることもあるので、線を割り込むまではあえてエグジットしません。

 

実例

昨日(2015年1月6日夜)、実際に私がトレードしたチャート(5分足)です。

紫で囲った部分がレンジで方向感がなく、この時点でブレイクに備えて待機していたところ、22:25の足でレンジの高値、安値を終値ベースで大きく上にブレイクしました。

既に3σを超えており、高値警戒感はあったもののブレイクした高値までの距離が6pipsと許容範囲内だったため、レンジブレイクした足が確定した次の足の始値118.520円で買いエントリーしました。

その後堅調に推移しましたが、22:40に続いて22:50の足で同じような長さで上ひげが出ていることから上値が重いと判断、その足の次の始値①、118.648円で+13pipsの利益確定を行いました。

その後は、利確を行った足の終値でもう一段の高値118.716円を付けましたが、次の足からは陰線が続き、3本目の陰線②で10本の赤い移動平均線を割り込みました。

利確のルールでは、最終的に陰線②で移動平均線を割った足が確定した次の足(陽線③)の始値でエグジットでしたので、利益は随分小さくなりますが最悪でもここでエグジットしなくてはいけません。

また、積極的な利食いを行うのであれば黄色のボリンジャーバンド2σから乖離したのが確定した次の足(②)の始値でエグジットすることも可能です。ただし、この位置はちょうど移動平均線上であるため、反発を期待した場合は③でのエグジットになってしまったと思われます。

  • エントリー: 118.520
  • 利益確定① 118.648 (+12.8pips)
  • 利益確定②: 118.600 (+8pips)
  • 利益確定③: 118.543 (+2.3pips)
  • ロスカットライン: 118.460 (-6pips)

結果として、このトレードでは①の位置で利益を確定するのが最適ということでした。今回は大きなトレンドではありませんでしたね。

瞬間的には.716を付け、ここで利確できれば+19.6pipsの利益となりましたが、この高値を記録した足では2σでのバンドウォーク中ですので利益確定は難しかったと思われます。これを取り逃がしたと悲しむ必要はないでしょう。

 

考察

前述のように、今回試している手法は明確なシグナルはなく、経験則を交えた裁量トレードなので、万人が同じような再現性を持つ手法ではありません。それでも、初心者の方でも比較的容易に利益が出しやすいのではないかと思っています。

この手法でトレードする場合の時間帯は日本時間で夕方〜深夜の欧州時間・NY時間が良いと思います。大きなトレンドが出やすいからです。また通貨ペアに関しては、ドル円よりもユーロドル、ユーロ円、ポンド円のほうがトレンドが継続しやすい傾向にあり利益も出しやすいと思います。

今回、ドル円の記録で1週間で100万円→270万円まで増やすことができました(下の画像)。勝率は平均すると5割程度ですが、トレンドにうまく乗れると1度のトレードで30〜100pips、最大で150pips取れたこともあります。損切りまでの距離が近いため勝率は低くなりがちなのですが、少しでも勝率を上げるために前述の通りエントリーサインが出た後で執行するか否かをフィルタリングしています。

CX0Yd6NUsAAw6SB

 

大体リスク・リワード(損失平均・利益平均)が1:2の比率であれば、勝率が30%を割っていたとしてもプラス収支にできることが多いです。もしリスクリワードが1:1であれば勝率50%でもスプレッドやスワップでマイナスになります。リスクリワード2:1、所謂スキャルピングに多い手法ですが、これだと勝率は6〜8割必要になります。利益が小さいコツコツトレードがいかに相当難しいのが分かるのではないでしょうか。

私は昔スキャルピングが好きでよくやっていたのですが、コツコツ小さな利益を重ねていても、数回に一度大きく負けることがあり、トータルでは全然勝つことができませんでした。所謂「コツコツ・ドカン」状態です。今回試しているトレードでは、損はコツコツ、利益はドカンと大きく取れるので、私が負けていた手法を本当に逆にしたような理想的なプロフィットチャートが出来上がります。

 

課題

一番は、レンジ相場では利益は出ない、トレンドありきのトレードスタイルということを理解しなくてはいけません。エントリーしたもののトレンドの発生ではなく、単にレンジ相場の変動幅が広がっただけというケースが多く、その場合は戻ってきてしまいますので損切りになることがとても多いです。この手法の一番の問題はその点で、いわば「レンジ」か「トレンド」か、の判断精度向上にかかっています。引き続き検証していこうと思います。

 

参考までに。

 

雑感

本業の仕事が始まり忙しくなりました。もうお正月気分も完全に抜けて、いつも通りって感じですね。Twitterで今月の抱負ということで勉強する誓いを立てたのですが、意外と続いていて良いスタートを切れました。がんばっていきます。