Open Ai API integration so Chat gpt can make trades automatically

 

I am trying to get my EA working that calls on Open Ai API for chat gpt to make trades automatically based on current price and history. Maybe news too. 

But i keep getting these errors - 

Yes i know my API key should not be hardcoded but for testing purposes i have put it in. Also open ai api url is allowed in tools - options - expert advisors.


I hope someone can help. Been trying to get it working for the past couple of weeks or so... 

#include <Trade\Trade.mqh>
CTrade trade;  // Declare trade object for global use
// User-configurable settings
input double RiskPercent = 1.0;           // Risk 1% of account per trade
input double StopLossPips = 50;           // Default stop loss in pips
input double TakeProfitPips = 100;        // Default take profit in pips
input int Slippage = 2;                   // Maximum slippage in points
input int RetryAttempts = 3;              // Number of retry attempts on failure
input int RequestTimeout = 20000;         // Timeout for WebRequest (in milliseconds)
// API settings (Replace these with more secure methods of storing credentials in production)
string api_key = "sk-your-api-key-here";  // Replace with your actual API key
string api_url = "https://api.openai.com/v1/chat/completions";
string org_id = "org-your-organization-id";  // Optional: Your OpenAI organization ID
string initial_prompt = "You are a master of trading any asset.";
string messages = "[{\"role\": \"system\", \"content\": \"" + initial_prompt + "\"}]";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   Print("EA initialized successfully.");
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Print("EA deinitialized.");
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    double price = iClose(_Symbol, PERIOD_CURRENT, 0); // Get the latest price
    string user_message = "The current price of " + _Symbol + " is " + DoubleToString(price, _Digits) + ". What should be my next trading move?";
    // Append user message to the conversation
    messages += ",{\"role\": \"user\", \"content\": \"" + user_message + "\"}";
    // Prepare request body for the API call
    string request_body = "{\"model\": \"gpt-3.5-turbo\", \"messages\": " + messages + "}";
    // Send the request and get the response
    string response = SendChatGPTRequest(request_body);
    if (response != "")
    {
        string reply = ExtractReplyFromResponse(response);
        messages += ",{\"role\": \"assistant\", \"content\": \"" + reply + "\"}";
        Print("ChatGPT: ", reply);
        // Process the trading decision based on the response
        ProcessTradingDecision(reply, price);
    }
    else
    {
        Print("Failed to get a valid response from ChatGPT.");
    }
}
//+------------------------------------------------------------------+
//| Function to send request to ChatGPT with retry logic and logging |
//+------------------------------------------------------------------+
string SendChatGPTRequest(string request_body)
{
    string headers = 
        "Content-Type: application/json\r\n" +
        "Authorization: Bearer " + api_key + "\r\n" +
        "OpenAI-Organization: " + org_id + "\r\n";  // Optional
    char result[4096];  // Buffer for response
    string result_headers;
    // Convert request body to a char array and ensure it's properly null-terminated
    char post_data[];
    ArrayResize(post_data, StringLen(request_body) + 1);  // Adjust size
    StringToCharArray(request_body, post_data);
    post_data[StringLen(request_body)] = '\0';  // Ensure null-termination
    int attempts = 0;
    while (attempts < RetryAttempts)
    {
        Print("Sending request to OpenAI (Attempt: ", attempts + 1, ")");
        
        int res = WebRequest("POST", api_url, headers, NULL, RequestTimeout, post_data, StringLen(request_body), result, result_headers);
        if (res == 200)  // Success
        {
            Print("Request successful.");
            return CharArrayToString(result);  // Return response as a string
        }
        else
        {
            Print("Attempt ", attempts + 1, ": Error in request. Status code: ", res, ", HTTP code: ", GetLastError(), ", Response: ", result_headers);
            attempts++;
            Sleep(1000 * attempts);  // Exponential backoff: increase delay on each attempt
        }
    }
    Print("Failed to get a valid response after ", RetryAttempts, " attempts.");
    return "";  // Return empty if all attempts fail
}
//+------------------------------------------------------------------+
//| Function to extract reply from ChatGPT response                  |
//+------------------------------------------------------------------+
string ExtractReplyFromResponse(string response)
{
    // Simplified extraction logic (parsing JSON manually)
    int start = StringFind(response, "\"content\":\"") + 11;
    int end = StringFind(response, "\"}", start);
    if (start > 0 && end > 0 && end > start)
    {
        return StringSubstr(response, start, end - start);
    }
    else
    {
        Print("Failed to extract reply from response.");
        return "";
    }
}
//+------------------------------------------------------------------+
//| Function to process ChatGPT trading decision                     |
//+------------------------------------------------------------------+
void ProcessTradingDecision(string reply, double price)
{
    double stop_loss, take_profit;
    double account_balance = AccountInfoDouble(ACCOUNT_BALANCE);
    double risk_amount = account_balance * (RiskPercent / 100.0);
    double lot_size = CalculateLotSize(risk_amount, StopLossPips);
    if (StringFind(reply, "buy") >= 0)
    {
        stop_loss = price - StopLossPips * _Point;
        take_profit = price + TakeProfitPips * _Point;
        ExecuteTrade(ORDER_TYPE_BUY, lot_size, stop_loss, take_profit);
    }
    else if (StringFind(reply, "sell") >= 0)
    {
        stop_loss = price + StopLossPips * _Point;
        take_profit = price - TakeProfitPips * _Point;
        ExecuteTrade(ORDER_TYPE_SELL, lot_size, stop_loss, take_profit);
    }
}
//+------------------------------------------------------------------+
//| Function to calculate lot size based on risk management          |
//+------------------------------------------------------------------+
double CalculateLotSize(double risk_amount, double stop_loss_pips)
{
    double pip_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
    double lot_size = risk_amount / (stop_loss_pips * pip_value);
    return NormalizeDouble(lot_size, 2);
}
//+------------------------------------------------------------------+
//| Function to execute a trade with error handling                  |
//+------------------------------------------------------------------+
void ExecuteTrade(int order_type, double lot_size, double stop_loss, double take_profit)
{
    MqlTradeRequest request;
    MqlTradeResult result;
    for (int i = 0; i < RetryAttempts; i++)
    {
        ZeroMemory(request);
        request.action = TRADE_ACTION_DEAL;
        request.symbol = _Symbol;
        request.volume = lot_size;
        request.type = order_type;
        request.price = (order_type == ORDER_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID);
        request.sl = stop_loss;
        request.tp = take_profit;
        request.deviation = Slippage;
        request.magic = 123456;
        request.comment = (order_type == ORDER_TYPE_BUY) ? "Buy order from ChatGPT" : "Sell order from ChatGPT";
        if (OrderSend(request, result) && result.retcode == TRADE_RETCODE_DONE)
        {
            Print("Order placed successfully, Ticket: ", result.order);
            return;
        }
        else
        {
            Print("Error placing order, attempt ", i + 1, ": ", GetLastError());
            Sleep(1000);  // Pause before retrying
        }
    }
    Print("Failed to place order after ", RetryAttempts, " attempts.");
}
 
