0
Я поступаю так. Тестирую по ценам открытия. Выбираю меньшую просадку не с меньшим количеством сделок. Перебираю полученное на контрольных точках. Выбираю более красивую линию. Проверяю на тиках. Т.е. перебор по ценам открытия. Дальше выбираю на КТ. Проверяю на тиках. Не лучшие значения, но быстро и приемлемо.

Друзья давайте с чистого листа, как я писал по ссылке www.opentraders.ru/downloads/3846#comment1637

А то я не пойму о чем мы говорим. У меня этих вариантов доработок аж 11 штук.
Надо как-то с начала и по порядку.

avatar

kvashnin007

  • 2 июня 2024, 22:30
0
Возможно и делал. Не попадался. Свое лучше. Хотя открытый код позволяет съэкономить уйму времени.
avatar

kvashnin007

  • 2 июня 2024, 11:01
+1
Опять сумбур. Отложенные ордера не имеют никакого отношения к прибыли-убытку, пока они не активируются. И вообще полуавтомат — вещь индивидуальная, не предсказуемая и часто зависит от присутствия в нужный момент в нужном месте. А если пописать?
avatar

kvashnin007

  • 2 июня 2024, 10:57
0
Каюсь. Хороший.
Только это не лучший вариант. Может открыть топик и заново обсосать идею? Задела меня идея открытия ордеров каждые Х секунд.
Особенно в связи с последней идеей малодоходного советника с большим числом сделок (абсолютная нирвана для брокера) с расчетом на программу возврата части спреда.
avatar

kvashnin007

  • 2 июня 2024, 10:16
0
Да нет. Надо быть внимательным. Просто информация не предполагает реакции. Ну разве что: ВАУ.
avatar

kvashnin007

  • 2 июня 2024, 00:56
0
Клеим вторую часть.


//*************************************************************//
   double BuyLot=0,SelLot=0;
   
   if(!Agressor)
      {   
      if(BuyPriceMinLot==0) 
         SelLot=StartLots; 
      else 
         SelLot=MathCeil(BuyPriceMinLot * 100 * CoeffLots)/100;
         
      if(SelPriceMaxLot==0) 
         BuyLot=StartLots; 
      else 
         BuyLot=MathCeil(SelPriceMaxLot * 100 * CoeffLots)/100;
      }
   else
      {   
      if(BuyPriceMinLot==0) 
         BuyLot=StartLots; 
      else 
         BuyLot=MathCeil(BuyPriceMinLot * 100 * CoeffLots)/100;
      if(SelPriceMaxLot==0) 
         SelLot=StartLots; 
      else 
         SelLot=MathCeil(SelPriceMaxLot * 100 * CoeffLots)/100;
      }
//*************************************************************//
   if(BuyLot>MaximalLots)      
      BuyLot=MaximalLots;
   if(SelLot>MaximalLots)      
      SelLot=MaximalLots;
   if(!CheckVolumeValue(BuyLot) || !CheckVolumeValue(SelLot))
      return;   
//*************************************************************//
   if(Metod==Normal)
     {
      if(Signal()==OP_BUY)
         if((b==0) || (b>0 && Ask<=BuyPriceMin-PointOrderStep*Point()))
            if(OrderSend(Symbol(),OP_BUY,NormalizeDouble(BuyLot,2),NormalizeDouble(Ask,Digits()),Slippage,0,0," ",MagicNumber,0,clrBlue)<0)
               Print("OrderSend error #",GetLastError());
   
      if(Signal()==OP_SELL)
         if((s==0) || (s>0 && Bid>=SelPriceMax+PointOrderStep*Point()))
            if(OrderSend(Symbol(),OP_SELL,NormalizeDouble(SelLot,2),NormalizeDouble(Bid,Digits()),Slippage,0,0," ",MagicNumber,0,clrRed)<0)
               Print("OrderSend error #",GetLastError());
     }
   //---   
   if(Metod==Shaman)
     {
      if(Signal()==OP_BUY && Ask<FullBU)
         if((b==0) || (b>0 && Ask<=BuyPriceMin-PointOrderStep*Point()))
            if(OrderSend(Symbol(),OP_BUY,NormalizeDouble(BuyLot,2),NormalizeDouble(Ask,Digits()),Slippage,0,0," ",MagicNumber,0,clrBlue)<0)
               Print("OrderSend error #",GetLastError());
   
      if(Signal()==OP_SELL && Bid>FullBU)
         if((s==0) || (s>0 && Bid>=SelPriceMax+PointOrderStep*Point()))
            if(OrderSend(Symbol(),OP_SELL,NormalizeDouble(SelLot,2),NormalizeDouble(Bid,Digits()),Slippage,0,0," ",MagicNumber,0,clrRed)<0)
               Print("OrderSend error #",GetLastError());
     }
//*************************************************************//
   for(int i=OrdersTotal()-1;i>=0;i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderMagicNumber()==MagicNumber)
            if(OrderSymbol()==Symbol())
              {
               op=NormalizeDouble(OrderOpenPrice(),Digits());
               tp=NormalizeDouble(OrderTakeProfit(),Digits());
               lt=NormalizeDouble(OrderLots(),2);
               tk=OrderTicket();

               if(OrderType()==OP_BUY && b==1 && tp==0)
                  if(!OrderModify(tk,op,OrderStopLoss(),NormalizeDouble(Ask+TakeProfit*Point(),Digits()),0,clrNONE))
                     Print("OrderModify error #",GetLastError());

               if(OrderType()==OP_SELL && s==1 && tp==0)
                  if(!OrderModify(tk,op,OrderStopLoss(),NormalizeDouble(Bid-TakeProfit*Point(),Digits()),0,clrNONE))
                     Print("OrderModify error #",GetLastError());

               if(OrderType()==OP_BUY && b>=2)
                 {
                  if(tk==BuyPriceMaxTic || tk==BuyPriceMinTic)
                     if(Bid<AwerageBuyPrice && tp!=AwerageBuyPrice)
                        if(!OrderModify(tk,op,OrderStopLoss(),AwerageBuyPrice,0,clrNONE))
                           Print("OrderModify error #",GetLastError());

                  if(tk!=BuyPriceMaxTic && tk!=BuyPriceMinTic && tp!=0)
                     if(!OrderModify(tk,op,0,0,0,clrNONE))
                        Print("OrderModify error #",GetLastError());
                 }
               if(OrderType()==OP_SELL && s>=2)
                 {
                  if(tk==SelPriceMaxTic || tk==SelPriceMinTic)
                     if(Ask>AwerageSelPrice && tp!=AwerageSelPrice)
                        if(!OrderModify(tk,op,OrderStopLoss(),AwerageSelPrice,0,clrNONE))
                           Print("OrderModify error #",GetLastError());

                  if(tk!=SelPriceMaxTic && tk!=SelPriceMinTic && tp!=0)
                     if(!OrderModify(tk,op,0,0,0,clrNONE))
                        Print("OrderModify error #",GetLastError());
                 }
              }
              //---
              double Prof = GetProfit();
              if((LevelStopLoss>0 && Prof<=-LevelStopLoss) || (LevelStopProfit>0 && Prof>=LevelStopProfit))
                CloseAll();
  }
