見出し画像

MT4とGPT-4をAPIで接続するインジケーターオープンソース

この記事では、MQL4 を使用して MetaTrader 4 と GPT-4 を API 経由で接続するインジケーター(GPT-API-forMT4)のオープンソースコードを紹介します。このコードを使用すると、MetaTrader 4 のチャートウィンドウに GPT-4 とのやりとりを行うための GUI を表示し、ユーザーが入力したテキストを GPT-4 に送信して返答を受け取り、その結果を MetaTrader 4 のチャート上に表示することができます。なおwindows7などは非対応です。

コードの概要:

  1. 必要なライブラリをインポートし、外部変数を定義

  2. OnDeinit 関数でオブジェクトを削除

  3. OnInit 関数で GUI オブジェクトを作成

  4. OnCalculate 関数で計算を行う

  5. OnChartEvent 関数でオブジェクトのクリックイベントを処理

  6. Connect2ChatGPT 関数で GPT-4 API との通信を行う

  7. GetMessage 関数で API から受け取った JSON テキストから返答を抽出

このコードを使用するには、まず ChatGPT_API_Key という変数にあなたの API キーを設定する必要があります。次に、このコードを MetaTrader 4 のインジケーターフォルダに保存し、MetaTrader 4 を再起動してインジケーターをチャートに適用します。適用後、チャートウィンドウにテキストボックスと送信ボタンが表示されるので、テキストボックスに GPT-4 に送信するテキストを入力し、送信ボタンをクリックすると GPT-4 からの返答がチャート上に表示されます。

このコードはオープンソースであり、独自のプロジェクトに合わせて改変や拡張が可能です。ただし、API キーの取り扱いには注意してください。API キーが漏洩すると、不正利用される可能性がありますので、コードの共有や公開には十分に注意してください。


#property strict
#property indicator_chart_window

#define OPEN_TYPE_PRECONFIG 0
#define FLAG_KEEP_CONNECTION 0x00400000
#define FLAG_PRAGMA_NOCACHE 0x00000100
#define FLAG_RELOAD 0x80000000
#define SERVICE_HTTP 3
#define DEFAULT_HTTPS_PORT 443
#define FLAG_SECURE 0x00800000
#define INTERNET_FLAG_SECURE 0x00800000
#define INTERNET_FLAG_KEEP_CONNECTION 0x00400000
#define HTTP_ADDREQ_FLAG_REPLACE 0x80000000
#define HTTP_ADDREQ_FLAG_ADD 0x20000000

#import "wininet.dll"
int InternetOpenW(string sAgent,int lAccessType,string sProxyName,string sProxyBypass,int lFlags);
int InternetConnectW(int hInternet,string ServerName, int nServerPort,string lpszUsername, string lpszPassword, int dwService,int dwFlags,int dwContext);
int HttpOpenRequestW(int hConnect, string Verb, string ObjectName, string Version, string Referer, string AcceptTypes, int dwFlags, int dwContext);
int HttpSendRequestW(int hRequest, string &lpszHeaders, int dwHeadersLength, uchar &lpOptional[], int dwOptionalLength);
int InternetReadFile(int hFile,uchar &sBuffer[],int lNumBytesToRead,int &lNumberOfBytesRead);
int InternetCloseHandle(int hInet);
#import
extern string ChatGPT_API_Key = "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";//"ここにAPI_Key書く";
extern string c_message = "こんにちは";
string EN = "gpt_edit";
string BN = "gpt_button";
void OnDeinit(const int reason)
{
ObjectDelete(EN);
ObjectDelete(BN);
}