Have you tried to allow WebRequest to access this domain:

https://api.openai.com

WebRequest access
 
Soewono Effendi #:
Have you tried to allow WebRequest to access this domain:

https://api.openai.com

Yes 

 
After closer look at the error code returned, please modify your code as following:

string SendChatGPTRequest(string request_body)
{

    string headers = 
        "Content-Type: application/json\r\n" +
        "Authorization: Bearer " + api_key + "\r\n" +
        "OpenAI-Organization: " + org_id + "\r\n";  // Optional

    char result[];  // Buffer for response
    string result_headers;

    // Convert request body to a char array and ensure it's properly null-terminated
    char post_data[];
    ArrayResize(post_data, StringLen(request_body) + 1);  // Adjust size
    StringToCharArray(request_body, post_data);
    post_data[StringLen(request_body)] = '\0';  // Ensure null-termination
    int attempts = 0;
    while (attempts < RetryAttempts)
    {
        Print("Sending request to OpenAI (Attempt: ", attempts + 1, ")");
        int res = WebRequest("POST", api_url, headers, RequestTimeout, post_data, result, result_headers);
        if (res == 200)  // Success
        {
            Print("Request successful.");
            return CharArrayToString(result);  // Return response as a string
        }
        else
        {
            Print("Attempt ", attempts + 1, ": Error in request. Status code: ", res, ", HTTP code: ", GetLastError(), ", Response: ", result_headers);
            attempts++;
            Sleep(1000 * attempts);  // Exponential backoff: increase delay on each attempt
        }
    }

    Print("Failed to get a valid response after ", RetryAttempts, " attempts.");
    return "";  // Return empty if all attempts fail
}