//************************************************************************************************/
bool CheckVolumeValue(double volume)
  {
//--- минимально допустимый объем для торговых операций
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(volume<min_volume)
      return(false);

//--- максимально допустимый объем для торговых операций
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   if(volume>max_volume)
      return(false);

//--- получим минимальную градацию объема
   double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

   int ratio=(int)MathRound(volume/volume_step);
   if(MathAbs(ratio*volume_step-volume)>0.0000001)
      return(false);

   return(true);
  }
//************************************************************************************************/
/*СИГНАЛ*/
//------------------------------------------------------------------	
int Signal()                   // Создаем функцию получения сигнала на указанном ТФ и баре
{
        double current_openprice = iOpen (Symbol(),TF , iB);
        double Mashka =iMA(NULL,0,Per_MA,0,0,4,iB) ;
        double Atrium=0;
        
          Atrium  = 0.2 * iATR(NULL,TF_ATR,Per_MA,iB);
         
          if(Bid>=current_openprice)                                               
            {
            SellBuff = (58000000.0 * (Bid  - Mashka) * Atrium);
            BuyBuff  = (58000000.0 * (Low[iB]   - Mashka) * Atrium);
            }
          if(Bid<current_openprice)
            {
            SellBuff = (58000000.0 * (High[iB]  - Mashka) * Atrium);
            BuyBuff  = (58000000.0 * (Bid   - Mashka) * Atrium);
            }
          if (SellBuff >  LevelSell) 
            return OP_SELL;
          
          if (BuyBuff < -LevelBuy) 
            return OP_BUY;
	return -1;                   // Иначе нет сигнала. Возвращаем в int Signai () -1 (никаких сигналов)
}
//************************************************************************************************
double GetProfit()
{  
   double Profit=0;
     
   for(int i=OrdersTotal()-1;i>=0;i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderMagicNumber()==MagicNumber)
            if(OrderSymbol()==Symbol())
              Profit += OrderProfit() + OrderCommission() + OrderSwap();
   return (Profit);
}
//************************************************************************************************
bool CloseAll()
{ 
   for(int i=OrdersTotal()-1;i>=0;i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderMagicNumber()==MagicNumber)
            if(OrderSymbol()==Symbol())
              {
              if(OrderType()==OP_BUY)
                if(!OrderClose(OrderTicket(),OrderLots(),Bid,Slippage))
                  Sleep(500);
              if(OrderType()==OP_SELL)
                if(!OrderClose(OrderTicket(),OrderLots(),Ask,Slippage))
                  Sleep(500);
              }
   return true;
}
//************************************************************************************************

avatar

kvashnin007

  • 2 июня 2024, 00:44
0
Кажется первый вариант.
Твикс. Две совы в одной.


#property strict
//---
enum ENUM_Metod
  {
   Shaman    = 0,  
   Normal    = 1     
  };
input ENUM_Metod      Metod               = Shaman;   // Metod - тип работы советника, метод открытия ордеров.
input bool            Agressor            = false;    // Agressor - функция влияет только на расчет ордеров и работает всегда.
input int             CloseLim            = 0;        // Close Limit - функция оставляет к-во ордеров в каждом направлении.
//---      
input double          LevelStopLoss       = 0;
input double          LevelStopProfit     = 0;
//---      
input int             TakeProfit          = 273;      // Take Profit (in pips)
input double          StartLots           = 0.01;     // Start lot
input double          CoeffLots           = 1.1;     
input double          MaximalLots         = 2.56;     // Maximal Lot 
input int             PointOrderStep      = 63;       // Point order step (in pips)
input int             MinimalProfit       = 37;       // Minimal profit for close Average orders (in pips)
input int             MagicNumber         = 227;      // Magic Number 
input int             Slippage            = 30;       // Slippage (in pips)
//---
input ENUM_TIMEFRAMES TF                  = PERIOD_M5; // Тайм Фрейм для ATR
input ENUM_TIMEFRAMES TF_ATR              = PERIOD_H1; // Тайм Фрейм для расчета входа
input int             Per_MA              = 9;
input int             LevelSell           = 55;
input int             LevelBuy            = 88;
//---
double SellBuff;
double BuyBuff;
double ShortSig;
double LongSig;
double op,lt,tp;
int    tk,b,s;
int    iB=1;
double LotStopSell,LotStopBuy;
double Trigger_S=0, Trigger_B=0;
double BuyPriceMax=0,BuyPriceMin=0,BuyPriceMaxLot=0,BuyPriceMinLot=0,
       SelPriceMin=0,SelPriceMax=0,SelPriceMinLot=0,SelPriceMaxLot=0;
double FullBU;
//************************************************************************************************/
int OnInit()
  {
  Comment("");
  return(INIT_SUCCEEDED);
  }
