【道楽】株の売買システムを自動的に実行する[1/4]

株の微益自動売買は、自動というからにはPCの電源入れとくだけで勝手に稼いでくれるのが理想である

そんなの簡単じゃん?と思ってた

マケスピを起動してエクセル開きっぱでVBA動かしときゃいーんじゃん?と思っていた。

けど、世の中そう甘くはなかったのだ。

甘くない理由はいくつかあって

  • マケスピ2がサーバー切断されて、接続しっぱなしにできない
  • 起動時にアップデートされる場合がある
  • エクセルが起動しているとアップデートに失敗する
  • そもそもネットが楽天モバイルだから接続しっぱなしにできない・草😇

てな具合だ

マケスピもエクセルも、起動しっぱなしにはできない

じゃあ皆さんどーしてるか?っていうのを検索するのだが

マケスピRSS全般でたいへん参考にさせていただいたWebではVBAで対処されていて、やはりなにか作らないと解決できない模様。

ならば仕方ない。

「朝にマケスピ2を起動して、エクセルを開いてマクロを実行し、取引が終わったらマケスピ2を終了する」
「土日や休日は動かさないようにする」

という感じのを作ろう

開発環境準備

IDEはタダで使えるVisual Studio 2022 Community Edition

言語はC#

UI操作はUI Automation

こんな環境がタダで使えるなんて、令和コンピューティング天国すぎるだろ

1. inspect.exe のインストール

※UI要素を調べるためのツール。エントリ記事のコードを使うだけなら要らない

https://qiita.com/RPAbot/items/f1d6438c8f2500db65ae

オレの環境では既に入ってた
C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\inspect.exe

2. Visual Studio(VS)でConsole app .NET framework プロジェクトを作る

空のプロジェクトを作成する

3. UI Automationを使うため、ソリューションエクスプローラでアセンブリへの参照を追加

  • UIAutomationClient
  • UIAutomationTypes
  • WindowsBase

4. UI Automationのラッパーを導入

UI Automationの使い方を調べてたら良さげなのがあったので使わせてもらった。

https://qiita.com/ken_hamada/items/501b164374667319d270

これをプロジェクトにソースコード登録する

メソッドをひとつ追加したので下記に貼っとく。NameProperty と LocalizedControlTypeProperty をAnd条件として検索するとかいう、他に応用効かない奴😇

なんで作ったかというと、UI要素のプロパティは同じ名前がたくさんあるので検索するときに名前だけで特定するのは難しい。そこで他の条件とAndすれば特定しやすくなる。

~ 続く ~

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Automation;
using System.Windows.Forms;

namespace TradeAutomation
{
    // UI Automation関連の処理で使う関数を集めてみました

    // 個別に抜き出して使うことも鑑み、各関数の独立を意図的に高める記述をしています。
    internal class UIAutomationLib
    {


	// ----- 中略 (リファレンス変更なし) -----


        // 追加
        // Name と Localized Control Type を指定して要素を検索する
        public AutomationElement FindElementByNameAndLCType(AutomationElement rootElement, string name, string lctype)
        {

            AutomationElement ret;
            try
            {
                var propCond1 = new PropertyCondition(
                    AutomationElement.NameProperty, name, PropertyConditionFlags.IgnoreCase);
                var propCond2 = new PropertyCondition(
                    AutomationElement.LocalizedControlTypeProperty, lctype, PropertyConditionFlags.IgnoreCase);
                var andCond = new AndCondition(propCond1, propCond2);

                // possible unhandled exception cuz ui elements may dismiss...
                ret = rootElement.FindFirst(TreeScope.Descendants, andCond);
            }
            catch
            {
                ret = null;
            }

            return ret;
        }
    }
}