記事「MQLプロジェクトでJSON Data APIを使用する」についてのディスカッション - ページ 2

 
Sara Sabaghi #:

もちろん、クレームはあなたに対してではなく、コンテンツ・プロバイダーに対してである。なぜかバイナリーデータではなく、テキストデータを提供するのだ ))))

残念ながら、この事実は変えられない。

 
Edgar Akhmadeev #:

もちろん、クレームはあなたに対してではなく、コンテンツ・プロバイダーに対してである。なぜかバイナリ・データではなく、テキスト・データを提供するのだ ))))

残念ながら、この事実は変えられない。

なぜなら、彼らは互換性を必要としているからだ。

 
Sara Sabaghi #:

この記事はAPIとその使い方についてです。バイナリーFXのデータを提供してくれるAPIを知っていますか?それなら紹介しましょう。

次に、量子コンピュータの方が速いのに、なぜ普通のコンピュータでFIFA2024をプレイするのかと批判している。答えは簡単で、そんな処理能力は必要ないからだ。
つまり、この分野のAPIでやり取りされるデータのほとんどは数メガバイトの範囲であり、スピードは必要ないというのがこの議論に対する答えだ。加えて、どのFXデータ・プロバイダーもXML、JSON...といった標準規格を使っている。

JSONの使用に反対しているわけではない。私自身もJSONを使用していますが、PostManやWireSharkで読みやすいレスポンスを常に確認できるため、開発段階でのみ使用しています。
私は、この記事が不当にバイナリ形式について触れていないことを指摘しただけです。さらに、よりパフォーマンスの高いJSONバイナリ(JSONB)が現在勢いを増している。
私がサーバーにアクセスできる場合、サーバーとクライアント間のやり取りでは常にバイナリデータを使用する。JSONがあらゆる場所で使用されている理由はただ1つ。ユーザーからの間抜けな質問を減らすためだ。
原則として転送されるデータが非常に小さいウェブソケットでさえ、バイナリデータを使うのは合理的だと思う。少なくとも、その方がサーバー側とクライアント側の負荷が少なく、生産性の高いシステムだからだ。また、クラウド技術を使用すれば、今日の競争の激しい現実において合理的であり、その支払いにかかる費用を大幅に節約できる。結局のところ、シリアライゼーションは多くのリソースを消費し、多くのトラフィックを節約する。
 
Nikolai Semko #:
JSONの使用に反対しているわけではない。私自身もJSONを使用しているが、PostManやWireSharkで読みやすいレスポンスを常に確認できるため、開発段階でのみ使用している。
私は、この記事が不当にバイナリ形式について触れていないことを指摘しただけです。さらに、よりパフォーマンスの高いJSONバイナリ(JSONB)が現在勢いを増している。
私がサーバーにアクセスできる場合、サーバーとクライアント間のやり取りでは常にバイナリデータを使用する。JSONがあらゆる場所で使用されている理由はただ1つ。ユーザーからの間抜けな質問を減らすためだ。
原則として転送されるデータが非常に小さいウェブソケットでさえ、バイナリデータを使うのは合理的だと思う。少なくとも、その方がサーバー側とクライアント側の負荷が少なく、生産性の高いシステムだからだ。また、クラウド技術を使用すれば、今日の競争の激しい現実において合理的であり、その支払いにかかる費用を大幅に節約できる。結局のところ、シリアライゼーションは多くのリソースを消費し、多くのトラフィックを節約する。

お時間を割いていただき、ありがとうございました。バイナリ形式とJSONBの使用についてご指摘いただいた点は、非常に有効です。バイナリ形式と比較して、JSONがシステムパフォーマンスに対して最適化されていないことはその通りであり、これは多くの開発者が認識していることです。

私たちが執筆した記事では、JSONに主眼を置きました。なぜなら、金融データプロバイダーの99%、特にFXの分野では、データ交換にこの標準を使用しており、多くのプラットフォームやサービスがこの形式でデータを提供しているからです。このため、他の標準については取り上げませんでした。

改めて、あなたの視点を共有し、この重要な詳細を指摘していただき、ありがとうございます。

 
Edgar Akhmadeev #:

もちろん、クレームはあなたに対してではなく、コンテンツ・プロバイダーに対してである。なぜかバイナリ・データではなく、テキスト・データを提供するのだ ))))

残念ながら、この事実は変えられない。

