見出し画像

MQL4 上の X/Twitter 投稿の実装

MT4/MT5上での、ややトリッキーかつトラブルサムなX/Twittrer投稿について解説

コード現物を有償公開してみます(記事末尾へ)


厄介の原因①X/Twitter APIの混乱

2024年現在、X APIに関しては特異な状況が続いている。
・XTwitterAPIのバージョン1.1と2.0の混在
・XTwitterAPIエンドポイントの1.1と2の混在
・OAuth1.1とOAuth2の混在
・TwitterからXへ移行しイーロンマスク閣下が有償化を謳いだした際の方針変化
・Freeプランでどこまで対応するのかがはっきりしない

こういった辺りで、本家説明も要領良いとはいいづらく、結果的に真偽の怪しい記事が乱発し混沌としている。
ネットで情報収集すると2020年頃か2022年頃の記事が見つかるが、それら2024現在は利用できない内容ばかりの様子。

厄介の原因②MQLについてのノウハウ不足

WebRequest や SHA1 関連部分で誤情報が広まっており混乱している。公式のサンプルコード(https://www.mql5.com/ja/articles/8270)が間違ってたり(?)する。

厄介の原因③OAuthが難解

難解というか説明を読む気にならないよねあれ!

厄介の原因④そもそも厄介なWebRequestとHMAC処理の組み合わせ

WebRequestやHMAC、SHA1といった処理のひとつひとつが根本的に厄介な部類に入ると思う。
説明を読む気にならないよねあれ 其ノ弐。


要点

2024年9月現在、MQL4上で、Freeプラン経由のX投稿はできる。
(※MQL5については筆者は未確認だけどMQL4より不利な要素は無い)

投稿のエンドポイントは https://api.twitter.com/2/tweets
・現在、https://api.twitter.com/1.1 のほうは Free プラン対象外の模様
・URLをhttps://api.twitter.com/1.1/statuses/update.json  とかしてる記事は古いっす。たぶん。
・注: https://api.x.com/2/tweets  で は な い 。
(他方の1.1については https://api.x.com/1.1 と https://api.twitter.com/1.1  両者が共存してるようだが...…)

投稿の認証はOAuth1(1.1)、HMACシグネチャ生成は必須。
現状のX APIでは、OAuth2.0は、投稿(POST)に使う認証ではない。
OAuth1.1のシグネチャー生成を回避しようとして 2.0 のトークンや Bearer トークンのほうに行ってもPOSTには無関係であり、無意味です。

HMACでOAuthシグネチャを生成するコード実装が必要
シグネチャ生成のためには、以下
・HMACコード化
・SHA1ハッシュ生成
・Base64エンコード
・URLエンコード
これらが必要で そのうち SHA1 と Base64 は MQL4 標準実装されている。
残る HMAC と URLエンコード の実装が必要だけど、コード規模はたかだか数百行とかで済みます。


デベロッパーアカウントの設定

デベロッパーアカウントのプロジェクト設定もややトリッキーです。
これの詳細は割愛(別記事で書くかも

デベロッパーアカウントの「Overview」は最終的にこのような表示になるはず

投稿文のデータ形式はJSON

投稿の文章は JSON (辞書っぽい文字列ね)です。
そのための Content-type の指定をヘッダに入れる必要がある
重要なのは、このContent-typeのヘッダは、後述のシグネチャー生成元には入れない ということ

    string headers = "Authorization: OAuth ";  //  Authorization<->autorization???
    headers += "oauth_consumer_key=\"" + consumer_key + "\", "
             + "oauth_nonce=\"" + oauth_nonce + "\", "
              + "oauth_signature=\"" + oauth_signature + "\", "
               + "oauth_signature_method=\"HMAC-SHA1\", "
                + "oauth_timestamp=\"" + oauth_timestamp + "\", "
                 + "oauth_token=\"" + access_token + "\", "
                 +  "oauth_version=\"1.0\"";
    
    headers += "\r\n Content-Type: application/json";
       

↑ 文書投稿であればヘッダーはこれですべて。
なお MQL4には StringAdd() メソッドもありますが、「+」で繋げても問題ないはずです。(いままで問題起きてないというだけかも汗)

OAuthシグネチャ生成(HMACコード化)

ここが難所ですよね。
そもそも MQL4上の、文字列と uchar 配列の相互変換がそれだけでトリッキーなんすよね。この点も困難要因かと。

HMACコードは、「コード化対象の文字列」と 「キー」 を元に生成します。
よって、前準備として「コード化対象文字列」と「キー」の
それぞれを生成する。

HMACコード化の対象文字列

コード化対象となる文字列は「OAuthヘッダをアルファベット順に並べたもの」とされますが、
 以下のとおりです。

    // リクエストパラメータをアルファベット順に並べる
   string sorted_params = ""
    + "oauth_consumer_key=" + consumer_key
     + "&oauth_nonce=" + nonce
      + "&oauth_signature_method=HMAC-SHA1"
       + "&oauth_timestamp=" + timestamp
         + "&oauth_token=" + access_token
           + "&oauth_version=1.0";

// メソッド(つまりは文字列POST)とエンドポイントURLと上の文字列を&で繋げる。
string base_string = method + "&" + URLencode(url) + "&" + URLencode(sorted_params);

↑ 最後の base_string がHMACコード化の対象となる文字列です。
ここでconsumer_keyとaccess_tokenはX開発者ポータルで生成取得する文字列、nonceは乱数とかで生成する使い捨てのユニーク番号、timestampは逐次時刻から生成する。
ちなみにtimestampは5分以上ずれると認証失敗するとか(詳細不明)。
※ URLエンコードは半角英数字のみの文字列に対しては必要ない。

HMACコード化のキー

キー文字列は、URLエンコードした「コンシューマシークレット」& URLエンコードした「アクセスシークレット」です。
(2つのシークレットは X 開発者ポータルで生成取得する)


MQL4コード現物

コードの現物全体を載せてます
・コード冒頭の4つの string 変数をX 開発者ポータルで取得したトークンとキー4項目で置き換えてコンパイルすればMT4上で動くはず。
・EAとして実行すると OnInit() 初期化関数から1回だけ投稿処理が呼ばれます。
・不具合報告等歓迎します。

ここから先は

11,240字

¥ 300

この記事が気に入ったらチップで応援してみませんか?