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エンコード の実装が必要だけど、コード規模はたかだか数百行とかで済みます。
デベロッパーアカウントの設定
デベロッパーアカウントのプロジェクト設定もややトリッキーです。
これの詳細は割愛(別記事で書くかも
投稿文のデータ形式は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回だけ投稿処理が呼ばれます。
・不具合報告等歓迎します。
ここから先は
¥ 300
この記事が気に入ったらチップで応援してみませんか?