はい、完全に理解しています。さらに、ほぼすべての金融データ・プロバイダーがこの方式を採用しているため、私たちはこの標準を使用することが義務付けられています。

 
こんにちは、これです。私がお願いしたのは、mql5コミュニティに投稿してほしいということです。
 //+------------------------------------------------------------------+
 //|ZIWOX APIと技術戦略。mq5|ZIWOX
 //|著作権 2024, ssabbaghi||サッバーギ
 //|https://www.mql5.com/ja/users/ssabbaghi|||.
 //+------------------------------------------------------------------+
 #property   copyright    "Sara Sabbaghi"
 #property   link          "https://www.mql5.com/ja/users/ssabbaghi"
 #property   version      "1.0"
 #property   strict

 //---- 入力パラメータ
 input      string       APIKey         =   "xxxxaquisuakey" ;       // API キー
 input      string       SymbolPrefix   =   "" ;       // ブローカー口座のシンボルプレフィックス
 input      string       SymbolSuffiex  =   "m" ;       // あなたのブローカー口座のシンボルの接尾辞
 input      int          shortMAPeriod  =   50 ;       // スローMA期間
 input      int          longMAPeriod   =   200 ;     // 高速MA期間
 input      double       Lots           =   0.01 ;     // 静的注文量
 input      int          APICallInterval = 300 ;     // API呼び出しの間隔(秒)(5分

 // ビブリオテカス キャットブースト
 #include <JAson.mqh>