//************************************************************************************************/
void OnTick()
  {
   BuyPriceMax=0;BuyPriceMin=0;BuyPriceMaxLot=0;BuyPriceMinLot=0;
   SelPriceMin=0;SelPriceMax=0;SelPriceMinLot=0;SelPriceMaxLot=0;

   int
   BuyPriceMaxTic=0,BuyPriceMinTic=0,SelPriceMaxTic=0,SelPriceMinTic=0;
   
   double
   BuyLotsSum=0,SelLotsSum=0,WeighBuy=0, WeighSell=0;

   op=0;lt=0;tp=0;

   tk=0;b=0;s=0;

   for(int i=OrdersTotal()-1;i>=0;i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderMagicNumber()==MagicNumber)
            if(OrderSymbol()==Symbol())
              {
               op=NormalizeDouble(OrderOpenPrice(),Digits());
               lt=NormalizeDouble(OrderLots(),2);
               tk=OrderTicket();
               if(OrderType()==OP_BUY)
                 {
                  b++;
                  BuyLotsSum += lt;
                  WeighBuy   += lt*op;
                  
                  if(op>BuyPriceMax || BuyPriceMax==0)
                    {
                     BuyPriceMax    = op;
                     BuyPriceMaxLot = lt;
                     BuyPriceMaxTic = tk;
                    }
                  if(op<BuyPriceMin || BuyPriceMin==0)
                    {
                     BuyPriceMin    = op;
                     BuyPriceMinLot = lt;
                     BuyPriceMinTic = tk;
                    }
                 }
               // ===
               if(OrderType()==OP_SELL)
                 {
                  s++;
                  SelLotsSum += lt;
                  WeighSell  += lt*op;
                  
                  if(op>SelPriceMax || SelPriceMax==0)
                    {
                     SelPriceMax    = op;
                     SelPriceMaxLot = lt;
                     SelPriceMaxTic = tk;
                    }
                  if(op<SelPriceMin || SelPriceMin==0)
                    {
                     SelPriceMin    = op;
                     SelPriceMinLot = lt;
                     SelPriceMinTic = tk;
                    }
                 }
              }
              //---
              if(b>CloseLim && CloseLim!=0)
                if(OrderClose (BuyPriceMaxTic, BuyPriceMaxLot, Bid , Slippage, clrBlue)) 
                  return;
                
              if(s>CloseLim && CloseLim!=0)
                if(OrderClose (SelPriceMinTic, SelPriceMinLot, Ask , Slippage, clrRed)) 
                  return;
              //---
              if (BuyLotsSum - SelLotsSum != 0) 
                 FullBU = (WeighBuy - WeighSell)/(BuyLotsSum - SelLotsSum);
//*************************************************************//
   double   AwerageBuyPrice=0,AwerageSelPrice=0;
   if(b>=2) AwerageBuyPrice=NormalizeDouble
         ((BuyPriceMax*BuyPriceMaxLot+BuyPriceMin*BuyPriceMinLot)/(BuyPriceMaxLot+BuyPriceMinLot)+MinimalProfit*Point(),Digits());
   if(s>=2) AwerageSelPrice=NormalizeDouble
         ((SelPriceMax*SelPriceMaxLot+SelPriceMin*SelPriceMinLot)/(SelPriceMaxLot+SelPriceMinLot)-MinimalProfit*Point(),Digits());

avatar

kvashnin007

  • 2 июня 2024, 00:42
0
Этот вари ант далеко не первый и не последний. Их было тьма.
СчаЗ посмотрел: 11 вариантов. Это все докрутки, какие придумал.

Число усредняющих ордеров зависят от шага. Лотность от CoeffLots. Усредняющие ордера по возможности сокращаются в плюс MinTP. Благодаря Awerage. Но здесь нюанс. Чтобы «качественнее» сокращались надо CoeffLots побольше, а MinimalProfit поменьше. Шаг лучше по индюку. Опять же, это все, с другой стороны, повышает нагрузку и просадку. Здесь нужна подгонка под рынок. А это само по себе не надежно.

Ввел CloseLim, которая ограничивает количество открытых сделок в каждом направлении. Теряя в депозите, но отыгрывая в свободных средствах. В итого понижает нагрузку и просадку.

Режим Agressor для безбашенных. Лучше отключать.

Режим Шаман открывает ордера только в направлении общего БУ. Надо, думаю, в БУ добавить MinTP.
Ну а нормальный режим — простой сеточник, но умный.
avatar

kvashnin007

  • 2 июня 2024, 00:35
+1
Хотя так и не понял как берутся показания индикатора, чисто по аналогии создал еще три варианта открытия ордеров.
Ввел внешнюю переменную VariantOpen.
Если VariantOpen=1, то это вариант АМ2. Если 2-4, то это мои извращения. Хотя это не последнее слово. Только надо разобраться с показаниями индикатора. Массив tr это что такое? Какому массиву он соответствует в индикаторе?
double val[],valc[],levup[],levdn[];

В mql4 просто указываешь номер массива, с которого снимаешь пальчики, а здесь как?
Ладно буду изучать матчасть.

К нашему баранчику. Как всегда даю две части для склейки. Сохраните как версию 2. Погоняйте. Должно быть получше, чем на скрине: zakaz.opentraders.ru/uploads/images/2/9/e/4/638/big/2b963a13c1.png.

Удачи.

Часть1.


//+------------------------------------------------------------------+
//|                                               TrendDirection.mq5 |
//|                                             Copyright 2024, AM2. |
//|                                      http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, AM2."
#property link      "http://www.forexsystems.biz"
#property version   "1.02"

#include <Trade\Trade.mqh>
CTrade trade;

input double    Lots         = 0.1;      // торговый объем
input double    MaxLot       = 5;        // максимальный торговый объем
input double    KLot         = 1.5;      // увеличение лота
input int       StopLoss     = 5555;     // стоп
input int       TakeProfit   = 111;      // тейк
input int       Count        = 20;       // число поз
input int       Step         = 333;      // шаг
input int       StartHour    = 0;        // час начала торговли
input int       StartMin     = 30;       // минута начала торговли
input int       EndHour      = 23;       // час окончания торговли
input int       EndMin       = 30;       // минута окончания торговли
input ulong     Magic        = 1961;     // магик
input int       Spread       = 33;       // спред
input int       Slip         = 22;       // проскальзывание
input bool      Buy          = 1;        // покупки
input bool      Sell         = 1;        // продажи
input string    Comm         = "Scalp";
input string    IndName      = "Trend direction and force - JMA smoothed";
input int       trendPeriod  = 20;       // Trend period
input int       smoothPeriod = 3;        // Smoothing period
input double    TriggerUp    = 0.1;      // Trigger up level
input double    TriggerDn    =-0.1;      // Trigger down level
input int       VariantOpen  = 3;        // Вариант отработки открытия ордеров (1-3)
//---
datetime t=0;
int td=0, Spr;
double    Ask, Bid;
double tr[2];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
      td = iCustom(NULL,0,IndName,trendPeriod,smoothPeriod,TriggerUp,TriggerDn);        // А какой массив из четырех ???????????????????
      trade.SetExpertMagicNumber(Magic);
      trade.SetDeviationInPoints(Slip);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   double sl=0,tp=0;
   bool buy=false, sell=false;
   
   Spr = (int)SymbolInfoInteger(NULL,SYMBOL_SPREAD);
   Ask = SymbolInfoDouble(NULL,SYMBOL_ASK);
   Bid = SymbolInfoDouble(NULL,SYMBOL_BID);

   CopyBuffer(td,2,1,2,tr);                            // А чему равен tr? Не вижу нигде наполнения массива. ????????????????????????????????

   if(VariantOpen==1)
      {
      buy  = tr[1]>TriggerUp && tr[0]<TriggerUp;      
      sell = tr[1]<TriggerDn && tr[0]>TriggerDn;
      }      

   if(VariantOpen==2)
      {
      if(tr[1]<TriggerDn && tr[0]<tr[1])
         buy=true;      
      if(tr[1]>TriggerUp && tr[0]>tr[1])
         sell=true; 
      }
           
   if(VariantOpen==3)
      {
      if(tr[1]<TriggerDn && tr[0]<tr[1] && tr[2]<tr[1])
         buy=true;      
      if(tr[1]>TriggerUp && tr[0]>tr[1] && tr[2]<tr[1])
         sell=true; 
      }     
   
   if(VariantOpen==4)
      {
      if(tr[0]<tr[1] && tr[2]<tr[1])
         buy=true;      
      if(tr[0]>tr[1] && tr[2]<tr[1])
         sell=true; 
      }     
   
   if(Spr<=Spread)
      {
      if(CountTrades()<1 && TimeSession(StartHour,StartMin,EndHour,EndMin,TimeCurrent()))
         {
         if(buy && Buy)
            {
            PutOrder(0);
            ModifyOrders();
            }
         if(sell && Sell)
            {
            PutOrder(1);
            ModifyOrders();
            }
         }
      //---
      if(CountTrades()>0 && CountTrades()<Count)
         {
         if(PositionType()==0 && FindLastBuyPrice()-Ask>Step*_Point)
            {
            PutOrder(0);
            ModifyOrders();
            }

         if(PositionType()==1 && Bid-FindLastSellPrice()>Step*_Point)
            {
            PutOrder(1);
            ModifyOrders();
            }
         }
      }
   Comment("\n tr1: ",tr[0],
           "\n tr2: ",tr[1]);

avatar

kvashnin007

  • 1 июня 2024, 22:31
0
Хотя из таких ляпов рождаются интересные идейки. Вот например: Тралим SL и ТР навстречу друг другу. Хрень? А если подумать?

Надо записать. Забуду, как и многие внезапные.
avatar

kvashnin007

  • 1 июня 2024, 21:45
+1
Стану поручителем.

Хотя логика путаная и не продуманная. Что такое: закрытие лимитника по SL?
Зачем закрывать ордер и открывать такой же? Как я понимаю — в том же направлении, тем же лотом и SL и ТР в пунктах? А не проще и не лучше ли просто перенести SL и ТР в ценах?

Ладно. Надеюсь Андрей уже привык к таким понятиям и поймет, что требуется.
avatar

kvashnin007

  • 1 июня 2024, 21:40
+1
Вторая часть склейки:


//+------------------------------------------------------------------+
//|   Получение цены открытия последнего ордера на покупку           |
//+------------------------------------------------------------------+
double FindLastBuyPrice()
{
      double pr=0;
   
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(PositionSelectByTicket(PositionGetTicket(i)) && PositionGetInteger(POSITION_TYPE)==0)
            if(PositionGetString(POSITION_SYMBOL)==_Symbol)
               if(PositionGetInteger(POSITION_MAGIC)==Magic)
                  {
                  pr=PositionGetDouble(POSITION_PRICE_OPEN);
                  break;                                       // Где гантия, что PositionSelectByTicket() даст последний OP_BUY  ?????????????
                  }                                            // Хотя, почему-то, работает !!!
   return(pr);
}
//+------------------------------------------------------------------+
//|   Получение цены открытия последнего ордера на продажу           |
//+------------------------------------------------------------------+
double FindLastSellPrice()
{
      double pr=0;
   
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(PositionSelectByTicket(PositionGetTicket(i)) && PositionGetInteger(POSITION_TYPE)==1)
            if(PositionGetString(POSITION_SYMBOL)==_Symbol)
               if(PositionGetInteger(POSITION_MAGIC)==Magic)
                  {
                  pr=PositionGetDouble(POSITION_PRICE_OPEN);
                  break;                                       // Где гантия, что PositionSelectByTicket() даст последний OP_SELL  ?????????????
                  }                                            // Хотя, почему-то, работает !!!
   return(pr);
}
//+------------------------------------------------------------------+
//|  Position Profit    ??? Type ???                                 |     // Это что?  Тип последнего открытого ордера. А почему Profit ?
//+------------------------------------------------------------------+
int PositionType()
{
      int type=8;
   
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(PositionSelectByTicket(PositionGetTicket(i)))
            if(PositionGetString(POSITION_SYMBOL)==_Symbol)
               if(PositionGetInteger(POSITION_MAGIC)==Magic)
                  {
                  type=(int)PositionGetInteger(POSITION_TYPE);   
                  break;
                  }
   return(type);
}
//+------------------------------------------------------------------+
//|  Соответствие времени заданному отрезку                          |
//+------------------------------------------------------------------+
bool TimeSession(int aStartHour,int aStartMinute,int aStopHour,int aStopMinute,datetime aTimeCur)
{
      //--- время начала сессии
      int StartTime=3600*aStartHour+60*aStartMinute;
      //--- время окончания сессии
      int StopTime=3600*aStopHour+60*aStopMinute;
      //--- текущее время в секундах от начала дня
      aTimeCur=aTimeCur%86400;
      if(StopTime<StartTime)
         //--- переход через полночь
         if(aTimeCur>=StartTime || aTimeCur<StopTime)
            return(true);
      else
         //--- внутри одного дня
         if(aTimeCur>=StartTime && aTimeCur<StopTime)
            return(true);
   return(false);
}
//+------------------------------------------------------------------+
//|      Открытие ордеров по типу                                    |   // А если ECN - SL и ТР надо открывать после открытия ордера !!!!
//+------------------------------------------------------------------+
void PutOrder(int type)
{
   int r=0;
   color clr=Green;                                                      // Не используется !!!!!!!!
   double sl=0,tp=0;
   double price;

   if(type==0) //OP_BUY
      {
      clr=Blue;                                                          // Не используется !!!!!!!!
      price=Ask;

      if(StopLoss>0)
         sl=NormalizeDouble(price-StopLoss*_Point,_Digits);
      if(TakeProfit>0)
         tp=NormalizeDouble(price+TakeProfit*_Point,_Digits);

      trade.Buy(Lot(type),_Symbol,price,sl,tp,Comm);                     // Правильно: trade.Buy(Lot(type),_Symbol,price,0,0,Comm)
      }                                                                  // Тем более, что по коду все правильно: Открыли - модифицировали.
   //---
   if(type==1) //OP_SELL                                                 // Аналогично
      {
      clr=Red;                                               
      price=Bid;

      if(StopLoss>0)
         sl=NormalizeDouble(price+StopLoss*_Point,_Digits);
      if(TakeProfit>0)
         tp=NormalizeDouble(price-TakeProfit*_Point,_Digits);

      trade.Sell(Lot(type),_Symbol,price,sl,tp,Comm);
      }
}
//+------------------------------------------------------------------+
//|     Общий Безубыток                                              |      // Расчет в корне не верен.!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//+------------------------------------------------------------------+      // Эта ункция истинна для ордеров одного направления. Выбери какого ?????
double All()
{
      double all=0, num=0;
   
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(PositionSelectByTicket(PositionGetTicket(i)))
            if(PositionGetString(POSITION_SYMBOL)==_Symbol)
               if(PositionGetInteger(POSITION_MAGIC)==Magic)
                  {
                  all+=PositionGetDouble(POSITION_PRICE_OPEN)*PositionGetDouble(POSITION_VOLUME);
                  num+=PositionGetDouble(POSITION_VOLUME);
                  }
      if(num>0)
         all=NormalizeDouble(all/num,_Digits);
   return(all);
}
//+------------------------------------------------------------------+      // Это мой первый код на mql5.
//|     Общий Безубыток должен выглядеть так                         |      //  Требует проверки !!!!!!!!!
//+------------------------------------------------------------------+      // Надеюсь получилось. 
double AllBE()
{
      double AllBU=0;
      double BuyLotsSum=0,SelLotsSum=0;
      double WeighBuy=0,WeighSel=0;
   
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(PositionSelectByTicket(PositionGetTicket(i)))
            if(PositionGetString(POSITION_SYMBOL)==_Symbol)
               if(PositionGetInteger(POSITION_MAGIC)==Magic)               
                  {
                  if(PositionGetInteger(POSITION_TYPE)==0)
                     {
                     WeighBuy   += PositionGetDouble(POSITION_PRICE_OPEN)*PositionGetDouble(POSITION_VOLUME);
                     BuyLotsSum += PositionGetDouble(POSITION_VOLUME);
                     }
                  if(PositionGetInteger(POSITION_TYPE)==1)
                     {
                     WeighSel   += PositionGetDouble(POSITION_PRICE_OPEN)*PositionGetDouble(POSITION_VOLUME);
                     SelLotsSum += PositionGetDouble(POSITION_VOLUME);
                     }
                  }
      if(BuyLotsSum-SelLotsSum!=0)
         AllBU=(WeighBuy-WeighSel)/(BuyLotsSum-SelLotsSum);
   return(NormalizeDouble(AllBU,_Digits));
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ModifyOrders()
{
   double sl=0, tp=0;

   for(int i=PositionsTotal()-1; i>=0; i--)
      if(PositionSelectByTicket(PositionGetTicket(i)))
         if(PositionGetString(POSITION_SYMBOL)==_Symbol)
            if(PositionGetInteger(POSITION_MAGIC)==Magic)
               {
               if(PositionGetInteger(POSITION_TYPE)==0)
                  {
                  tp=NormalizeDouble(All()+TakeProfit*_Point,_Digits);
                  sl=NormalizeDouble(All()-StopLoss*_Point,_Digits);

                  if(PositionGetDouble(POSITION_TP)!=tp && PositionGetDouble(POSITION_SL)!=sl)  // А если ...==tp, а !=sl, то что??????????????????????
                     trade.PositionModify(PositionGetTicket(i),sl,tp);                          // Возможно необходимо && заменить на ||  !!!!!!!!!!!!!
                  }

               if(PositionGetInteger(POSITION_TYPE)==1)
                  {
                  tp=NormalizeDouble(All()-TakeProfit*_Point,_Digits);
                  sl=NormalizeDouble(All()+StopLoss*_Point,_Digits);

                  if(PositionGetDouble(POSITION_TP)!=tp && PositionGetDouble(POSITION_SL)!=sl)  // Аналогично.
                     trade.PositionModify(PositionGetTicket(i),sl,tp);
                  }
               }
}
//+------------------------------------------------------------------+


Смотрите, комментируйте, исправляйте.
avatar

kvashnin007

  • 31 мая 2024, 13:15
0
Пересмотрел код советника. Есть куча замечаний. Возможно не правильных.
Замечания сделал в виде комментариев в коде. Так удобнее править-отвечать.
Сигнальный блок надо сильно дорабатывать.
С наскока не вышло. Сказывается незнание mql5.

Посмотрите, кто попродвинутее. Или к Андрею может пробиться.

Даю код с замечаниями. В один файл не поместился. Два склеить, думаю, проблем не составит.


//+------------------------------------------------------------------+
//|                                               TrendDirection.mq5 |
//|                                             Copyright 2024, AM2. |
//|                                      http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, AM2."
#property link      "http://www.forexsystems.biz"
#property version   "1.00"

#include <Trade\Trade.mqh>
CTrade trade;

input double    Lots        = 0.1;      // торговый объем
input double    MaxLot      = 5;        // максимальный торговый объем
input double    KLot        = 1.5;      // увеличение лота
input int       StopLoss    = 5555;     // стоп
input int       TakeProfit  = 111;      // тейк
input int       Count       = 20;       // число поз
input int       Step        = 333;      // шаг
input int       StartHour   = 0;        // час начала торговли
input int       StartMin    = 30;       // минута начала торговли
input int       EndHour     = 23;       // час окончания торговли
input int       EndMin      = 30;       // минута окончания торговли
input ulong     Magic        = 1961;    // магик
input int       Spread       = 33;      // спред
input int       Slip         = 22;      // проскальзывание
input bool      Buy          = 1;       // покупки
input bool      Sell         = 1;       // продажи
input string    Comm         = "Scalp";
input string    IndName      = "Trend direction and force - JMA smoothed";
input int       trendPeriod  = 20;      // Trend period
input int       smoothPeriod = 3;       // Smoothing period
input double    TriggerUp    =  0.1;    // Trigger up level
input double    TriggerDown  = -0.1;    // Trigger down level
//---
datetime t=0;
int td=0, Spr;
double    Ask, Bid;
double tr[2];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
      td = iCustom(NULL,0,IndName,trendPeriod,smoothPeriod,TriggerUp,TriggerDown);        // А какой массив из четырех ???????????????????
      trade.SetExpertMagicNumber(Magic);
      trade.SetDeviationInPoints(Slip);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   double sl=0,tp=0;
   
   Spr = (int)SymbolInfoInteger(NULL,SYMBOL_SPREAD);
   Ask = SymbolInfoDouble(NULL,SYMBOL_ASK);
   Bid = SymbolInfoDouble(NULL,SYMBOL_BID);

   CopyBuffer(td,2,1,2,tr);                            // А чему равен tr? Не вижу нигде наполнения массива. ????????????????????????????????

   bool buy = tr[1]>TriggerUp && tr[0]<TriggerUp;      // !!!!!!!!!!!!!!!!!!!!    // Сигналы требуют коррекции
   bool sell = tr[1]<TriggerDown && tr[0]>TriggerDown; // !!!!!!!!!!!!!!!!!!!!    // Другой раз !!!

   if(Spr<=Spread)
      {
      if(CountTrades()<1 && TimeSession(StartHour,StartMin,EndHour,EndMin,TimeCurrent()))
         {
         if(buy && Buy)
            {
            PutOrder(0);
            ModifyOrders();
            }
         if(sell && Sell)
            {
            PutOrder(1);
            ModifyOrders();
            }
         }
      //---
      if(CountTrades()>0 && CountTrades()<Count)
         {
         if(PositionType()==0 && FindLastBuyPrice()-Ask>Step*_Point)
            {
            PutOrder(0);
            ModifyOrders();
            }

         if(PositionType()==1 && Bid-FindLastSellPrice()>Step*_Point)
            {
            PutOrder(1);
            ModifyOrders();
            }
         }
      }
   Comment("\n tr1: ",tr[0],
           "\n tr2: ",tr[1]);
}//+------------------------------------------------------------------+
//|   Расчет лота                                                    |   // Получение лота. Лот каждой позиции *KLot. Зачем????????????????
//+------------------------------------------------------------------+   // Против направления - согласен. По ходу - ?!
double Lot(int type)
{
      double lot=Lots;
   
      if(CountTrades(type)>0)
         lot=NormalizeDouble(Lots*MathPow(KLot,CountTrades(type)),2);
      if(lot>MaxLot)
         lot=Lots;
   return(lot);
}
//+------------------------------------------------------------------+
//|     Подсчет открытых позиций по типу                             |
//+------------------------------------------------------------------+
int CountTrades(int type=-1)
{
      int count=0;
   
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(PositionSelectByTicket(PositionGetTicket(i)))
            if(PositionGetString(POSITION_SYMBOL)==_Symbol)
               if(PositionGetInteger(POSITION_MAGIC)==Magic)
                  if(PositionGetInteger(POSITION_TYPE)==type || type==-1)  // ... || type==-1 - нет необходимости. Даже вредно для здоровья. 
                     count++;                                              // если предполагается ручное вмешательство,
   return(count);                                                          // то надо создавать кнопки на открытиЯ, но уже с Magic !!!!!!!!! 
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseAll(int type=-1)
{
   for(int i=PositionsTotal()-1; i>=0; i--)
      if(PositionSelectByTicket(PositionGetTicket(i)))
         if(PositionGetString(POSITION_SYMBOL)==_Symbol)
            if(PositionGetInteger(POSITION_MAGIC)==Magic)
               if(PositionGetInteger(POSITION_TYPE)==type || type==-1)     // ... || type==-1 - нет необходимости. Даже вредно для здоровья. 
                  trade.PositionClose(PositionGetTicket(i));               // если предполагается ручное вмешательство,
}                                                                          // то надо создавать кнопки на открытиЯ, но уже с Magic !!!!!!!!!
avatar

kvashnin007

  • 31 мая 2024, 13:13
0
Погонял в тестере.

Кажется, не тот вариант дал. Давно это было.

Попробуй этот:

<code>
//+------------------------------------------------------------------+
//|                                               KAE Impuls v.2.mq4 |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""

#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 clrCoral
#property indicator_color2 clrCornflowerBlue
#property indicator_color3 Red
#property indicator_color4 Blue

extern int                Per_ATR  = 9;
extern int                Per_MA   = 5;
extern ENUM_MA_METHOD     Ma_Type  = MODE_SMMA;
extern ENUM_APPLIED_PRICE PRICE    = PRICE_CLOSE;
extern double             Level_Up = 16.7;
extern double             Level_Dn = 16.7;
//---
extern bool   alertsOn        = false;
extern bool   alertsOnCurrent = true;
extern bool   alertsMessage   = true;
extern bool   alertsSound     = false;
extern bool   alertsEmail     = false;
//---
double AboveBuff[];
double ShortBuff[];
double LongBuffe[];
double BelowBuff[];

// ---
int init() {
   SetIndexBuffer(0, AboveBuff); SetIndexStyle(0, DRAW_HISTOGRAM, EMPTY, 3);                          
   SetIndexBuffer(1, BelowBuff); SetIndexStyle(1, DRAW_HISTOGRAM, EMPTY, 3);                          
   SetIndexBuffer(2, ShortBuff); SetIndexStyle(2, DRAW_ARROW, EMPTY, 1);       SetIndexArrow(2, 108);
   SetIndexBuffer(3, LongBuffe); SetIndexStyle(3, DRAW_ARROW, EMPTY, 1);       SetIndexArrow(3, 108); 
   
   SetIndexLabel(0, "Вверх");
   SetIndexLabel(1, "Вниз");   
   SetIndexLabel(2, NULL);  
   SetIndexLabel(3, NULL);  
   
   SetLevelStyle(STYLE_DOT, 0, SteelBlue);

   IndicatorShortName(" KAE Impuls v.2 ");
   return (0);
}
// ---
void deinit() {
   Comment("");
}
// ---
void start()
{
   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return;
      if(counted_bars>0) counted_bars--;
           int limit=MathMin(Bars-counted_bars,Bars-1);
      
      for (int i = limit; i >=0; i--) 
        {
        double Main =iMA(NULL,0,Per_MA,0,Ma_Type,PRICE,i);//  !!! +1
        double Minr = 0.2 * iATR(NULL,PERIOD_CURRENT,Per_ATR,i);
         
        if (Minr!=0)
          {
          AboveBuff[i] = 3.0 * (High[i]  - Main) / Minr;
          BelowBuff[i] = 3.0 * (Low[i]   - Main) / Minr;
          }
        
        if(AboveBuff[i] + BelowBuff[i]>=0)
          {
          AboveBuff[i] = AboveBuff[i] - BelowBuff[i];
          BelowBuff[i] = 0;
          }
        if(AboveBuff[i] + BelowBuff[i]<0)
          {
          BelowBuff[i] = -AboveBuff[i] + BelowBuff[i];
          AboveBuff[i] = 0;
          }
                       
        ShortBuff[i] = EMPTY_VALUE;
        LongBuffe[i] = EMPTY_VALUE;
        
        if (AboveBuff[i] >  Level_Up && Close[i] > Open[i]) 
          ShortBuff[i] =  Level_Up;
          
        if (BelowBuff[i] < -Level_Dn && Close[i] < Open[i]) 
          LongBuffe[i] = -(Level_Dn);
        }
   manageAlerts();
   return;
}
//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------
void manageAlerts()
{
    if (alertsOn)
      {
      if (alertsOnCurrent)
           int whichBar = 0;
      else     whichBar = 1;
      
      if (ShortBuff[whichBar] != EMPTY_VALUE || LongBuffe[whichBar] != EMPTY_VALUE)
        {
        if (ShortBuff[whichBar] !=  EMPTY_VALUE) doAlert(whichBar,"down");
        if (LongBuffe[whichBar] !=  EMPTY_VALUE) doAlert(whichBar,"up");
        }
      }
}
// ---
void doAlert(int forBar, string doWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;
   
   if (previousAlert != doWhat || previousTime != Time[forBar]) 
     {
     previousAlert  = doWhat;
     previousTime   = Time[forBar];

     message =  StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," IMPULS signal ",doWhat);
       if (alertsMessage) 
         Alert(message);
       if (alertsEmail)   
         SendMail
           (StringConcatenate(Symbol()," IMPULS "),message);
       if (alertsSound)   
         PlaySound("alert2.wav");
     }
}
// ------------------------------------------------------------------------------------------------------------------

</code>


avatar

kvashnin007

  • 30 мая 2024, 21:33
0
Стряпал когда-то индюка для ловли импульса. Правда на МТ4. Посмотри. Может подойдет. На текущей свече может путать в показаниях (впрочем как и любой индюк). Но не перерисовывает закрытые свечи. А путание в показаниях идет (шло) на пользу. Стратегия была рассчитана на откат цены. Т.е. на истории не все Arrows остались. На текущей свече появился сигнал, открыли сделку, цена откатила — сигнал исчез. Работать по закрытым свечам не интересно.

<code>
//+------------------------------------------------------------------+
//|                                                   KAE Impuls.mq4 |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""

#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 clrCoral
#property indicator_color2 clrCornflowerBlue
#property indicator_color3 Red
#property indicator_color4 Blue

extern int                Per_ATR  = 3;
extern int                Per_MA   = 3;
extern ENUM_MA_METHOD     Ma_Type  = MODE_SMMA;
extern ENUM_APPLIED_PRICE PRICE    = PRICE_CLOSE;
extern double             Level_Up = 16.7;
extern double             Level_Dn = 16.7;
//---
extern bool   alertsOn        = false;
extern bool   alertsOnCurrent = true;
extern bool   alertsMessage   = true;
extern bool   alertsSound     = false;
extern bool   alertsEmail     = false;
//---
double AboveBuff[];
double ShortBuff[];
double LongBuffe[];
double BelowBuff[];

// ---
int init() {
   SetIndexBuffer(0, AboveBuff); SetIndexStyle(0, DRAW_HISTOGRAM, EMPTY, 3);                          
   SetIndexBuffer(1, BelowBuff); SetIndexStyle(1, DRAW_HISTOGRAM, EMPTY, 3);                          
   SetIndexBuffer(2, ShortBuff); SetIndexStyle(2, DRAW_ARROW, EMPTY, 1);       SetIndexArrow(2, 108);
   SetIndexBuffer(3, LongBuffe); SetIndexStyle(3, DRAW_ARROW, EMPTY, 1);       SetIndexArrow(3, 108); 
   
   SetIndexLabel(0, "Вверх");
   SetIndexLabel(1, "Вниз");   
   SetIndexLabel(2, NULL);  
   SetIndexLabel(3, NULL);  
   
   SetLevelStyle(STYLE_DOT, 0, SteelBlue);

   IndicatorShortName(" KAE Impuls ");
   return (0);
}
// ---
void deinit() {
   Comment("");
}
// ---
void start()
{
   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return;
      if(counted_bars>0) counted_bars--;
           int limit=MathMin(Bars-counted_bars,Bars-1);
      
      for (int i = limit; i >=0; i--) 
        {
        double Main =iMA(NULL,0,Per_MA,0,Ma_Type,PRICE,i);//  !!! +1
        double Minr = 0.2 * iATR(NULL,PERIOD_CURRENT,Per_ATR,i);
         
        if (Minr!=0)
          {
          AboveBuff[i] = 3.0 * (High[i]  - Main) / Minr;
          BelowBuff[i] = 3.0 * (Low[i]   - Main) / Minr;
          }
        
        if(AboveBuff[i] + BelowBuff[i]>=0)
          {
          AboveBuff[i] = AboveBuff[i] + BelowBuff[i];
          BelowBuff[i] = 0;
          }
        if(AboveBuff[i] + BelowBuff[i]<0)
          {
          BelowBuff[i] = AboveBuff[i] + BelowBuff[i];
          AboveBuff[i] = 0;
          }
                       
        ShortBuff[i] = EMPTY_VALUE;
        LongBuffe[i] = EMPTY_VALUE;
        
        if (AboveBuff[i] >  Level_Up && Close[i] > Open[i]) 
          ShortBuff[i] =  Level_Up;
          
        if (BelowBuff[i] < -Level_Dn && Close[i] < Open[i]) 
          LongBuffe[i] = -(Level_Dn);
        }
   manageAlerts();
   return;
}
//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------
void manageAlerts()
{
    if (alertsOn)
      {
      if (alertsOnCurrent)
           int whichBar = 0;
      else     whichBar = 1;
      
      if (ShortBuff[whichBar] != EMPTY_VALUE || LongBuffe[whichBar] != EMPTY_VALUE)
        {
        if (ShortBuff[whichBar] !=  EMPTY_VALUE) doAlert(whichBar,"down");
        if (LongBuffe[whichBar] !=  EMPTY_VALUE) doAlert(whichBar,"up");
        }
      }
}
// ---
void doAlert(int forBar, string doWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;
   
   if (previousAlert != doWhat || previousTime != Time[forBar]) 
     {
     previousAlert  = doWhat;
     previousTime   = Time[forBar];

     message =  StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," SimilarFxMNT signal ",doWhat);
       if (alertsMessage) 
         Alert(message);
       if (alertsEmail)   
         SendMail
           (StringConcatenate(Symbol()," SimilarFxMNT "),message);
       if (alertsSound)   
         PlaySound("alert2.wav");
     }
}
// ------------------------------------------------------------------------------------------------------------------

