MetaEditor build 1490

 

新しい「FileSave」機能は、バイナリ形式のファイルしか保存できないのですか?

//+------------------------------------------------------------------+
//|                                                 Scripts_Test.mq5 |
//|                                      Copyright 2012, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
//--- входные параметры
input int      rates_to_save=1000; // количество
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   string  filename=_Symbol+"_ticks.csv";
   MqlRates rates[];        
//---
   int copied=CopyRates(Symbol(),Period(),0,rates_to_save,rates);
   if(copied!=-1)
     {
      PrintFormat(" CopyRates(%s) copied %d rates",Symbol(),copied);
      //---  запишем тики в файл
      if(!FileSave(filename,rates,FILE_COMMON))
         PrintFormat("FileSave() failed, error=%d",GetLastError());
     }
   else
      PrintFormat("Failed CopyRates(%s), Error=",_Symbol,GetLastError());
  }
//+------------------------------------------------------------------+

やりたいこと:「csv」形式で保存し、Excelで開く。

ファイル:
 
Vladimir Karputov:

新しい「FileSave」機能は、バイナリ形式でファイルを保存するだけですか?

はい。
 

CGraphic.mqhクラスについての提案です。

チャートオブジェクトを削除できるようにするために、GraphPlot のメソッドを変更する必要があります。

//+------------------------------------------------------------------+
//| Create graphic of one curve and return resource name             |
//+------------------------------------------------------------------+
string GraphPlot(const double &y[],ENUM_CURVE_TYPE type=CURVE_POINTS)
  {
   string   name="Graphic"+(string)(GetTickCount()+MathRand());
   ulong    width = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
   ulong    height= ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
   CGraphic graphic;
//--- create graphic and add curves
   graphic.Create(0,name,0,65,45,(int)(0.6*width),(int)(0.65*height));
   graphic.CurveAdd(y,type);
//--- plot curves
   graphic.CurvePlotAll();
   graphic.Update();
//--- return resource name
   //return graphic.ResourceName();
   return graphic.ChartObjectName();
  }

例えば今、チャート上に "Graphic27489614" というオブジェクトがあり、graphic.ResourceName() メソッドは "::Graphic2748961427502758" を、graphic.ChartObjectName() メソッドは "Graphic27489614" を返しています。また、変更を加えた場合は、オブジェクト名で ObjectDeleteを呼び、チャートオブジェクトを削除することができます。

 
Vladimir Karputov:

CGraphic.mqhクラスについての提案です。

チャートオブジェクトを削除できるようにするために、GraphPlot のメソッドを変更する必要があります。

例えば今、チャート上に "Graphic27489614" というオブジェクトがあり、graphic.ResourceName() メソッドは "::Graphic2748961427502758" を、graphic.ChartObjectName() メソッドは "Graphic27489614" を返しています。また、変更を加えた場合は、オブジェクト名で ObjectDeleteを呼び、チャートオブジェクトを削除することができます。

しかし、この可能性はすでに存在しているのです。CGraphic::ChartObjectName()メソッドを呼び出すことで、削除するオブジェクトの名前を取得します。

追記:CGraphic::Destroy()メソッドでもよいです。

 
Vladimir Karputov:

CGraphic.mqhクラスへの提案。

これはResourceSaveの ために行われたものです。
 
Anatoli Kazharski:

この機能はすでに利用可能です。CGraphic::ChartObjectName()メソッドを呼び出すだけで、削除するオブジェクトの名前を取得することができます。

追記:CGraphic::Destroy()メソッドでもよいです。

CGraphic::ChartObjectName()は "NULL "を返し、CGraphic::Destroy()はチャートを破棄する ためのものではありません。
 
Vladimir Karputov:
CGraphic::ChartObjectName()は "NULL "を返し、CGraphic::Destroy()はチャートを削除 するためのものではありませんので、両方のメソッドは機能しません。

どちらも私には有効です。このスクリプトをテストして、あなたのバージョンを見せてください。どうしてうまくいかなかったんでしょうね。

スクリプトで2つのメソッドをテストすることができます。

//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//---
#include <Math/Stat/Binomial.mqh>
#include <Graphics/Graphic.mqh>
//--- Размер массива
#define ARRAY_SIZE 50
//---
double array_values[ARRAY_SIZE];
double array_results[ARRAY_SIZE];
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(void)
  {
   string name   ="Graphic";
   ulong  width  =::ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
   ulong  height =::ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
//---
   CGraphic graphic;
//--- create graphic
   graphic.Create(0,name,0,65,45,(int)(0.6*width),(int)(0.65*height));
//---
   InitArray();
   CCurve *curve1=graphic.CurveAdd(array_values,CURVE_POINTS);
//---
   graphic.CurvePlotAll();
   graphic.Update();
//---
   for(int i=0; i<10; i++)
     {
      InitArray();
      curve1.Update(array_values);
      //---
      graphic.CurvePlotAll();
      graphic.Update();
      //---
      Sleep(500);
     }
//---
   graphic.Destroy();
//---
   ::Print(__FUNCTION__," > graphic.ChartObjectName(): ",graphic.ChartObjectName());
   if(!::ObjectDelete(0,graphic.ChartObjectName()))
      Print(__FUNCTION__," > Объект уже удалён!");
  }