CJAVal JsonValue;

 string    OBJPREFIX      =   "ZXAPI" ,
         SymbolRequest  =   "" ,
         APIJSON[];
 bool      APIOK =   false ;
 datetime LastAPICallTime = 0 ; // API の最終チャネルの時間を確認する

 //+------------------------------------------------------------------+
 //| エキスパート初期化関数|
 //+------------------------------------------------------------------+
 int OnInit ()
{
   EventSetTimer ( 30 );
   ArrayResize (APIJSON, 15 );
   SymbolRequest = PureSymbol( Symbol (), SymbolSuffiex, SymbolPrefix); // 実際のシンボル名を準備する 
   Comment ( "Wait a sec, to Get API data..." );
   return ( INIT_SUCCEEDED );
}

 //+------------------------------------------------------------------+
 |エキスパート初期化関数|
 //+------------------------------------------------------------------+
 void OnDeinit ( const int reason)
{
   Comment ( "" );
   ObjectsDeleteAll ( 0 );
}

 //+------------------------------------------------------------------+
 //| エキスパートティック関数 OnTick()|
 //+------------------------------------------------------------------+
 void OnTick ()
{
   if (!APIOK) return ;

   double shortMA, longMA;
   long ticket = - 1 ;

   if (IsNewCandle())
   {
      shortMA = iMA ( Symbol (), PERIOD_CURRENT , shortMAPeriod, 0 , MODE_SMA , PRICE_CLOSE );
      longMA = iMA ( Symbol (), PERIOD_CURRENT , longMAPeriod, 0 , MODE_SMA , PRICE_CLOSE );

       // クロスオーバー信号のチェック 
       if ( int (APIJSON[ 3 ]) >= 60 ) // 強気予想が60%より高い場合 
      {
         if (shortMA > longMA)   // トレンドを買う 
         {
             if ( OrdersTotal () == 0 ) {
               MqlTradeRequest request;
               MqlTradeResult result;
               request.action = TRADE_ACTION_DEAL ; // 買いにはTRADE_ACTION_DEALを使用する。 
               request.symbol = Symbol ();
               request.volume = Lots;
               request.type = ORDER_TYPE_BUY ; // 購入にはORDER_BUYを使用する。 
               request.price = SymbolInfoDouble ( Symbol (), SYMBOL_ASK );
               request.sl = 0 ;
               request.tp = 0 ;
               request.deviation = 3 ;
               request.comment = "Buy Order" ;
               if (! OrderSend (request, result)) {
                   Print ( "Error opening buy order: " , GetLastError ());
               }
            }
         }
      }
       if ( int (APIJSON[ 4 ]) >= 60 ) // 弱気予想が60%より高い場合 
      {
         if (shortMA < longMA)   // 売りトレンド 
         {
             if ( OrdersTotal () == 0 )
            {
               MqlTradeRequest request;
               MqlTradeResult result;
               request.action = TRADE_ACTION_DEAL ; // 売りにはTRADE_ACTION_DEALを使用する。 
               request.symbol = Symbol ();
               request.volume = Lots;
               request.type = ORDER_TYPE_SELL ; // 販売にはORDER_SELLを使用する。 
               request.price = SymbolInfoDouble ( Symbol (), SYMBOL_BID );
               request.sl = 0 ;
               request.tp = 0 ;
               request.deviation = 3 ;
               request.comment = "Sell Order" ;
               if (! OrderSend (request, result)) {
                   Print ( "Error opening sell order: " , GetLastError ());
               }
            }
         }
      }
   }
}

 //+------------------------------------------------------------------+
 | Expert OnTimer関数|
 //+------------------------------------------------------------------+
 void OnTimer ()
{
   // 最後にAPIに接続したときからの時間が、定義した間隔よりも長いかどうかを確認する。 
   if ( TimeCurrent () - LastAPICallTime >= APICallInterval)
   {
       string APIfilename = SymbolRequest + "_API_Data.json" ; // APIストアのファイル名 
      APIOK = GetAPI(SymbolRequest, APIKey, APIfilename);   // APIデータを取得し、APIfilenameに保存する。 
       if (APIOK) JsonDataParse(APIfilename, APIJSON);     // JSONデータを読み取り、API_DATA配列に格納する。 
       Comment ((APIOK ? "API OK" : "API FAILED" ),
               "\nAPI:\n" ,
               "\nBullish Forecast: " , APIJSON[ 3 ],
               "\nBearish Forecast: " , APIJSON[ 4 ],
               "\nRetail traders Long: " , APIJSON[ 5 ],
               "\nRetail traders Short: " , APIJSON[ 6 ],
               "\nMarket Sentiment: " , APIJSON[ 14 ]
              );

       // API の最新チャネルの時間を更新する 
      LastAPICallTime = TimeCurrent ();
   }
}

 //+------------------------------------------------------------------+
 //| 記事へ|コメント(2)||新キャンドル・チェック機能|
 //+------------------------------------------------------------------+
 datetime NewCandleTime = TimeCurrent ();
 bool IsNewCandle()
{
   if (NewCandleTime == iTime ( Symbol (), 0 , 0 ))
       return false ;
   else 
   {
      NewCandleTime = iTime ( Symbol (), 0 , 0 );
       return true ;
   }
}

 //+------------------------------------------------------------------+
 //| 純粋記号機能|
 //+------------------------------------------------------------------+
 string PureSymbol( string symbol, string suffiex, string prefix)
{
   string puresymbol = symbol;
   if (prefix != "" || suffiex != "" )
   {
       StringReplace (puresymbol, suffiex, "" );
       StringReplace (puresymbol, prefix, "" );
   }
   return puresymbol;
}

 //+------------------------------------------------------------------+
 |ziwoxからファンドデータを取得|
 //+------------------------------------------------------------------+
 datetime LastWebRequest = 0 ; // 失敗したリクエストのリミットAPIには、このdatetime varを使用する。
 bool GetAPI( string symbolname, string apikey, string filename)
{
   Print ( "Get API Update" );
   bool NeedToUpdate = false ;

   // APIデータファイルが利用可能かチェックする 
   if ( FileGetInteger (filename, FILE_EXISTS , true ) >= 0 )
   {
       // ファイルの更新日時から最新の更新日時をチェックする。 
       if ( TimeLocal () - ( datetime ) FileGetInteger (filename, FILE_MODIFY_DATE , true ) > 900 ) // 15分ごとにデータを更新 
         NeedToUpdate = true ;
   }
   else 
      NeedToUpdate = true ;

   if (NeedToUpdate && TimeLocal () - LastWebRequest > 300 )   // 失敗したAPIリクエストを5分ごとに再試行 
   {
       string cookie = NULL , headers;
       char post[], result[];
       int res;
       string URL = "https://www.ziwox.com/terminal/services/API/V1/fulldata.php?expn=ziwoxuser&amp;apikey=" + apikey + "&apitype=json&pair=" + symbolname;
       ResetLastError ();
       int timeout = 5000 ;
      res = WebRequest ( "GET" , URL, cookie, NULL , timeout, post, 0 , result, headers);
       if (res == - 1 )
      {
         LastWebRequest = TimeLocal ();
         int error = GetLastError ();
         if (error == 4060 )
             Print ( "API data Webrequest Error " , error, " Check your webrequest on Metatrader Expert option." );
         else if (error == 5203 )
             Print ( "HTTP request for " + symbolname + " Data failed!" );
         else 
             Print ( "Unknown HTTP request error(" + string (error) + ")! " + symbolname + " Data" );
         return false ;
      }
       else if (res == 200 )
      {
         LastWebRequest = TimeLocal ();
         string HTTPString = CharArrayToString (result, 0 , 0 , CP_UTF8 );
         Print ( "HTTP request for " + symbolname + " Data successful!" );
         Print (HTTPString);
         if ( StringFind (HTTPString, "invalid api key" , 0 ) != - 1 ) {
             Alert ( "Invalid API key" );
             return false ;
         }
         // APIデータを共通フォルダファイルに格納する。 
         int filehandle = FileOpen (filename, FILE_READ | FILE_SHARE_READ | FILE_WRITE | FILE_SHARE_WRITE | FILE_BIN | FILE_COMMON );
         if (filehandle != INVALID_HANDLE )
         {
             FileWriteArray (filehandle, result, 0 , ArraySize (result));
             FileClose (filehandle);
         }
      }
   }
   return true ;
}

 //+------------------------------------------------------------------+
 //| JSONデータ・パース機能|
 //+------------------------------------------------------------------+
 void JsonDataParse( string filename, string &_APIJSON[])
{
   for ( int arraIn = 0 ; arraIn < ArraySize (APIJSON); arraIn++) APIJSON[arraIn] = "" ;

   if ( FileGetInteger (filename, FILE_EXISTS , true ) >= 0 )
   {
       int FileHandle = FileOpen (filename, FILE_READ | FILE_SHARE_READ | FILE_WRITE | FILE_SHARE_WRITE | FILE_BIN | FILE_COMMON );
       char jsonarray[];
       FileReadArray (FileHandle, jsonarray);
       FileClose (FileHandle);

      JsonValue.Clear();
      JsonValue.Deserialize( CharArrayToString (jsonarray, 0 , 0 , CP_UTF8 ));

      _APIJSON[ 0 ] = JsonValue[ 0 ][ "Symbol" ].ToStr();
      _APIJSON[ 1 ] = JsonValue[ 0 ][ "Fundamental Bias" ].ToStr();
      _APIJSON[ 2 ] = JsonValue[ 0 ][ "Fundamental Power" ].ToStr();
      _APIJSON[ 3 ] = JsonValue[ 0 ][ "AI Bullish Forecast" ].ToStr();
      _APIJSON[ 4 ] = JsonValue[ 0 ][ "AI Bearish Forecast" ].ToStr();
      _APIJSON[ 5 ] = JsonValue[ 0 ][ "Retail Long Ratio" ].ToStr();
      _APIJSON[ 6 ] = JsonValue[ 0 ][ "Retail Short Ratio" ].ToStr();
      _APIJSON[ 7 ] = JsonValue[ 0 ][ "Retail Short Lot" ].ToStr();
      _APIJSON[ 8 ] = JsonValue[ 0 ][ "Retail Short pos" ].ToStr();
      _APIJSON[ 9 ] = JsonValue[ 0 ][ "Base COT NET" ].ToStr();
      _APIJSON[ 10 ] = JsonValue[ 0 ][ "Base COT change" ].ToStr();
      _APIJSON[ 11 ] = JsonValue[ 0 ][ "Quote COT NET" ].ToStr();
      _APIJSON[ 12 ] = JsonValue[ 0 ][ "Quote COT change" ].ToStr();
      _APIJSON[ 13 ] = JsonValue[ 0 ][ "COT chng Ratio" ].ToStr();
      _APIJSON[ 14 ] = JsonValue[ 0 ][ "Risk Sentiment" ].ToStr();
   }
}
 //+------------------------------------------------------------------+