</code>




Если проявится интерес, можно будет просить Андрея перевести на mql5.
avatar

kvashnin007

  • 30 мая 2024, 21:10
+1
Расчет общего безубытка в функции All () в корне не верен.
Он истинен только для ордеров одного направления. Если советник просто перевёртыш, функция будет работать корректно. Опять же, безубыток будет равен цене открытия ордера и расчет не нужен. Правда, без учета поборов брокера.
Предлагаю универсальную функцию на все случаи жизни. Еще не известно куда нас приведут наши доработки.
Кроме того, такой вариант практически на 100% (косвенно) учитывает поборы брокера, если есть разнонаправленные ордера.
Сюда же можно добавить расчет БУ отдельно для ордеров Buy, отдельно для Sell.
Легко. Добавив две переменные.


//+------------------------------------------------------------------+      // Это мой первый код на mql5.
//|     Общий Безубыток должен выглядеть так                         |      //  Требует проверки !!!!!!!!!
//+------------------------------------------------------------------+      // Надеюсь получилось. 
double All()
{
      double AllBU=0;
      double BuyLotsSum=0,SelLotsSum=0;
      double WeighBuy=0,WeighSel=0;
   
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(PositionSelectByTicket(PositionGetTicket(i)))
            if(PositionGetString(POSITION_SYMBOL)==_Symbol)
               if(PositionGetInteger(POSITION_MAGIC)==Magic)               
                  {
                  if(PositionGetInteger(POSITION_TYPE)==0)
                     {
                     WeighBuy   += PositionGetDouble(POSITION_PRICE_OPEN)*PositionGetDouble(POSITION_VOLUME);
                     BuyLotsSum += PositionGetDouble(POSITION_VOLUME);
                     }
                  if(PositionGetInteger(POSITION_TYPE)==1)
                     {
                     WeighSel   += PositionGetDouble(POSITION_PRICE_OPEN)*PositionGetDouble(POSITION_VOLUME);
                     SelLotsSum += PositionGetDouble(POSITION_VOLUME);
                     }
                  }
      if(BuyLotsSum-SelLotsSum!=0)
         AllBU=(WeighBuy-WeighSel)/(BuyLotsSum-SelLotsSum);
   return(NormalizeDouble(AllBU,_Digits));
}
//+------------------------------------------------------------------+