Good luck.
 
Soewono Effendi #:
After closer look at the error code returned, please modify your code as following:


Good luck.

Getting different errors now... 

I know 401 is unauthorised in terms of a api request.

I can send you my API key in a private message so you can test if you dont mind ? 

FF 0 15:10:22.010 AI Beast (EURUSD,H1) Sending request to OpenAI (Attempt: 1)
PQ 0 15:10:22.158 AI Beast (EURUSD,H1) Attempt 1: Error in request. Status code: 401, HTTP code: 0, Response: Date: Thu, 05 Sep 2024 14:10:22 GMT
EN 0 15:10:22.158 AI Beast (EURUSD,H1) Content-Type: application/json; charset=utf-8
MH 0 15:10:22.158 AI Beast (EURUSD,H1) Content-Length: 218
IP 0 15:10:22.158 AI Beast (EURUSD,H1) Connection: keep-alive
JE 0 15:10:22.158 AI Beast (EURUSD,H1) vary: Origin
OR 0 15:10:22.158 AI Beast (EURUSD,H1) x-request-id: req_79abc03967a6c03b0d764920bc472244
MN 0 15:10:22.158 AI Beast (EURUSD,H1) strict-transport-security: max-age=15552000; includeSubDomains; preload
JE 0 15:10:22.158 AI Beast (EURUSD,H1) CF-Cache-Status: DYNAMIC
CM 0 15:10:22.158 AI Beast (EURUSD,H1) X-Content-Type-Options: nosniff
LD 0 15:10:22.158 AI Beast (EURUSD,H1) Server: cloudflare
IS 0 15:10:22.158 AI Beast (EURUSD,H1) CF-RAY: 8be6cd66af9071f8-LHR
OJ 0 15:10:22.158 AI Beast (EURUSD,H1) alt-svc: h3=":443"; ma=86400
DH 0 15:10:22.158 AI Beast (EURUSD,H1)
HK 0 15:10:23.023 AI Beast (EURUSD,H1) Sending request to OpenAI (Attempt: 2)
PO 0 15:10:23.023 AI Beast (EURUSD,H1) Attempt 2: Error in request. Status code: 1003, HTTP code: 5203, Response: Date: Thu, 05 Sep 2024 14:10:22 GMT
MH 0 15:10:23.023 AI Beast (EURUSD,H1) Content-Type: application/json; charset=utf-8
MS 0 15:10:23.023 AI Beast (EURUSD,H1) Content-Length: 218
IJ 0 15:10:23.023 AI Beast (EURUSD,H1) Connection: keep-alive
RO 0 15:10:23.023 AI Beast (EURUSD,H1) vary: Origin
OE 0 15:10:23.023 AI Beast (EURUSD,H1) x-request-id: req_79abc03967a6c03b0d764920bc472244
EP 0 15:10:23.023 AI Beast (EURUSD,H1) strict-transport-security: max-age=15552000; includeSubDomains; preload
RO 0 15:10:23.023 AI Beast (EURUSD,H1) CF-Cache-Status: DYNAMIC
CG 0 15:10:23.023 AI Beast (EURUSD,H1) X-Content-Type-Options: nosniff
LN 0 15:10:23.023 AI Beast (EURUSD,H1) Server: cloudflare
QI 0 15:10:23.023 AI Beast (EURUSD,H1) CF-RAY: 8be6cd66af9071f8-LHR
OP 0 15:10:23.023 AI Beast (EURUSD,H1) alt-svc: h3=":443"; ma=86400
 
Alexander Martin Nichols #:

Getting different errors now... 

I know 401 is unauthorised in terms of a api request.

I can send you my API key in a private message so you can test if you dont mind ? 

Hi, did you solve that problem?