MQL5 METATRADER 5用バージョン メタトレーダー5で動くようにコードを変更しました。また、現在の商業的な状況において、より良い条件でのコーディングに関しても変更を加えた。すべての変更はコードをメタトレーダー5に適応させるためのものです。機能的には問題ありません。このファイルをダウンロードして実行してください。必要であれば、JAson.mqh ライブラリ(コンパニオンのオリジナル・コードにあります)をインストールしてください。私の名前はネイ-ボルヘスです。出身はブラジルのゴイアス州、カルダス・ノヴァス市、ブラジルの森の真ん中です。誰も助けてくれず、一人で学ぶのはとても大変でしたが、このコミュニティで多くを学ぶことができました。ありがとう。

MQL5 METATRADER 5用バージョン メタトレーダー5で動作するようにコードを変更しました。また、現在の商業的な状況において、より良い条件のコーディングに関しても変更を加えました。すべての変更はコードをメタトレーダー5に適応させるためのものです。機能的には問題ありません。このファイルをダウンロードして実行してください。必要であれば、JAson.mqh ライブラリ(コンパニオンのオリジナル・コードにあります)をインストールしてください。私の名前はネイ-ボルヘスです。出身はブラジルのゴイアス州、カルダス・ノヴァス市、ブラジルの森の真ん中です。誰も助けてくれず、一人で学ぶのはとても大変でしたが、このコミュニティで多くを学ぶことができました。ありがとう。

ブラジル - ゴイアス州 - カルダス・ノヴァス - ネイ・ボルヘス

Sara Sabaghi
Sara Sabaghi
  • 2025.01.13
  • www.mql5.com
Trader's profile
 
Ney Borges #:
必要であれば、 コンパニオンのオリジナルコードに あるJAson.mqhライブラリを使うことができます。

google翻訳機にとっては何とも恐ろしい方法だ。

JAsonライブラリがなければ、もちろん動作しません。

ライブラリは彼のコードにあるのではなく、ここに あり、作者がそう指定しているのだ。

JSON Serialization and Deserialization (native MQL)
JSON Serialization and Deserialization (native MQL)
  • www.mql5.com
Сериализация и десериализация JSON протокола. Портированный код со скоростной библиотеки С++.
 
Sara Sabaghi #:

はい、完全に理解しています。さらに、ほぼすべての財務データ・プロバイダーがこの方法を採用しているため、私たちはこの基準を使用することが義務付けられています。

Ney Borges#:
こんにちは、これです。私がお願いしたのは、mql5コミュニティに投稿することです。

