Google App Script 投資 自動化

【GAS】約定内容をGoogleカレンダーに登録

はじめに

楽天証券には、米国株式の注文が約定するとメールで通知してくれる約定通知サービスがあります。このサービスで受信したメールの内容を解析し、Google Apps Scriptを使ってGoogleカレンダーに自動登録する仕組みを紹介します。

Google App Scriptについては以下の記事を参照ください。

ここで紹介する内容は、以下の条件を満たす方が対象となります。

対象読者

  • 楽天証券の口座を保有している
  • 楽天証券の米国株式約定通知メール設定において「配信希望」としている
  • 楽天証券からの配信メールにGmailを指定している
  • 米国株式約定内容をGoogleカレンダーに自動登録させたい

楽天証券の米国株式約定通知メール設定は、ログインしてから以下の画面で行うことができます。

  • マイメニュー
    • メールサービス
      • 約定通知メール
        • 米国株式(「詳細通知」を選択)

米国株式の約定通知は、「簡易通知」ではなく、「詳細通知」を選択してください。

詳細は、楽天証券の以下のサイトを確認ください。

約定内容をGoogleカレンダーに自動登録する

ほとんどの処理はこれまで公開したカレンダー登録と同様です。

主な違いは以下の3点です。

  • メール検索文字は、楽天証券からの約定通知を指定
  • メール本文内容解析
  • カレンダーに登録する文字は「約定(銘柄コード)xx株」です

未処理メールの抽出

楽天証券からの米国株式の約定通知メールを抽出します。

メールの抽出条件の構文は、Gmailの抽出条件に設定できる構文と同じです。

// 処理済み後に付けるラベル名(ラベルが存在しなければ自動的に作られる)
var LABEL = '自動処理済';

// GMail検索文字列(楽天証券からの米国株式の約定通知メールを抽出)
var SEARCH_QUERY = 'is:unread -label:' + LABEL + ' from:tradesys@rakuten-sec.co.jp subject:米国株式の注文が約定しました';

約定内容のカレンダー登録処理

楽天証券の約定通知(詳細版)は、以下の形式でメールが送られ来ます。

ここから、Googleカレンダーに登録するために、以下の項目を抽出します。

  • 銘柄コード
  • 約定日時
  • 約定数量

米国株式 約定通知メール


米国株式の注文が約定しました。

注文番号:<注文番号>
銘柄名(銘柄コード):<銘柄名>(<銘柄コード>)
口座・売買:<口座区分>・<売買>
決済方法:<決済通貨>
約定単価:<約定単価>米ドル
約定数量:<約定株数>株(口)
約定日時:<約定日時>

約定は一部約定の場合があります。
詳細は約定照会画面でご確認ください。

■米国株式取引の約定照会
<PCウェブ>
ウェブログイン後、「注文」→「米国株式」→「注文照会・訂正・取消」

<マーケットスピード>
ログイン後、「注文約定」→「米国株式」→「約定照会」

■本メールの設定の確認・変更(配信・停止)
ウェブログイン後 「設定・変更」→「メールサービス」→「約定通知メール」からお手続きください。
http://www.rakuten-sec.co.jp/cgi-bin/CTS/Direct_Login.cgi?homeid=USER&type=account&sub_type=&local=acc_mail_select&eventType=init

このメールについてのご質問等は、楽天証券カスタマーサービスセンターまでお気軽にお問い合わせください。
楽天証券カスタマーサービスセンター
フリーダイヤル:0120-41-1004
携帯電話からは:0570-07-1004 または03-6739-3333 (通話料有料)
https://www.rakuten-sec.co.jp/web/support/
楽天証券株式会社

メインの処理は以下の通りとなります。

// 検索文字列
var CUT_START = '注文番号';
var CUT_END = '約定は一部約定の場合があります。';

