【自動売買】【PHP】テクニカル分析を実装する方法【MACD編】
以前公開した記事「【BTC/JPY-FX】【PHP】bitFlyerAPIとinvestingのテクニカルデータを使った自動売買システムの構築」にてinvestingのテクニカルデータを解析して自動売買を行うプログラムを公開していますが、
人によっては自分でテクニカル分析のプログラムを組んで売買ポイントを決めたいと考える方もいらっしゃると思います。
今回はそんな方に向けた「PHPでテクニカル分析を簡単に実装する方法」について紹介させていただきます。
1 . 準備
まず今回の情報を使うためにはPHP 5.3〜5.6(PHP7系は未対応)が必要になります。
また、PECL(PHPのC言語ライブラリインストーラー)が必要です。
composerには未対応です。
PECLのインストールがわからない方は以下のブログを参考にしてください。
【Windows】
http://emija.hatenablog.com/entry/2013/12/11/121246
【mac】
http://d.hatena.ne.jp/As_hsp/20120422/1335122128
【Linux】
PECLのインストールができたら、PECLインストーラを利用または以下のサイトから直接ダウンロードにて
https://pecl.php.net/package/trader
「trader」を入手してPHP環境に読み込みを行います。
環境に正しくtraderが反映されているか確認するにはphpinfoを実行して、traderが追加モジュールにtraderが存在するか確認してください。
http://www.1x1.jp/blog/2011/05/basic_of_php_phpinfo.html
ここまでできたらphp traderをphpプログラムから使用する準備ができました。
次にphp traderについて説明させていただきます。
2 . PHP TRADERとは
株、FX、仮想通貨等のチャートにおいて、トレーダーが売買の判断をするために様々なテクニカル分析の手法が存在しますが、
自動売買などでこれを実装するためにはそれぞれの手法で複雑な計算をする必要があります。
しかしphp traderを利用することで、複雑な計算ロジックを組むことなく、必要なパラメータを関数に渡すことで分析結果を提供してくれます。
また各関数のパラメータに指定する情報は基本的に取引所などが提供するAPIで取得できるロウソク足の情報のみであるため、
ロウソク足の情報が取ることができれば、php traderを使用して様々なテクニカル分析が行えます。
取れるテクニカル情報の例としましては移動平均線やMACD、RSI、ボリンジャーバンド、ストキャスティクスやWilliams' %Rのオシレータ等の有名なテクニカル指標からマイナーなものまで全163の指標が取得できます。
php trader リファレンス:http://php.net/manual/ja/ref.trader.php
3 . 具体的にMACDの情報をプログラムで取得してみる
それでは具体的にテクニカル分析のサンプルとしてMACDを取得するプログラムを作成してみます。
MACDについては以下のサイトを参考にしてください。
https://www.sevendata.co.jp/shihyou/technical/macd.html
例では https://note.mu/mochobi/n/nfa3b0cd1ed65
をカスタマイズすること前提にbitFlyerでMACDを分析をする想定として作成します。
まず、bitFlyerのロウソク足の情報を取得するにはcryptowatchのOHLCのAPIを利用します。
https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc?periods=86400
上記のURLを実際にブラウザで叩いてみると、日足のロウソク足のデータが取得できます。
periodsは分単位で指定しますが、86400とすることで直近500日分の日足ロウソクが取得できます。
その他の単位で取得したい場合は
https://cryptowatch.jp/docs/api#ohlc
こちらにサポートするperiodsが全て記載されています。
$ch = curl_init();
// period = 60:1分, 300:5分, 900:15分, 1800:30分, 3600:1時間,
// 18000:5時間, 86400:日足, week:週足, month:月足
$period = 86400;
$url = "https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc?periods=$period";
// curlに各種オプションを設定
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_URL => $url,
CURLOPT_FRESH_CONNECT => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
]);
// curl実行
$ret = curl_exec($ch);
$ret = json_decode($ret, true);
curl_close($ch);
header('content-type: application/json; charset=utf-8');
echo json_encode($ret, JSON_PRETTY_PRINT);
こうすることで日足のロウソク足500件分の情報が取得できるはずです。
実際に実行させてみると、"86400"という添字の配下に
6データ1セットの情報が500件表示されます。
{
"result": {
"86400": [
[
1478563200,
74639,
74650,
73229,
74119,
37668.52
],
[
1478649600,
74154,
75450,
73939,
74834,
39817.887
],
.......
この1セットが1本のロウソク足の情報になります。
セット内の6データの情報はそれぞれ
・ロウソクの最終日時
・ロウソクの最初の価格
・ロウソク内の最高価格
・ロウソク内の最低価格
・ロウソクの最後の価格
・ロウソク内で取引されたサイズ(ボリューム)
となっています。
また、最終日時をみると分かりますが、
最初のデータが最も古いロウソクの情報で、最後のデータが直近のロウソク足の情報となります。
ここまで取れたら今度はtraderのtrader_macd関数を利用してMACDを取得してみます。
trader_macdに必要なパラメータは
trader_macd ( array $real [, int $fastPeriod [, int $slowPeriod [, int $signalPeriod ]]] )
となっています。[]で表記されているパラメータは省略可能です。
パラメータのrealにはロウソク足の最終価格の配列を設定します。fastPeriodとslowPeriodは基準線、相対線に設定する日数なので、
investing.com似合わせて12日、26日とし、signalPeriodに9日を設定します。
先ほど作ったプログラムの
$ret = json_decode($ret, true);
の下の行に以下のロジックを追加します。
// ロウソク足の情報のみ取得
$chart = $ret["result"]["86400"];
// 最終価格のみの配列を作成
$lastPrice = array_column($chart, 1);
// MACD計算
$ret = trader_macd($lastPrice, 12, 26, 9);
これを実行するとtrader_macdの実行の結果3つの配列の中にそれぞれmacdの分析結果のデータが格納されてきます。
それぞれの配列は
[MACD, SIGNAL, Divergence]
となっています。このままでは見辛いのでMACD, SIGNAL, Divergenceを同じ時系列で配列にするため、
$ret = trader_macd($lastPrice, 12, 26);
の下に以下のロジックを追加します。
$macd = array();
foreach ($ret[0] as $k => $v) {
$tmp = array();
$tmp["MACD"] = $v;
if(isset($ret[1][$k])) $tmp["SIGNAL"] = $ret[1][$k];
if(isset($ret[2][$k])) $tmp["Divergence"] = $ret[2][$k];
$macd[] = $tmp;
}
こうすることで同じ時系列のMACDの情報(MACD, SIGNAL, Divergence)がまとまります。
配列の数がロウソクの数(500件)より少なくなりますが、古いデータのMACDは計算できない(さらに古いデータがないと計算できない)ため、
私が実行した結果、"497"がmacdの配列の最後の添字となりましたが、こちらを最新のMACD情報として分析に使用すると良いです。
495: {
"MACD": -61455.244,
"SIGNAL": -76617.231,
"Divergence": 15161.987
},
496: {
"MACD": -70120.283,
"SIGNAL": -84542.427,
"Divergence": 14422.143
},
497: {
"MACD": -76617.231,
"SIGNAL": -87418.869,
"Divergence": 10801.638
}
具体的なMACDの利用方法としてはデッドクロス、ゴールデンクロスを見るのが一般的ですが、
取得してきたデータの直近でデッドクロス、ゴールデンクロスが発生したかどうかを判別するには以下のロジックで対応します。
先ほどのforeach文の最終行の後に追加してください。
// 直近のMACD
$new_macd = $macd[count($macd) -1];
// 一個前のMACD
$before_macd = $macd[count($macd) -2];
// MACD判定結果
$result = "none";
// デッドクロス
if($before_macd["Divergence"] < 0 && $new_macd["Divergence"] > 0) $result = "golden";
if($before_macd["Divergence"] > 0 && $new_macd["Divergence"] < 0) $result = "dead";
MACDの判断の仕方として
・ゴールデンクロスはMACDがSIGNALを下から抜いた時
・デッドクロスはMACDがSIGNALを上から抜いた時
となります。
今回のプログラムでDivergenceにはMACDとSIGNALの乖離値が格納されてます。
Divergenceがプラス値の場合はMACDがSIGNALより上のラインにいる時で、
マイナス値の場合はMACDがSIGNALより下のラインのいる場合に格納される値となります。
つまり、
・ゴールデンクロスは[一個前のDivergenceの値がマイナス]かつ[直近のDivergenceの値がプラス]
・デッドクロスは[一個前のDivergenceの値がプラス]かつ[直近のDivergenceの値がマイナス]
となるため、上のようなロジックで判断が可能となっています。
この結果、resultの変数にはnone, goleden, deadの判定結果が入るようにしています。
これを関数化してgoldenの場合買い注文、deadの場合に売り注文をすれば
MACDの分析に従った自動売買の仕組みが作れるということです。
4 . 最後に
https://note.mu/mochobi/n/nfa3b0cd1ed65
こちらを購買いただいた方のために、investing.comから独自のMACDに売買ポイントを切り替えるための関数を用意いたします。
function getMACDAnalysis() {
$ch = curl_init();
// period = 60:1分, 300:5分, 900:15分, 1800:30分, 3600:1時間,
// 18000:5時間, 86400:日足, week:週足, month:月足
$period = 86400;
$url = "https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc?periods=$period";
// curlに各種オプションを設定
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_URL => $url,
CURLOPT_FRESH_CONNECT => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
]);
// curl実行
$ret = curl_exec($ch);
// phpの配列に変換
$ret = json_decode($ret, true);
// ロウソク足の情報のみ取得
$chart = $ret["result"]["86400"];
// 最終価格のみの配列を作成
$lastPrice = array_column($chart, 1);
// MACD計算
$ret = trader_macd($lastPrice, 12, 26, 9);
$macd = array();
foreach ($ret[0] as $k => $v) {
$tmp = array();
$tmp["MACD"] = $v;
if(isset($ret[1][$k])) $tmp["SIGNAL"] = $ret[1][$k];
if(isset($ret[2][$k])) $tmp["Divergence"] = $ret[2][$k];
$macd[] = $tmp;
}
// 直近のMACD
$new_macd = $macd[count($macd) -1];
// 一個前のMACD
$before_macd = $macd[count($macd) -2];
// MACD判定結果
$result = "none";
// デッドクロス
if($before_macd["Divergence"] < 0 && $new_macd["Divergence"] > 0) $result = "ask";
if($before_macd["Divergence"] > 0 && $new_macd["Divergence"] < 0) $result = "bid";
curl_close($ch);
return $result;
}
こちらを
https://note.mu/mochobi/n/nfa3b0cd1ed65
のプログラムの一番最後に差し込み、
$bidask = parseBidAsk($html);
の部分をコメントアウトし、
$bidask = getMACDAnalysis();
とすることでMACDの分析に合わせて自動売買が実行できるはずです。
気が向いたらMACD以外の分析についても載せようと思います。
最後までお読みいただきありがとうございました。