MQL5用バージョン METATRADER 5 メタトレーダー5で動作するようにコードを変更しました。また、現在の商業的な状況において、より良い条件でのコーディングに関しても変更を加えた。すべての変更はコードをメタトレーダー5に適応させるためのものです。機能的には問題ありません。このファイルをダウンロードして実行してください。必要であれば、JAson.mqh ライブラリ(コンパニオンのオリジナル・コードにあります)をインストールしてください。私の名前はネイ-ボルヘスです。出身はブラジルのゴイアス州、カルダス・ノヴァス市、ブラジルの森の真ん中です。誰も助けてくれず、一人で学ぶのはとても大変でしたが、このコミュニティで多くを学ぶことができました。ありがとう。

MQL5 METATRADER 5用バージョン メタトレーダー5で動作するようにコードを変更しました。また、現在の商業的な状況において、より良い条件のコーディングに関しても変更を加えました。すべての変更はコードをメタトレーダー5に適応させるためのものです。機能的には問題ありません。このファイルをダウンロードして実行してください。必要であれば、JAson.mqh ライブラリ(コンパニオンのオリジナル・コードにあります)をインストールしてください。私の名前はネイ-ボルヘスです。出身はブラジルのゴイアス州、カルダス・ノヴァス市、ブラジルの森の真ん中です。誰も助けてくれず、一人で学ぶのはとても大変でしたが、このコミュニティで多くを学ぶことができました。ありがとう。

ブラジル - ゴイアス州 - カルダス・ノヴァス - ネイ・ボルヘス

MQL5で動作するようにコードを修正しました。

//+------------------------------------------------------------------+
//| ZIWOX APIと技術戦略.mq5|ネイ・ボルヘス版mql5
//|著作権 2024, ssabbaghi||サッバーギ
//|https://www.mql5.com/ja/users/ssabbaghi|||.
//+------------------------------------------------------------------+
#property   copyright   "Sara Sabbaghi"
#property   link        "https://www.mql5.com/ja/users/ssabbaghi"
#property   version     "1.0"
#property   strict
#property   description "ZIWOXのAPIに対応した開発機能のエキスパート"

// ビブリオテカス
#include <JAson.mqh>
CJAVal JsonValue;

// レド機能を実現するエキスパートの機能
//#property script_show_inputs
//#プロパティ script_show_confirm

//---- 入力パラメータ
input    string      APIKey         =  "sua Key aqui xxxxxxxx";      // 一意のAPIキー
input    string      SymbolPrefix   =  "";      // ブローカー口座のシンボルプレフィックス
input    string      SymbolSuffiex  =  "m";      // あなたのブローカー口座のシンボルの接尾辞
input    int         shortMAPeriod  =  50;      // スローMA期間
input    int         longMAPeriod   =  200;     // 高速MA期間
input    double      Lots           =  0.01;    // 静的注文量
input    double      BullishThreshold = 60.0;   // 強気予想のしきい値
input    double      BearishThreshold = 60.0;   // 弱気予想のしきい値
input    int         APICallInterval = 300;     // API呼び出しの間隔(秒)(5分

string   OBJPREFIX      =  "ZXAPI",
         SymbolRequest  =  "",
         APIJSON[];
bool     APIOK          =  false;
datetime LastAPICallTime = 0; // API の最終チャネルの時間を確認する

//+------------------------------------------------------------------+
//| HTTP接続テスト機能|
//+------------------------------------------------------------------+
bool TestHTTPConnection()
{
   string cookie=NULL,headers;
   char post[],result[];
   string url="https://www.ziwox.com";
   
   ResetLastError();
   int timeout=5000; 
   
   int res=WebRequest("GET",url,cookie,NULL,timeout,post,0,result,headers);
   
   if(res==-1)
   { 
      int error=GetLastError();
      string msg = "Falha ao conectar, erro "+IntegerToString(error);
      
      // 許可に誤りがあった場合、特別なメッセージを表示する。
      if(error==4014)
         msg = "Adicione "+url+" 設定 -> オプション -> Expert Advisors -> WebRequest の許可" をクリックします。;
         
      Print("DEBUG: ", msg);
      return(false);
   }
   
   Print("DEBUG:HTTP 接続テスト成功");
   return(true);
}