//+------------------------------------------------------------------+
//| Генерация значений                                               |
//+------------------------------------------------------------------+
void InitArray(void)
  {
   for(int j=0; j<ARRAY_SIZE; j++)
      array_values[j]=j;
   Shuffle(array_values);
  }
//+------------------------------------------------------------------+
//| Тасование значений массива                                       |
//+------------------------------------------------------------------+
void Shuffle(double &array[])
  {
   for(uint i=0; i<ARRAY_SIZE; i++)
      RandomSwap(array_values,i);
  }
//+------------------------------------------------------------------+
//| Случайно поменять элементы местами                               |
//+------------------------------------------------------------------+
void RandomSwap(double &array[],uint i)
  {
//--- Случайный индекс для замены
   uint j=::rand()%ARRAY_SIZE;
//--- Меняем местами
   double temp =array[i];
   array[i]    =array[j];
   array[j]    =temp;
  }
//+------------------------------------------------------------------+
 

私はもともとこの例(MetaTrader 5 build 1485: additional test and chart modes in the standard libraryから引用)を拷問しました。

//+------------------------------------------------------------------+
//|                                                       Test_1.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#include <Math/Stat/Binomial.mqh>
#include <Graphics/Graphic.mqh>
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart(void)
  {
   double    vars[101];
   double    results[101];
   const int N=2000;
//---  
   MathSequence(0,N,20,vars);
   MathProbabilityDensityBinomial(vars,N,M_PI/10,true,results);
   GraphPlot(results);
//---
  }
 
#include <Math\Stat\Math.mqh> // https://www.mql5.com/ru/forum/162251#comment_3885372
#include <Math\Stat\Normal.mqh>
#include <Graphics\Graphic.mqh>

void OnStart()
  {
//---
   double random_values[];
   double pdf[];
   double cdf[];
   double x[];
   if(MathRandomNormal(0,1,1000000,random_values))
     {
      if(MathProbabilityDensityEmpirical(random_values,200,x,pdf))
        {
         GraphPlot(x,pdf,CURVE_LINES);
         //---
         DebugBreak();
        }

      if(MathCumulativeDistributionEmpirical(random_values,200,x,cdf))
        {
         GraphPlot(x,cdf,CURVE_LINES);
         //---
         DebugBreak();
        }
     }
  }
 
Vladimir Karputov:

私はもともとこの例(MetaTrader 5 build 1485: additional testing and charting modes in the standard libraryから引用)を拷問しました。

//+------------------------------------------------------------------+
//|                                                       Test_1.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#include <Math/Stat/Binomial.mqh>
#include <Graphics/Graphic.mqh>
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart(void)
  {
   double    vars[101];
   double    results[101];
   const int N=2000;
//---  
   MathSequence(0,N,20,vars);
   MathProbabilityDensityBinomial(vars,N,M_PI/10,true,results);
   GraphPlot(results);
//---
  }

一般的な除去では、当面はこうしています。

      ObjectsDeleteAll(0,"Graphic",0,OBJ_BITMAP_LABEL);
      ChartRedraw();
 

OnTradeTransaction() で SL/TP がトリガーされたかどうかを知るにはどうすればよいですか?

これは私がやったことですが、役に立ちません。

void  OnTradeTransaction (const MqlTradeTransaction &trans,   // структура торговой транзакции
                          const MqlTradeRequest     &request, // структура запроса
                          const MqlTradeResult      &result)  // структура ответа
{
  if(trans.type == TRADE_TRANSACTION_HISTORY_ADD)
  {
    datetime date = TimeCurrent ();
    MqlDateTime dateT;
    TimeToStruct (date, dateT);
    dateT.hour += 1;
    date = StructToTime (dateT);
    
    if(HistorySelect (TimeCurrent (), date))
    {
      int dealsTotal = HistoryDealsTotal ();
      ulong ticketD = HistoryDealGetTicket (dealsTotal - 1);
      if(HistoryDealGetString (ticketD, DEAL_SYMBOL) == Symbol ())
      {
        ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger (ticketD, DEAL_ENTRY);
        if(entry == DEAL_ENTRY_OUT)
        {
          int ordersTotal = HistoryOrdersTotal ();
          ulong ticketO = HistoryOrderGetTicket (ordersTotal - 1);
          if(HistoryOrderGetString (ticketO, ORDER_SYMBOL) == Symbol ())
          {
            double orderPrice = HistoryOrderGetDouble (ticketO, ORDER_PRICE_OPEN);
            double orderSL    = HistoryOrderGetDouble (ticketO, ORDER_SL);
            double orderTP    = HistoryOrderGetDouble (ticketO, ORDER_TP);
            
            if(orderPrice == orderSL)
              Print ("Сработал SL");
            
            if(orderPrice == orderTP)
              Print ("Сработал TP");
          }  
        }
      }  
    }
  }
}

そして、とにかく、もっとシンプルな方法はないのか!?

2016.12.04 14:33:01.854 2016.11.17 03:14:40take profit triggered #4 sell 0.10 EURUSD 1.07103 sl: 1.07153 tp: 1.07053 [#5 buy 0.10 EURUSD at 1.07053] ←クリックすると拡大します。
ここでは、ターミナルのログにイベントが表示されていますが、なぜEAでこのイベント(SL/TPのトリガー)を簡単に取得できるのでしょうか?それとも、可能なのでしょうか?
理由: