オープンポジションをグループ分けする - ページ 3

 

ほいほい、納得のいく仕上がりになったようです。

ポジションを 開くと、配列は必要なデータで満たされる。

テスターでEAを実行すると、テスターが低速で、一時停止を使用した場合、コメントの最初の4つのエントリが表示されます - すべてが明確です。

コードの入ったファイルを添付します。

今度は、最初の条件をごまかして、この条件を満たしたポジションにN_Caste = 1を割り当ててみる。

批評家は大歓迎です。

無関心でないすべての人に感謝します。

ファイル:
Sower_1_3.mq5  21 kb
 
Nikolay Kositsin:

...そういうものは、自分で書いたり、フリーランスから依頼されたりしています。

すみません、通過できませんでした。そういうのはないんですか?

 

おやすみなさい。

上記のメッセージのフォローアップとして、EAに2次元の配列を作成するように教え、ポジションがオープンするたびに、各ポジションのチケットとランクの値を入力します。

今後、シグナルや条件が整えば、対応するポジションの順位も変わってくる。このようにポジション管理をしていく予定です。

問題がある-専門家に対応を求める。配列から要素を削除する処理を助けてください。

ポジションが閉じられると、エリートは配列に蓄積され、チケットと「死んだ」すでに閉じられたポジションの ランクを格納し、どのように私は知らない削除します。

pp.の操作です。172-173は動作しません。

         if(dead_pos)ArrayRemove(Arr_Position,e,2);
         ArrayResize(Arr_Position,All_Position);

ローソク足ごとにOnTick()でポジションをオープンし、ストップを変更し、ティックを配列に入力し、元のゼロランクを割り当てます。

停止がトリガーになると、配列に不要な要素が蓄積されます。わかりやすいように、必要なコメントを出力して、すべてオンラインで見られるようにしています。

コードが小さいので、ここに掲載し、ファイルも添付します。

アレイクリーニングの整理をお願いします。

//+------------------------------------------------------------------+
//|                                                        Sower_1_6 |
//|                                              Sergei Voicehovskii |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Sergei Voicehovskii"
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
#include <Trade\AccountInfo.mqh>
#include <Trade\DealInfo.mqh>
#include <Trade\HistoryOrderInfo.mqh>
#include <Trade\OrderInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\TerminalInfo.mqh>
#include <Trade\Trade.mqh>
#include <Arrays\ArrayInt.mqh>
//---
CAccountInfo      m_account;
CDealInfo         m_deal;
CHistoryOrderInfo m_history;
COrderInfo        m_order;
CPositionInfo     m_position;
CSymbolInfo       m_symbol;
CTerminalInfo     m_terminal;
CTrade            m_trade;
CArrayInt         m_array;
//---
#define  observations 2
int  Arr_Position[][observations];
int  Array_Change[];
//--- input parameters
input int      SL                      = 50;
input int      TP                      = 50;
input double   Lot                     = 0.01;
input double   InpCloseProfit_money    = 5.0;   
input double   InpCloseProfit_points   = 50.0;   
input double   InpCloseProfit_percent  = 3.0;   
input ulong    InpDeviation            = 10;    
input bool     InpPrintLog             = true;
input bool     InpCommentLog           = true;
input ulong    Magic                  = 557755; 
//---
      int   stoploss    = SL;   
      int   takeprofit  = TP;
      ulong slippage    = InpDeviation;
      
      datetime Time_OpenPos;
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Обновляем данные
   Refresh_Rates();
//--- Устанавливаем символ
   m_symbol.Name(_Symbol);
//--- Устанавливаем Magic
   m_trade.SetExpertMagicNumber(Magic);
//--- Определяем режим расчета маржи    
   m_trade.SetMarginMode();
//--- Определяем режим исполнения ордеров    
   m_trade.SetTypeFillingBySymbol(m_symbol.Name());
//--- Устанавливаем максимальное отклонение от запрашиваемой цены   
   m_trade.SetDeviationInPoints(slippage);
//---
   ArrayFree(Arr_Position);  
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   if(Checking_NewBar())
   {
//+---Открываем начальные позиции "свежего" бара       
      m_trade.Buy(0.01);
      m_trade.Sell(0.01);
//+---Выставляем стопы начальных позиций       
      ModifySLTP_1_range(stoploss,takeprofit,Magic);
//+---Заполняем массив c тикет/кастой позиций 
      int N = Array_Creating_Caste_Positions();
//+--- 
      int R = ArrayRange(Arr_Position,0)-1;
      if(R<30)R=0;else R=30;
      int tic = Arr_Position[R][0];
      if(m_position.SelectByTicket(tic))
      Time_OpenPos = m_position.Time();
      int P = PositionsTotal();
      
      if(InpCommentLog){
         Comment("Выводим данные \n"
         "ticket:                       ",tic,"\n"
         "Время открытия позиции:       ",Time_OpenPos,"\n"
         "Сколько элементов в массиве:  ",R+1,"\n"
         "Проверок тикета за проход:  ",N,"\n"
         "Ввсего открыто позиций:       ",P,"\n"
         //"Время жизни позиции (стр): ",structura_time.year," год. ",structura_time.mon," мес. ",structura_time.day," дн. ",structura_time.hour," час. ",structura_time.min," мин. ",structura_time.sec," сек. \n"
         );}
//---
      ArrayPrint(Arr_Position); 
//---
   }
//---
}
//+------------------------------------------------------------------+
int Array_Creating_Caste_Positions()
{
   int  n           = 0;
   long ticket      = 0;
   bool new_pos     = true;
//---Запись новых тикетов в массив позиций        
   int All_Position = PositionsTotal();
   int Array_Size   = ArrayRange(Arr_Position,0);
//---  
   for(int i = 0; i < All_Position; i++)
      {
      if(m_position.SelectByIndex(i))
         {
            ticket  = PositionGetInteger(POSITION_TICKET);
            new_pos = true;
         }
      for(int e = 0; e < Array_Size; e++)
         {
            if(Arr_Position[e][0]==ticket)
               {
                  new_pos = false;
                  n++;
                  break;
               }
         }
      if(new_pos){
      int New_Size = Array_Size+1;
      ArrayResize(Arr_Position,New_Size,0);
         Arr_Position[Array_Size][0] = (int)ticket;//Ticket
         Arr_Position[Array_Size][1] = 0;//Number_Caste (0 = начальные позиции)
         n++;}                       
      }
//---Удаление из массива мёртвых тикетов 
      Array_Size   = ArrayRange(Arr_Position,0);
      All_Position = PositionsTotal();
//---      
      for(int e = 0; e < Array_Size; e++)
      {
         int tickt = Arr_Position[e][0];
         bool dead_pos = true;
         
         for(int i = 0; i < All_Position; i++)
         {
            if(m_position.SelectByIndex(i))
               {
                  if(tickt == PositionGetInteger(POSITION_TICKET))
                     {
                        dead_pos = false;
                        n++;
                        break;
                     }   
               }
         }
         if(dead_pos)ArrayRemove(Arr_Position,e,2);
         ArrayResize(Arr_Position,All_Position);
      }
//---     
return(n);
}
//+------------------------------------------------------------------+
//Проверка на наличие нового бара
//+------------------------------------------------------------------+
bool Checking_NewBar()
{
//--- переменная для возврата функции
   bool new_bar_opened = false;
//--- статическая переменная для хранения времени открытия последнего бара 
   static datetime last_bar_time=0; 
//--- если статическая переменная еще неинициализирована 
   if(last_bar_time==0) 
     { 
      //--- это первый вызов, запишем время открытия и выйдем 
      last_bar_time=(datetime)SeriesInfoInteger(_Symbol,Period(),SERIES_LASTBAR_DATE); 
      if(InpPrintLog)
      PrintFormat("Инициализировали переменную last_bar_time значением %s",TimeToString(last_bar_time)); 
     } 
//--- получим время открытия последнего бара по своему символу 
   datetime curr_time=(datetime)SeriesInfoInteger(Symbol(),Period(),SERIES_LASTBAR_DATE); 
//--- если время открытия текущего бара не совпадает с тем, что хранится в last_bar_time то открылся новый бар
   if(curr_time!=last_bar_time) 
     { 
      new_bar_opened = true;
      //--- запомним время открытия нового бара в статической переменной 
      last_bar_time=curr_time; 
      //--- выведем сообщение об этом событии 
      if(InpPrintLog)
      PrintFormat("На символе %s открылся новый бар в %s",_Symbol,TimeToString(TimeCurrent())); 
     } 
return(new_bar_opened);   
} 
//+------------------------------------------------------------------+
//Обновление котировок
//+------------------------------------------------------------------+
bool Refresh_Rates()
  {
//--- refresh rates
   if(!m_symbol.RefreshRates())
     {
      if(InpPrintLog)
         Print(__FILE__," ",__FUNCTION__,", ERROR: ","RefreshRates error");
      return(false);
     }
//--- protection against the return value of "zero"
   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
     {
      if(InpPrintLog)
         Print(__FILE__," ",__FUNCTION__,", ERROR: ","Ask == 0.0 OR Bid == 0.0");
      return(false);
     }
//---
   return(true);
  }