//+------------------------------------------------------------------+
//| エキスパート初期化関数|
//+------------------------------------------------------------------+
int OnInit()
{
   Print("=== Iniciando Expert Advisor ===");
   
   // 基本設定の確認
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
   {
      Print(「AVISO:アルゴリズム取引は許可されていない);
      // 同じように続ける
   }
   
   if(!TerminalInfoInteger(TERMINAL_CONNECTED))
   {
      Print(「AVISO: 端末がインターネットに接続されていません");
      // 同じように続ける
   }
   
   // EAコンフィギュレーション
   EventSetTimer(30);
   ArrayResize(APIJSON, 15);
   SymbolRequest = PureSymbol(Symbol(), SymbolSuffiex, SymbolPrefix);
   
   // 使用するURLを準備し、表示する。
   string cleanSymbol = SymbolRequest;
   StringReplace(cleanSymbol, "m", "");
   string apiUrl = StringFormat("https://www.ziwox.com/terminal/services/API/V1/fulldata.php?expn=ziwoxuser&amp;apikey=%s&apitype=json&pair=%s", 
                              APIKey, cleanSymbol);
   
   Print("URL configurada: ", apiUrl);
   Print("IMPORTANTE: Adicione a URL https://www.ziwox.com em:");
   Print(「設定 -> オプション -> Expert Advisors -> WebRequestの許可");
   
   Comment("Iniciando EA...\n",
           "使用するURL:˶",
           apiUrl,
           "♪Application a URL nas opções do Expert Advisor");
   
   // HTTP 接続をテストしましたが、エラーは発生しませんでした。
   if(!TestHTTPConnection())
   {
      Print(「AVISO: HTTP接続テストが失敗しました。);
      Print("EAは引き続き接続を試みている...");
      // 同じように続ける
   }
   
   Print("===イニシャルの終了 ===");
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
|エキスパート初期化関数|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment("");
   ObjectsDeleteAll(0);
}

//+------------------------------------------------------------------+
//| エキスパートティック関数 OnTick()|
//+------------------------------------------------------------------+
void OnTick()
{
   if (!APIOK) return;
   
   double shortMA, longMA;
   MqlTradeRequest request = {};
   MqlTradeResult result = {};
   
   if (IsNewCandle())
   {
      shortMA = iMA(Symbol(),PERIOD_CURRENT, shortMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
      longMA = iMA(Symbol(),PERIOD_CURRENT, longMAPeriod, 0, MODE_SMA, PRICE_CLOSE);

      // JSONデータを分析し、ビジネスを決定する
      double aiBullishForecast = StringToDouble(APIJSON[3]); // 高額賞金
      double aiBearishForecast = StringToDouble(APIJSON[4]); // 最低保証

      // クロスオーバー信号のチェック
      if (aiBullishForecast >= BullishThreshold && shortMA > longMA) // 予測値が上限を超える場合
      {
         if (OrdersTotal() == 0) {
            request.action = TRADE_ACTION_DEAL;
            request.symbol = _Symbol;
            request.volume = Lots;
            request.type = ORDER_TYPE_BUY;
            request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
            request.deviation = 3;
            request.magic = 123456;
            request.comment = "Buy Order";
            request.type_filling = ORDER_FILLING_FOK;
            
            if(!OrderSend(request, result))
               Print("Error opening buy order: ", GetLastError());
         }
      }
      if (aiBearishForecast >= BearishThreshold && shortMA < longMA) // 予測値が制限値より大きい場合
      {
         if (OrdersTotal() == 0) {
            request.action = TRADE_ACTION_DEAL;
            request.symbol = _Symbol;
            request.volume = Lots;
            request.type = ORDER_TYPE_SELL;
            request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
            request.deviation = 3;
            request.magic = 123456;
            request.comment = "Sell Order";
            request.type_filling = ORDER_FILLING_FOK;
            
            if(!OrderSend(request, result))
               Print("Error opening sell order: ", GetLastError());
         }
      }
   }
}

//+------------------------------------------------------------------+
//| URL が許可されているかどうかを確認する関数です。
//+------------------------------------------------------------------+
bool IsURLAllowed()
{
   string url = "https://www.ziwox.com";
   string cookie=NULL, headers;
   char post[], result[];
   ResetLastError();
   
   int res = WebRequest("GET", url, cookie, NULL, 5000, post, 0, result, headers);
   
   if(res == -1)
   {
      int error = GetLastError();
      if(error == 4014)
      {
         Comment("ATENÇÃO: URL não permitidan",
                 "1. Ferramentas -> Opções -> Expert Advisorsn "から選択。,
                 "2. Marque 'Permitir WebRequest para as URLs listadas abaixo'\n",
                 "3. Adicione a URL: ", url, "\n",
                 "4. Clique em OK");
         return false;
      }
   }
   return true;
}

//+------------------------------------------------------------------+
| Expert OnTimer関数|
//+------------------------------------------------------------------+
void OnTimer()
{
   // URLが許可されているか確認する。
   if(!IsURLAllowed())
   {
      Print("DEBUG:URL が許可されていません。設定を行ってください...");
      return;
   }

   if (TimeCurrent() - LastAPICallTime >= APICallInterval)
   {
      string APIfilename = SymbolRequest + "_API_Data.json";
      
      // コメントに表示するURLを準備する
      string cleanSymbol = SymbolRequest;
      StringReplace(cleanSymbol, "m", "");
      string apiUrl = StringFormat("https://www.ziwox.com/terminal/services/API/V1/fulldata.php?expn=ziwoxuser&amp;apikey=%s&apitype=json&pair=%s", 
                                 APIKey, cleanSymbol);
      
      // 現在開催中のチャリティイベント
      Comment("Fazendo chamada à API...୧",
              "URL: ", apiUrl,
              "\n\nAguarde...");
      
      APIOK = GetAPI(SymbolRequest, APIKey, APIfilename);
      
      if (APIOK) {
         JsonDataParse(APIfilename, APIJSON);
         Comment("=== API OK ===\n",
                 "URL: ", apiUrl, "\n",
                 "最新更新情報", TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS), "\n",
                 "\nDados recebidos:",
                 "\nSymbol: ", APIJSON[0],
                 "最高価格", APIJSON[1],
                 "ファンダメンタル:", APIJSON[2],
                 "Μ繝槭シ繝ォ "Μ繝槭シ繝ォ "Μ繝槭シ繝ォ", APIJSON[3], "%",
                 "¶nPrevisão de Baixa:", APIJSON[4], "%",
                 "競争力", APIJSON[5],
                 "売り手市場", APIJSON[6],
                 "傾向D1:", APIJSON[7],
                 "\nRSI D1: ", APIJSON[8],
                 "\nPermitido Operar: ", APIJSON[9]
                 );
      } else {
         Comment("=== FALHA NA API ===\n",
                 "URL tentada: ", apiUrl, "\n",
                 "Hora: ", TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS), "\n",
                 "\nVerifique:",
                 "\n1.URL はツール -> オプション -> エキスパートアドバイザー -> WebRequest で許可されています。",
                 "\n2.インターネットへの接続は可能ですか?,
                 "\n3.記号が正しい場合"
                 );
      }

      LastAPICallTime = TimeCurrent();
   }
}

//+------------------------------------------------------------------+
//| 新しいキャンドルかどうかを確認する関数です。
//+------------------------------------------------------------------+
bool IsNewCandle()
{
   static datetime lastCandleTime = 0;
   datetime currentCandleTime = iTime(Symbol(), 0, 0);
   if (currentCandleTime != lastCandleTime)
   {
      lastCandleTime = currentCandleTime;
      return true;
   }
   return false;
}

//+------------------------------------------------------------------+
//| 純粋記号機能|
//+------------------------------------------------------------------+
string PureSymbol(string symbol, string suffiex, string prefix)
{
   string puresymbol = symbol;
   if (prefix != "" || suffiex != "")
   {
      StringReplace(puresymbol, suffiex, "");
      StringReplace(puresymbol, prefix, "");
   }
   return puresymbol;
}

//+------------------------------------------------------------------+
//| WebRequestの設定を確認する関数です。
//+------------------------------------------------------------------+
bool CheckWebRequestSettings()
{
   if(!TerminalInfoInteger(TERMINAL_DLLS_ALLOWED))
   {
      Print(「エラー:DLLは許可されていません!");
      return false;
   }
   
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
   {
      Print("ERRO:アルゴリズム取引は許可されていない!");
      return false;
   }
   
   if(!MQLInfoInteger(MQL_DLLS_ALLOWED))
   {
      Print("エラー: DLL はこのエキスパートには許可されていません!");
      return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| サーバーとの接続を確認する関数です。
//+------------------------------------------------------------------+
bool CheckServerConnection()
{
   int socket = SocketCreate();
   
   if(socket != INVALID_HANDLE)
   {
      // ZIWOX サーバーに接続します (HTTP ポートは 80)
      if(SocketConnect(socket, "www.ziwox.com", 80, 1000))
      {
         Print(「DEBUG:サーバーとの接続テスト成功");
         // 本当に接続されているか確認する。
         if(SocketIsConnected(socket))
         {
            SocketClose(socket);
            return true;
         }
      }
      else
      {
         Print("DEBUG: Falha ao conectar com o servidor: ", GetLastError());
      }
      SocketClose(socket);
   }
   else
   {
      Print("DEBUG: Falha ao criar socket: ", GetLastError());
   }
   return false;
}

//+------------------------------------------------------------------+
|APIデータ取得関数|
//+------------------------------------------------------------------+
bool GetAPI(string symbolname, string apikey, string filename)
{
   if(!TestHTTPConnection())
   {
      Print("DEBUG:HTTP 接続テストに失敗");
      return false;
   }

   string headers = "Content-Type: application/json\r\nAccept: application/json\r\n";
   char post[], result[];
   string cookie=NULL;
   int res;
   
   // API のシンボルから 'm' を削除する。
   string cleanSymbol = symbolname;
   StringReplace(cleanSymbol, "m", "");
   
   string URL = "https://www.ziwox.com/terminal/services/API/V1/fulldata.php";
   string params = StringFormat("?expn=ziwoxuser&apikey=%s&apitype=json&pair=%s", 
                              apikey, cleanSymbol);
   
   Print(「DEBUG:リクエストの準備中...");
   Print("DEBUG: URL completa: ", URL + params);
   
   URL = URL + params;
   
   string body = StringFormat("{\"apikey\":\"%s\",\"pair\":\"%s\"}", apikey, cleanSymbol);
   StringToCharArray(body, post, 0, WHOLE_ARRAY, CP_UTF8);
   
   Print(" DEBUG: リクエスト本文:", body);
   
   // リクエストを送信する
   Print("DEBUG: Iniciando WebRequest...");
   res = WebRequest("GET", URL, cookie, NULL, 5000, post, 0, result, headers);
   Print(「DEBUG:WebRequest 応答コード:", res);
   
   if(res == -1)
   {
      int error = GetLastError();
      Print("DEBUG: GetLastError retornou: ", error);
      return false;
   }
   
   if(res != 200)
   {
      Print("DEBUG: Resposta HTTP diferente de 200: ", res);
      return false;
   }
   
   string response = CharArrayToString(result, 0, WHOLE_ARRAY, CP_UTF8);
   
   // レスポンスのタグ <pre> を削除する
   StringReplace(response, "<pre>", "");
   StringReplace(response, "</pre>", "");
   
   Print("DEBUG: Resposta recebida (primeiros 500 caracteres): ", StringSubstr(response, 0, 500));
   Print("DEBUG: Tamanho total da resposta: ", StringLen(response));
   
   if(StringFind(response, "invalid api key") >= 0)
   {
      Print("DEBUG:API キーが応答で見つかりませんでした");
      Alert("Invalid API key");
      return false;
   }
   
   // レスポンスを返そう
   Print("DEBUG: Tentando salvar resposta no arquivo: ", filename);
   int filehandle = FileOpen(filename, FILE_WRITE|FILE_BIN|FILE_COMMON);
   if(filehandle != INVALID_HANDLE)
   {
      // 応答を文字配列に変換する
      char responseArray[];
      StringToCharArray(response, responseArray, 0, StringLen(response));
      
      // お問い合わせはこちら
      FileWriteArray(filehandle, responseArray);
      FileClose(filehandle);
      Print("DEBUG: Arquivo salvo com sucesso");
      return true;
   }
   
   Print("DEBUG: Falha ao salvar arquivo");
   return false;
}

//+------------------------------------------------------------------+
//| JSONデータ解析機能|
//+------------------------------------------------------------------+
void JsonDataParse(string filename, string &_APIJSON[])
{
   for (int arraIn = 0; arraIn < ArraySize(APIJSON); arraIn++) 
      APIJSON[arraIn] = "";

   if (FileGetInteger(filename, FILE_EXISTS, true) >= 0)
   {
      int FileHandle = FileOpen(filename, FILE_READ|FILE_BIN|FILE_COMMON);
      if(FileHandle != INVALID_HANDLE)
      {
         char jsonarray[];
         FileReadArray(FileHandle, jsonarray);
         FileClose(FileHandle);

         JsonValue.Clear();
         string jsonString = CharArrayToString(jsonarray, 0, WHOLE_ARRAY, CP_UTF8);
         Print("JSON Recebido: ", jsonString); // デバッグ
         
         if(JsonValue.Deserialize(jsonString))
         {
            _APIJSON[0] = JsonValue[0]["Symbol"].ToStr();
            _APIJSON[1] = JsonValue[0]["Last Price"].ToStr();
            _APIJSON[2] = JsonValue[0]["Base Fundamental Bias"].ToStr();
            _APIJSON[3] = JsonValue[0]["AI Bullish Forecast"].ToStr();
            _APIJSON[4] = JsonValue[0]["AI Bearish Forecast"].ToStr();
            _APIJSON[5] = JsonValue[0]["Retail Long Ratio"].ToStr();
            _APIJSON[6] = JsonValue[0]["Retail Short Ratio"].ToStr();
            _APIJSON[7] = JsonValue[0]["D1 Trend"].ToStr();
            _APIJSON[8] = JsonValue[0]["D1 RSI"].ToStr();
            _APIJSON[9] = JsonValue[0]["Allow To Trade"].ToStr();
            
            Print("Dados processados:");
            Print("Symbol: ", _APIJSON[0]);
            Print("Last Price: ", _APIJSON[1]);
Discussing the article: "Using JSON Data API in your MQL projects"
Discussing the article: "Using JSON Data API in your MQL projects"
  • 2025.01.17
  • Edgar Akhmadeev
  • www.mql5.com
Check out the new article: Using JSON Data API in your MQL projects . Author: Sara Sabaghi...
 
Ney Borges #:

MQL5で動作するようにコードを修正しました。

こんにちは。

コードを教えてくれてありがとう。テストしてみました。問題なく動作しています。

Ziwox Forex Data API

 
Nikolai Semko #:

バイナリに切り替えた。同じデータのサイズが1.2メガバイトに なった。必要な構造体の配列への解析に5ミリ秒 かかるようになった。

これはちょっとかかりすぎだ。ここでは 12ミリ秒かかるが、データは80Mbである。