//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void PutOrder(int type, double price=0)
{
int r=0;
color clr=clrNONE;
double lot=0,SL=0;
// double sl = OrderSL*Point;
// double sl = Delta*4*KLot*Point;
if(type==OP_SELLSTOP)
{
clr=clrRed;
lot=Lot(OP_SELL);
// SL=NormalizeDouble(price-sl,Digits);
}
if(type==OP_BUYSTOP)
{
clr=clrBlue;
lot=Lot(OP_SELL);
// SL=NormalizeDouble(price+sl,Digits);
}
r=OrderSend(Symbol(),type,Lot(type),NormalizeDouble(price,Digits),Slip,0,0,"",Magic,0,clr);
return;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CountTrades()
{
int count=0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
{
if(OrderType()<2)
count++;
}
}
}
return(count);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int LastOrderType()
{
int type=0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
{
if(OrderType()==0)
{
type=1; //buy
break;
}
if(OrderType()==1)
{
type=2; //sell
break;
}
}
}
}
return(type);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseAll(int ot=-1)
{
bool cl;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
{
if(OrderType()==0 && (ot==0 || ot==-1))
{
RefreshRates();
cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),Slip,White);
}
if(OrderType()==1 && (ot==1 || ot==-1))
{
RefreshRates();
cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),Slip,White);
}
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double AllProfit()
{
double profit=0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
{
if(OrderType()<2)
profit+=OrderProfit()+OrderSwap()+OrderCommission();
}
}
}
return(profit);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double Lot(int type)
{
double lot=Lots;
if(CountTrades()>0 && type==OP_BUY)
lot=Lots*MathPow(KLot,CountTrades())*3/4;
if(CountTrades()>0 && type==OP_SELL)
lot=Lots*MathPow(KLot,CountTrades())*3/4;
lot=NormalizeDouble(lot, 2);
if(lot>MaxLot)
lot=Lots;
return(lot);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CountOrders(int type)
{
int count=0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
{
if(OrderType()==type)
count++;
}
}
}
return(count);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void DelOrder()
{
bool del;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
{
if(OrderType()>1)
del=OrderDelete(OrderTicket());
}
}
}
return;
}
//+------------------------------------------------------------------+
//| Замена функции double Lot(int type) |
//+------------------------------------------------------------------+
double Lot2(int type)
{
double lot_B=0, lot_S=0, lot=0;
for(int i=OrdersTotal()-1;i>=0;i--)
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
if(OrderMagicNumber()==Magic)
if(OrderSymbol()==Symbol())
{
double lt = OrderLots();
if(OrderType()==OP_BUY)
lot_B=lot_B+lt; // Суммируем все лоты ордеров на покупку
if(OrderType()==OP_SELL)
lot_S=lot_S+lt; // Суммируем все лоты ордеров на продажу
}
if(type==OP_BUY) // Если мы хотим посчитать лот очередного ордера на покупку, то
lot=lot_S*2-lot_B; // Берем удвоенный суммаррный лот на продажу и
// вычитаем все, что до этого успели выставить по покупкам.
// В итоге, на уровне покупок у нас будет ровно в 2 раза > продаж.
if(type==OP_SELL) // Если мы хотим посчитать лот очередного ордера на продажу, то
lot=lot_B*2-lot_S; // Берем удвоенный суммаррный лот на покупку и
// вычитаем все, что до этого успели выставить по продажам.
// В итоге, на уровне продаж у нас будет ровно в 2 раза > покупок.
return(NormalizeDouble(lot, 2)); // В 2 разза можно заменить на KLot. Тоже интересно получится, если потестить.
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| HedgeMartinStop.mq4 |
//| Copyright 2021, AM2 |
//| http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, AM2"
#property link "http://www.forexsystems.biz"
#property version "1.00"
#property strict
//--- Inputs
extern double Loss = 417; // убыток в валюте
extern double Profit = 5; // профит в валюте
extern double Lots = 3.1; // лот
extern double KLot = 2.5; // увеличение лота
//extern double OrderSL = 800; // Ограничение убытка ордера
extern double MaxLot = 10; // максимальный лот
extern int Delta = 55; // дельта
extern int Slip = 30; // проскальзывание
extern int Magic = 123; // магик
input ENUM_TIMEFRAMES TF_ATR = PERIOD_M5; // Тайм Фрейм для ATR
extern int PerATR = 21; // Период ATR
extern double Level = 0.0009; // уровень
double buy=0,sel=0;
int num=0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
double atr=iATR(Symbol(),TF_ATR,PerATR,0);
if(AllProfit()>Profit || AllProfit()<-Loss)
{
CloseAll();
DelOrder();
}
if(CountTrades()<1 && atr>Level) // Если ордеров на графике нет ATR стало больше уровня
{
if(CountOrders(OP_BUYSTOP)<1) // то, если нет Buy Stop ордеров
{
PutOrder(OP_BUYSTOP, buy);
buy=NormalizeDouble(Bid+Delta*_Point,_Digits);
}
if(CountOrders(OP_SELLSTOP)<1)
{
PutOrder(OP_SELLSTOP,sel);
sel=NormalizeDouble(Bid-Delta*_Point,_Digits);
}
}
// открытие последующих ордеров
if(num!=CountTrades())
{
if(LastOrderType()==1)
{
DelOrder();
if(CountOrders(5)<1)
PutOrder(5,sel);
}
if(LastOrderType()==2)
{
DelOrder();
if(CountOrders(4)<1)
PutOrder(4,buy);
}
num=CountTrades();
}
/* Comment("\n Profit: ",DoubleToString(AllProfit(),2),
"\n Last Order Type: ",LastOrderType(),
"\n Count Trades: ",CountTrades());*/
}
//+------------------------------------------------------------------+
//| Замена функции double Lot(int type) |
//+------------------------------------------------------------------+
double Lot2(int type)
{
double lot_B=0, lot_S=0, lot=0;
for(int i=OrdersTotal()-1;i>=0;i--)
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
if(OrderMagicNumber()==Magic)
if(OrderSymbol()==Symbol())
{
double lt = OrderLots();
if(OrderType()==OP_BUY)
lot_B=lot_B+lt; // Суммируем все лоты ордеров на покупку
if(OrderType()==OP_SELL)
lot_S=lot_S+lt; // Суммируем все лоты ордеров на продажу
}
if(type==OP_BUY) // Если мы хотим посчитать лот очередного ордера на покупку, то
lot=lot_S*2-lot_B; // Берем удвоенный суммаррный лот на продажу и
// вычитаем все, что до этого успели выставить по покупкам.
// В итоге, на уровне покупок у нас будет ровно в 2 раза > продаж.
if(type==OP_SELL) // Если мы хотим посчитать лот очередного ордера на продажу, то
lot=lot_B*2-lot_S; // Берем удвоенный суммаррный лот на покупку и
// вычитаем все, что до этого успели выставить по продажам.
// В итоге, на уровне продаж у нас будет ровно в 2 раза > покупок.
return(NormalizeDouble(lot, 2)); // В 2 разза можно заменить на KLot. Тоже интересно получится, если потестить.
}
//+------------------------------------------------------------------+
lot=Lots*MathPow(KLot,CountTrades()); Это формула исходника.
При K_Lot=0 LotStart=1 лотность изменяется от уровня к уровню так
1- старт; дальше 1*(2 в степени 1)=2; 1*(2 в степени 2)=4… Стоп.
В исходнике int CountTrades() не имеет типа, поэтому функция считает все ордера без типа.
Дальнейшие размышления в коде первоисточника ниже.Думаюю. что даже эти предлагаемые изменения значительно повлияют на заработоспособность советника. Странно другое, формула в исходнике уже стала эталоном. А я ей не верю.Станиславский, блин.
Блин… Сам дурак. Почему второй ордер считаю в первой степени, а третий в третьей, а не второй?
kvashnin007