//+------------------------------------------------------------------+
void ModifySLTP_1_range(int    stplss, 
                        int    tkprfit, 
                        ulong  mgc)
{
      double sl     = 0.0,
             tp     = 0.0;      
      double slbuy  = 0.0,
             slsell = 0.0,
             tpbuy  = 0.0,
             tpsell = 0.0;
             
      Refresh_Rates();
      
      if(stplss>0)
      {
       slbuy  = m_symbol.Bid() - stplss*m_symbol.Point();
       slsell = m_symbol.Ask() + stplss*m_symbol.Point();
      }
      if(tkprfit>0)
      { 
       tpbuy  = m_symbol.Bid() + tkprfit*m_symbol.Point();    
       tpsell = m_symbol.Ask() - tkprfit*m_symbol.Point();
      }

      for(int i=PositionsTotal()-1;i>=0;i--)
      {
         if(m_position.SelectByIndex(i))
         {
            if(m_position.Symbol()==Symbol())
            { 
                if(m_position.Magic() == mgc)
                {   
                     if(m_position.PositionType()==POSITION_TYPE_BUY)
                     {
                        sl = m_position.StopLoss()   > 0 ? m_position.StopLoss()   : slbuy;
                        tp = m_position.TakeProfit() > 0 ? m_position.TakeProfit() : tpbuy;
                              m_trade.PositionModify(m_position.Ticket(),NormalizeDouble(sl,Digits()),NormalizeDouble(tp,Digits()));
                     }
                     if(m_position.PositionType()==POSITION_TYPE_SELL)
                     {
                        sl = m_position.StopLoss()   > 0 ? m_position.StopLoss()   : slsell;
                        tp = m_position.TakeProfit() > 0 ? m_position.TakeProfit() : tpsell;
                              m_trade.PositionModify(m_position.Ticket(),NormalizeDouble(sl,Digits()),NormalizeDouble(tp,Digits()));
                     }
               }
            }
         }
      }
}  
//+------------------------------------------------------------------+
ファイル:
Sower_1_6.mq5  20 kb
 

プロセスを明確にするために、StLossを0にし、TProfを50のままにし、EAを任意の通貨の時間足チャートに配置するのがよいでしょう。テスターに収録されています。

オンランデモでは、もちろん分単位の方がいいのですが

削除済み  
Sergey Voytsekhovsky:

プロセスを明確にするために、StLossを0にし、TProfを50のままにし、EAを任意の通貨の時間足チャートに配置するのがよいでしょう。テスターに収録されています。

オンランデモでは、もちろんミニッツの方が良い。

St.Loss †©あなたの壁に!

椅子から転げ落ちました)

St.Lossは避けられない。

うーん...この話題の人、まあ†、すでに掲示板にいるんですけどね...。)

 
onedollarusd:

St.Loss †© あなたの壁に!

椅子から転げ落ちました)

どうやらSt.Lossは避けられないようです。

うーん...このようなトピックで誰か、まあ†、すでにフォーラムで...。)

そうですね、バカバカしいと思います。しかし、それはあくまでアルゴリズムの一部を鍛えるためのモデルです。あなたの気分を良くすることができてうれしいです。

あなたが気にしない場合は、"....このトピックで誰かが、よく†、フォーラムで既にある... "へのリンクを投げる。" plz.

 
Sergey Voytsekhovsky:

もしあなたが「......このようなトピックで誰かが、よく†、フォーラムですでに......」へのリンクを投げることを気にしないなら、それは。" をお願いします。

さらに、2次元配列から不要になった要素を削除する方法をご存じでしたら教えてください。

頭を割って、ディレクトリを穴まで拭いた。私にそのような頭脳がないのが残念です。

 
Sergey Voytsekhovsky:

2次元配列から不要になった要素を削除するには?

ArrayResize()

ArrayResize - Операции с массивами - Справочник MQL4
ArrayResize - Операции с массивами - Справочник MQL4
  • docs.mql4.com
При успешном выполнении функция возвращает количество всех элементов, содержащихся в массиве после изменения размера; в противном случае возвращает -1 и массив не меняет размеры. Функция может быть применена только к динамическим массивам. При этом необходимо иметь ввиду, что нельзя изменять размер для динамических массивов, назначенных в...
 
Sergey Voytsekhovsky:

それよりも、2次元配列から不要になった要素を削除する方法をご存じですか?

頭が真っ白になった、参考書をふいた。私にそのような頭脳がないのが残念です。

削除された配列の 隣の位置から「それ自体」でコピー し、削除された位置から書き込む。そして、Grigori.S.Bが提案したようにリサイズします。

   int src_data[10];
   //--- Не важно как заполнен массив
   //--- Удалим индекс 4
   ArrayCopy(src_data, src_data, 4, 5);
   ArrayResize(src_data, ArraySize(src_data)-1);
2次元配列の場合は、削除する行数を2倍してください。3次元配列の場合、3倍して...
 
Grigori.S.B:

ArrayResize()

おはようございます、返信ありがとうございます。

お気づきでないようですが、上を見ていただければわかりますが、質問はすべてMQL5に関するものでした。

その差が決定的でない場合もあることは理解していますが、それにしても。引用した関数は配列のサイズを変更するもので、サイズを小さくすると余分な要素が削られる可能性があります。

これは必要なことではありません。要素を値で探して削除する必要があります。この機能は私も試しました、#23に書きました。とにかくありがとうございます。