【PHP×MySQL】サイコロジカルライン出力プラグラムを作成しました

サイコロジカルラインを作りましたブログ

テクニカル指標の1つ、サイコロジカルラインを出力するプログラムを作成しました。大した内容ではないようですが、備忘録として残しておきます。

サイコロジカルラインとは

サイコロジカルラインは「投資家の心理」を数値化した指標で、計算式も簡単でわかりやすい指標です。
主に、相場の強弱の見極めや、買い場、売り場を判断するのに有効的です。

マネックス証券ウェブサイト

前日より上昇した場合を勝ち、下落した場合を負けとして勝った割合を0~100%の間で表現します。よく使われるのは12日間なので本ブログでも12日間を使用しました。

 12日間の内の上昇した日数 ÷ 12 × 100[%]

サイコロジカルラインについての詳細は以下からご覧ください。

オシレーター分析/サイコロジカルライン | はじめてのテクニカル分析 / マネックス証券
サイコロジカルラインは「投資家の心理」を数値化した指標で、相場の強弱の見極めや、買い場、売り場を判断するのに有効的です。RSIやストキャスティクスほど有名ではありませんが、計算式も簡単でわかり易いため、好む投資家もいます。

%の遷移をグラフで表す場合が多いですが、今回は勝利を白丸、敗北を黒丸で表して数珠つなぎのように見せるやり方を採用しました。

前日比変わらずは、負けとしたり、0.5ずつとしたりとする方法があるようですが、本ブログでは前日と同じステータスとなると定義しています。

使用したテーブル

以前の記事で作成した日本株投資成績のテーブルを利用しています。今回メインで使用しているのは連騰、続落の連続日数を入力しているcontinuous_daysのカラムになります。

テーブルの内容について詳しくは以下の記事をご覧ください。

作成したコード

では早速作成したコードをお見せします。コード内にコメントを結構入れてますのでポイントのみ補足します。

PHP

<?php

//offsetの値を取得(閲覧中の記事が最新から何番目か)
$post_name = substr($_SERVER['REQUEST_URI'], 14, 15);//①
$offset = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->stock_jp WHERE post_name >= '$post_name' ORDER BY post_name DESC") - 1;//②

//テーブルにレコードが追加されていない場合は何も生成しない
if ($offset == -1) {
  echo '';
} else {
      //offsetした位置から12日ぶんのレコードを抽出
      $results = $wpdb->get_results("SELECT * FROM $wpdb->stock_jp ORDER BY post_name DESC LIMIT 12 OFFSET $offset");

      //連騰、続落の連続日を取得(小数点以下とそれ以外を分けて$numberに格納)
      $continuous_days = $results[0]->continuous_days;
      $number = explode('.', $continuous_days);//③

      $chart = '';
      $count_win = 0;

      foreach ( $results as $value ) {
        //白丸と黒丸を出力
        if ($value->continuous_days > 0) {
          $chart = '<i class="fa fa-circle-o" aria-hidden="true"></i>' . $chart;
          //勝ち数をカウント
          $count_win++;
        } else {
          $chart = '<i class="fa fa-circle" aria-hidden="true"></i>' . $chart;
        }
      }

    $count_lose = 12 - $count_win;
    $ratio = round($count_win / 12 * 100, 2);

    $code = '<strong>サイコロ</strong> ';

    //勝敗が連続している場合はバッチを追加
    if ($number[0] >= 2) {
      $code = $code . '<span class="badge-win">' .  $number[0] . '連勝中</span>';
    }else if ($number[0] <= -2) {
      $code = $code . '<span class="badge-lose">' . abs($number[0]) . '連負中</span>';
    }

    //引き分けが含まれる場合は注記を追加
    if ($number[1] != 0) {//④
      $code = $code . '<small> ※引き分け含む</small>';
    }

    //表示内容をすべて結合
    $code = '<p>' . $code . '<br>' .$count_win . '勝' . $count_lose . '負 <span id="psyind">' . $ratio . '</span>% ' . $chart . '</p>';//⑤

    //htmlコードを生成
    echo $code;
}
?>

以下補足です。

  1. 現在閲覧中のURLからpost_nameに当たる「stock-jp-XXXXXX」の部分を抽出しています
  2. 「post_name >= ‘$post_name’」の条件に引っかかるレコード数を取得して最新から数えて何番目の記事かを取得しています
  3. 引き分けを挟んでいることがわかるように引き分けの場合はcontinuous_daysに「0.01をプラス」もしくは「0.01をマイナス」するように変更しました。
  4. 小数点以下が0でなければ引き分けを挟んでますので「引き分けを含む」という注記を追加しています。