int OnInit()
{
if (MQLInfoInteger(MQL_DLLS_ALLOWED) != 1) {
Print("DLL is not allowed");
return(INIT_FAILED);
}
ObjectCreate(0,EN,OBJ_EDIT,0,0,0);
ObjectSetInteger(0,EN,OBJPROP_XDISTANCE,3);
ObjectSetInteger(0,EN,OBJPROP_YDISTANCE,53);
ObjectSetInteger(0,EN,OBJPROP_XSIZE, 300);
ObjectSetInteger(0,EN,OBJPROP_YSIZE, 25);
ObjectSetString(0,EN,OBJPROP_TEXT, c_message);
ObjectSetString(0,EN,OBJPROP_FONT, "MSゴシック");
ObjectSetInteger(0,EN,OBJPROP_FONTSIZE, 9);
ObjectSetInteger(0,EN,OBJPROP_CORNER, 0);
ObjectSetInteger(0,EN,OBJPROP_COLOR, clrBlack);
ObjectSetInteger(0,EN,OBJPROP_BGCOLOR, clrWhite);
ObjectSetInteger(0,EN,OBJPROP_BORDER_COLOR,clrRed);
ObjectSetInteger(0,EN,OBJPROP_SELECTABLE,false);
ObjectSetInteger(0,EN,OBJPROP_SELECTED, false);

ObjectCreate(0,BN,OBJ_BUTTON,0,0,0);
ObjectSetInteger(0,BN,OBJPROP_XDISTANCE,250);
ObjectSetInteger(0,BN,OBJPROP_YDISTANCE,85);
ObjectSetInteger(0,BN,OBJPROP_XSIZE, 50);
ObjectSetInteger(0,BN,OBJPROP_YSIZE, 25);
ObjectSetString(0,BN,OBJPROP_TEXT, "送信");
ObjectSetString(0,BN,OBJPROP_FONT, "MSゴシック");
ObjectSetInteger(0,BN,OBJPROP_FONTSIZE, 12);
ObjectSetInteger(0,BN,OBJPROP_CORNER, 0);
ObjectSetInteger(0,BN,OBJPROP_COLOR, clrWhite);
ObjectSetInteger(0,BN,OBJPROP_BGCOLOR, clrRed);
ObjectSetInteger(0,BN,OBJPROP_BORDER_COLOR,clrRed);
ObjectSetInteger(0,BN,OBJPROP_SELECTABLE,false);
ObjectSetInteger(0,BN,OBJPROP_SELECTED, false);

return(INIT_SUCCEEDED);
}

int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
return(rates_total);
}

void OnChartEvent(
const int id,
const long& lparam,
const double& dparam,
const string& sparam)
{
if(id == CHARTEVENT_OBJECT_CLICK){
c_message = ObjectGetString(0, EN, OBJPROP_TEXT, 0);
if(sparam == BN){
string return_text = Connect2ChatGPT(c_message);
Print(return_text);
return_text = GetMessage(return_text);
Print(return_text);

Comment(return_text);
}

}
}

string Connect2ChatGPT(string message){
string result = "";
int Session = InternetOpenW("MetaTrader 4 Terminal", 0, "", "", 0);
if(Session<=0){
Print("-Err create Session");
}

string nill = "";
int connect = InternetConnectW(Session, "api.openai.com", DEFAULT_HTTPS_PORT, nill, nill, SERVICE_HTTP, 0, 0);
if(connect<=0){
Print("-Err create Connect");
if(Session>0) {
InternetCloseHandle(Session); Session=-1;
}
}

int hRequest = HttpOpenRequestW(connect, "POST", "/v1/chat/completions", "HTTP/1.1", NULL, NULL, (int)(FLAG_SECURE|FLAG_KEEP_CONNECTION|FLAG_RELOAD|FLAG_PRAGMA_NOCACHE), 0);
if(hRequest<=0){
Print("-Err OpenRequest");
InternetCloseHandle(connect);
}

uchar data[];
string text;
string headers = "Authorization: Bearer " + ChatGPT_API_Key + "\r\n " + "Content-Type: application/json\r\n";
string dataString = "{ "model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "" + message +""}] }";
StringToCharArray(dataString, data, 0, -1, CP_UTF8);
int hSend = HttpSendRequestW(hRequest, headers, StringLen(headers), data, ArraySize(data)-1);
if(hSend <= 0){
Print("Err SendRequest");
if(connect > 0) InternetCloseHandle(hRequest);
if(Session > 0) InternetCloseHandle(Session); Session = -1;
if(connect > 0) InternetCloseHandle(connect); connect = -1;
}else{
uchar ch[4096];
int dwBytes;
while(InternetReadFile(hRequest, ch, 4095, dwBytes)){
if(dwBytes <= 0) break;
text += CharArrayToString(ch, 0, dwBytes, CP_UTF8);
}
}

InternetCloseHandle(hSend);
InternetCloseHandle(hRequest);
if(Session > 0) InternetCloseHandle(Session); Session = -1;
if(connect > 0) InternetCloseHandle(connect); connect = -1;
result = text;
return result;
}

string GetMessage(string text){
string message;
string result1[];
string result2[];
string result3[];
int sep_num=0;
ushort u_sep = StringGetCharacter("{", 0);
if(StringSubstr(text, 0, 1)=="{"){
sep_num = StringSplit(text, u_sep, result1);
if(sep_num>=5){
message = result1[4];
}
}

u_sep = StringGetCharacter(":", 0);
sep_num = StringSplit(message, u_sep, result2);
if(sep_num>=3){
message = result2[2];
}

u_sep = StringGetCharacter("}", 0);
sep_num = StringSplit(message, u_sep, result3);
if(sep_num>=1){
message = result3[0];
}

if(StringSubstr(message, 0, 1)=="""){
message = StringSubstr(message, 1, -1);
}

int stringlength = StringLen(message);
if(StringSubstr(message, stringlength-1 , 1)=="""){
message = StringSubstr(message, 0, stringlength-1);
}
return message;
}