function registStockContractInfoToCalendar() {

  // デフォルトカレンダーを取得
  var calendar = CalendarApp.getDefaultCalendar();

  var threads = GmailApp.search(SEARCH_QUERY, 0, 1);
  if (threads.length === 0) {
    Logger.log("メールが見つかりません");
    return;
  }

  for(var k in threads){
    var thread = threads[k]
    var messages = thread.getMessages();
    for (var j in messages){
      var message = messages[j];
      var body = message.getPlainBody();    // HtmlメールからPlain textの本文を取得する
      var cutting = false;
      var ticker = null;
      var amount = null;
      var startTime = null;
      var endTime = null;
      var contents = '';

      // 楽天証券からの約定メールの内容確認
      var rows = body.split("\n");
      for (var i in rows) {
        var row = rows[i];

        if(row.indexOf(CUT_START) >= 0){
          cutting = true;
        }

        if(cutting){
          if(row.indexOf(CUT_END) >= 0){
            cutting = false;
          }
          else{
            contents += row + '\n';
            if(row.indexOf('銘柄名(銘柄コード):') >= 0){
              ticker = row.match(/([A-Z]*)/);
            }
            else if(row.indexOf('約定数量:') >= 0){
              amount = row.match(/\d{1,2}/);
            }
            else if(row.indexOf('約定日時:') >= 0){
              tmp = row.match(/\d{4}\/\d{1,2}\/\d{1,2} \d{1,2}:\d{1,2}/)
              Logger.log(tmp[0]);
              startTime = new Date(tmp[0]);
              endTime = new Date(startTime.getTime() + 10 * 60000); // 終了時刻取得
            }
          }
        }
      }
      Logger.log('ticker:' + ticker);
      Logger.log('amount:' + amount);
      Logger.log('startTime:' + startTime);
      Logger.log('endTime:' + endTime);

      // Googleカレンダーに登録
      if(ticker && amount && startTime && endTime){
        var title = '約定' + ticker + amount + '株'; 
        Logger.log(title);
        Logger.log(contents);
        if(checkExist(calendar, startTime, endTime, title) == false){
          var options = {
            description : contents
          }
          var event = calendar.createEvent(title, startTime, endTime, options);
          event.setColor(CalendarApp.EventColor.GREEN);
          event.removeAllReminders();   // 結果なので通知は無し
        }
      }

      // 処理済みメールとしてラベルを付ける
      putLabel(thread); 
    }
  }
}

条件に合致したメールを抽出し、CUT_STARTからCUT_ENDまでをGoogleカレンダーのメモに登録すると共に、銘柄名、約定数量、約定日時を抽出してイベントのタイトルを作っています。

カレンダーに登録する日時は、開始時間を約定日時とし、終了時間を約定日時+10分後としています。

登録済みのカレンダーイベントがあるかどうかのチェック関数checkExist()のコードは以下の通りです。

/*
 * 登録済みのカレンダー情報があるかチェック
 * イベントのタイトル、開始時刻、終了時刻に同じものがある場合は登録済みとする
 */
function checkExist(calendar, registStart, registEnd, registTitle){

  // イベントリスト取得
  var events = calendar.getEvents(registStart, registEnd);
  for(const event of events){
    var title = event.getTitle();
    //Logger.log('title:' + title);
    if(title.indexOf(registTitle) >= 0){
      return true;    // イベント登録済み
    }
  }
  // イベント未登録
  return false;
}

処理済みメールとしてラベルを付ける処理putLabel()については以下の通りです。

/*
 * 処理済みとしてスレッドにラベルを付ける
 * 
 * LABELで指定されるラベルが存在しない場合は作成する
 */
function putLabel(thread){
  var label = GmailApp.getUserLabelByName(LABEL);
  if(label){
    thread.addLabel(label);
    Logger.log('既存ラベル使用');
  }
  else{
    var newlabel = GmailApp.createLabel(LABEL);
    thread.addLabel(newlabel);
    Logger.log('新規ラベル追加');
  }
}

定期実行

上記コードを自動実行するように設定します。

以下に示すトリガーの設定画面において、「トリガーを追加」ボタンを押します。

続いて、実行する関数に「registStockContractInfoToCalendar」を設定し、5分おきに実行する設定にします。

1分おきの実行でも良いですが、それほど忙しく動く必要はないので5分おきで充分です。

最後に、「保存」ボタンを押してトリガーを登録します。

実行結果

Googleカレンダーには以下のように登録されます。

タイトルには「約定(銘柄コード)xx株」と表示され、メモには詳細内容が登録されていることを確認できます。

まとめ

約定情報は証券会社が提供する情報を確認すればよいのですが、確認するためにはいくつかの手順を踏まなければ必要な情報にたどり着けません。

これが手間に感じたので、何でもかんでもGoogleカレンダーに登録する方針にしています。

これにより、関連情報含めて確認できるので、いつ何があったのかを思い出すときに便利になりました。

こんなアイディアもあるんだというくらいで試してみてください。

以外に重宝するものですよ。

では、今日も良い一日を。

-Google App Script, 投資, 自動化
-, , , , ,