Просто поменяйте функции и будет вам счастье. Надеюсь.

Всем удачи.
avatar

kvashnin007

  • 30 мая 2024, 20:53
0
Два облегченных TrendDirection. А как интересно.



www.opentraders.ru/downloads/3848/
avatar

kvashnin007

  • 28 мая 2024, 10:47
0
Два облегченных TrendDirection. А как интересно.



Сами индюки по ссылке: www.opentraders.ru/downloads/3848/
avatar

kvashnin007

  • 28 мая 2024, 10:44
0
По вопросу добавок.

Здесь сЦуть в чем?

Кэшируем основную сделку. Т.е. не зарабатываем, но и не теряем. Спред и комиссию при TF М15 и выше можем считать досадным недоразумением. Индикатор (цена) вновь развернулся в направление основной сделки. фиксируем профит от доп. сделки, а основная как-бы продолжает движение вниз, только с более лучшей цены. Мы ничего не теряем. Даже, если доп. профит будет минусовой, он компенсируется профитом основной сделки.

Кроме того, таким же образом можно поступать в «серой зоне».
При переходе индикатора в серую зону, просто кэшируем основную сделку.
А при выходе из этой зоны, просто закрываем противоположную. Она то даст прибыль. В противном случае просто съест накопленную прибыль. Т.е. убыток.

Можно побаловать с периодами. Интересные варианты получаются. Например TrendPeriod=2.
Можно взять тот же индюк, но Forse.
Два индюка на разных TF.

Понимаю. Все это потом. Просто мысли сейчас. И их надо записать.
Склероз, понимаешь ли.
avatar

kvashnin007

  • 28 мая 2024, 10:18
0
Если что?, могу быть поручителем.
avatar

kvashnin007

  • 28 мая 2024, 09:25