引き分けが表現できるようにするためにcontinuous_daysのデータ型は「int(2)」から「float(4,2)」に変更しました。
「float(4,2)」は小数点以下が2桁、全体で4桁を表しています。

CSS

連勝、連敗数にclassを付与しさました。cocoonのバッチと同じデザインで背景色を変えています。

.badge-win {
  color: #fff;
  padding: 1px 5px 0;
  border-radius: 2px;
  font-size: 12px;
  background-color: #009933;
}

.badge-lose {
  color: #fff;
  padding: 1px 5px 0;
  border-radius: 2px;
  font-size: 12px;
  background-color: #ff333a;
}

ショートコードに登録

毎度おなじみのショートコード登録です。今回も上記PHPを別ファイルとして呼び出す形で登録しました。

One More Thing

今回のサイコロジカルラインですが、一度PHPでHTMLコードを作成したらそのコードはテーブルのデータに不備がない限りはずっと変わりません。なぜなら参照しているデータは前日比の増減だけであり、記事のタイトルなど将来的にリライトを行う可能性がある項目が含まれていないためです。

同じHTMLコードを生成するためにアクセス毎にPHPで複雑な処理を回すのはもったいないと感じ、1回目のアクセス時のみHTMLコードを作成し、2回目以降は1回目に作成したコードを使う方式に変更しました。

<?php

//offsetの値を取得(閲覧中の記事が最新から何番目か)
$post_name = substr($_SERVER['REQUEST_URI'], 14, 15);
$offset = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->stock_jp WHERE post_name >= '$post_name' ORDER BY post_name DESC") - 1;

//テーブルにレコードが追加されていない場合は何も生成しない
if ($offset == -1) {
    echo '';
} else {
    //初回のみhtmlコードを作成(2回目以降はpsy_ind内のコードを出力)
    if ( $code = $wpdb->get_var("SELECT psy_ind FROM $wpdb->stock_jp WHERE post_name = '$post_name'")){//①
        echo $code;
    } else {
            //offsetした位置から12日ぶんのレコードを抽出
            $results = $wpdb->get_results("SELECT * FROM $wpdb->stock_jp ORDER BY post_name DESC LIMIT 12 OFFSET $offset");

            //連騰、続落の連続日を取得(小数点以下とそれ以外を分けて$numberに格納)
            $continuous_days = $results[0]->continuous_days;
            $number = explode('.', $continuous_days);

            $chart = '';
            $count_win = 0;

            foreach ( $results as $value ) {
                //白丸と黒丸を出力
                if ($value->continuous_days > 0) {
                    $chart = '<i class="fa fa-circle-o" aria-hidden="true"></i>' . $chart;
                    //勝ち数をカウント
                    $count_win++;
                } else {
                    $chart = '<i class="fa fa-circle" aria-hidden="true"></i>' . $chart;
                }
            }

        $count_lose = 12 - $count_win;
        $ratio = round($count_win / 12 * 100,2);

        $code = '<strong>サイコロ</strong> ';

        //勝敗が連続している場合はバッチを追加
        if ($number[0] >= 2) {
            $code = $code . '<span class="badge-win">' .  $number[0] . '連勝中</span>';
        }else if ($number[0] <= -2) {
            $code = $code . '<span class="badge-lose">' . abs($number[0]) . '連負中</span>';
        }

        //引き分けが含まれる場合は注記を追加
        if ($number[1] != 0) {
            $code = $code . '<small> ※引き分け含む</small>';
        }

        //表示内容をすべて結合
        $code = '<p>' . $code . '<br>' .$count_win . '勝' . $count_lose . '負 <span id="psyind">' . $ratio . '</span>% ' . $chart . '</p>';

        //htmlコードを生成
        echo $code;

        //psy_indにhtmlコードを書き込み
        $wpdb->update($wpdb->stock_jp, array('psy_ind' => $code), array('post_name' => $post_name));//②
    }
}
?>

以下補足です。

  1. テーブルに新しく「psy_ind」(varchar型)という列を作成しました。デフォルト値はNULLなので、NULLでなければ即格納してあるデータを返すようにしています。
  2. 最後に$codeの内容を「psy_ind」に書き込む処理を追加しています。

厳密な時間の比較はしていませんが、体感的には早くなったと感じています。

参考サイト

あとがき

作るものがちょっとしたものということもあってか詰まることなく作成ができました。MySQLで引っ張ってくるデータのテーブルが作れていれば、あとは手を動かすだけというイメージです。(もちろんPHPの構文など調べながらですが…)

One More Thingまで進めたことを個人的に満足しています(これを自己満足と言います)。k今後は記事内で持ち株全体の連勝数、連敗数が分かりやすくなるので楽しみです。

コメント

タイトルとURLをコピーしました