/*
Риккардо.mq4
© 2003-2006 Mandor ®
E-mail:
mandorr@gmail.comПериод канала X=150/ADX(14); если X>40, тогда X=40; если X<1, тогда X=1
Отложенный ордер Buy Stop выставляется на 1 пипс выше максимума за X дней
Отложенный ордер Sell Stop выставляется на 1 пипс ниже минимума за X дней
Стоп лосс устанавливается дальше на 1 пипс от противоположной граница канала
UseMM: использовать Money Management. Рекомендуется включить (UseMM=true)
PercentMM: процент от свободных средств для вычисления новой позиции
MinLots: минимально допустимый размер позиции у дилера
MinStop: минимально допустимое расстояние от текущей цены до отложенного ордера, стоп лосса или тейк профита у дилера
*/
// Parametres
extern int TakeProfit=0;
extern double Lots=0.1;
extern bool DeleteOldOrders=true;
extern bool UseMM=false;
extern int PercentMM=20;
extern double MinLots=0.1;
extern int MinStop=11;
// Variables
int result;
int err;
int i;
int time_bar;
int X;
int upper;
int lower;
int high_stop;
int low_stop;
int ask;
int bid;
int price;
int loss;
int profit;
double ADX;
double volume;
// Initialization
void init()
{
time_bar=Time[0];
ChannelCounting();
}
// New quotations are received
void start()
{
if (Bars<100 || IsTradeAllowed()==false) return;
if (time_bar!=Time[0])
{
time_bar=Time[0];
ChannelCounting();
}
LevelCounting();
if (TotalBuy()>0) if (ModifyBuy()>0) return;
if (TotalSell()>0) if (ModifySell()>0) return;
if (TotalBuyStop()>0) if (ModifyBuyStop()>0) return;
if (TotalSellStop()>0) if (ModifySellStop()>0) return;
if (TotalBuyStop()==0 && TotalBuy()==0) if (SetBuyStop()>0) return;
if (TotalSellStop()==0 && TotalSell()==0) if (SetSellStop()>0) return;
}
// Account channel
void ChannelCounting()
{
ADX=iADX(NULL,0,14,PRICE_CLOSE,MODE_MAIN,0);
if (ADX==0) X=40; else X=MathRound(150/ADX);
if (X>40) X=40; if (X<1) X=1;
upper=MathRound(High[Highest(NULL,0,MODE_HIGH,X,1)]/Point)+1;
lower=MathRound(Low[Lowest(NULL,0,MODE_LOW,X,1)]/Point)-1;
}
// Account levels
void LevelCounting()
{
ask=MathRound(Ask/Point);
bid=MathRound(Bid/Point);
high_stop=upper; if (high_stop<ask+MinStop) high_stop=ask+MinStop;
low_stop=lower; if (low_stop>bid-MinStop) low_stop=bid-MinStop;
}
// Modify a Buy order
int ModifyBuy()
{
result=0;
for(i=0;i<OrdersTotal();i++)
{
if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if (OrderSymbol()!=Symbol()) continue;
if (OrderType()!=OP_BUY) continue;
loss=MathRound(OrderStopLoss()/Point);
if (loss>=low_stop) continue;
loss=low_stop;
if (OrderModify(OrderTicket(),OrderOpenPrice(),loss*Point,OrderTakeProfit(),0)) result=1;
else {err=GetLastError(); Print("Modify the opened position failed with error #",err);}
break;
}
return(result);
}
// Modify a Sell order
int ModifySell()
{
result=0;
for(i=0;i<OrdersTotal();i++)
{
if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if (OrderSymbol()!=Symbol()) continue;
if (OrderType()!=OP_SELL) continue;
loss=MathRound(OrderStopLoss()/Point);
if (loss<=high_stop) continue;
loss=high_stop;
if (OrderModify(OrderTicket(),OrderOpenPrice(),loss*Point,OrderTakeProfit(),0)) result=1;
else {err=GetLastError(); Print("Modify the opened position failed with error #",err);}
break;
}
return(result);
}
// Modify a Buy Stop order
int ModifyBuyStop()
{
result=0;
for(i=0;i<OrdersTotal();i++)
{
if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if (OrderSymbol()!=Symbol()) continue;
if (OrderType()!=OP_BUYSTOP) continue;
price=MathRound(OrderOpenPrice()/Point);
loss=MathRound(OrderStopLoss()/Point);
if (price<=high_stop && loss>=low_stop) continue;
price=high_stop;
loss=low_stop;
profit=0; if (TakeProfit>MinStop) profit=ask+TakeProfit;
if (OrderModify(OrderTicket(),price*Point,loss*Point,profit*Point,0)) result=1;
else {err=GetLastError(); Print("Modify a pending order failed with error #",err);}
break;
}
return(result);
}
// Modify a Sell Stop order
int ModifySellStop()
{
result=0;
for(i=0;i<OrdersTotal();i++)
{
if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if (OrderSymbol()!=Symbol()) continue;
if (OrderType()!=OP_SELLSTOP) continue;
price=MathRound(OrderOpenPrice()/Point);
loss=MathRound(OrderStopLoss()/Point);
if (price>=low_stop && loss<=high_stop) continue;
price=low_stop;
loss=high_stop;
profit=0; if (TakeProfit>MinStop) profit=bid-TakeProfit;
if (OrderModify(OrderTicket(),price*Point,loss*Point,profit*Point,0)) result=1;
else {err=GetLastError(); Print("Modify a pending order failed with error #",err);}
break;
}
return(result);
}
// Set a Buy Stop order
int SetBuyStop()
{
result=0;
volume=LotsCounting();
price=high_stop;
loss=low_stop;
profit=0; if (TakeProfit>0) profit=ask+TakeProfit;
if (OrderSend(Symbol(),OP_BUYSTOP,volume,price*Point,0,loss*Point,profit*Point,"Open by expert",0,0)>0) result=1;
else {err=GetLastError(); Print("Set a pending order failed with error #",err);}
return(result);
}
// Set a Sell Stop order
int SetSellStop()
{
result=0;
volume=LotsCounting();
price=low_stop;
loss=high_stop;
profit=0; if (TakeProfit>0) profit=ask+TakeProfit;
if (OrderSend(Symbol(),OP_SELLSTOP,volume,price*Point,0,loss*Point,profit*Point,"Open by expert",0,0)>0) result=1;
else {err=GetLastError(); Print("Set a pending order failed with error #",err);}
return(result);
}
// Buy count
int TotalBuy()
{
result=0;
for(i=0;i<OrdersTotal();i++)
{
if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if (OrderSymbol()!=Symbol()) continue;
if (OrderType()==OP_BUY) result++;
}
return(result);
}
// Sell count
int TotalSell()
{
result=0;
for(i=0;i<OrdersTotal();i++)
{
if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if (OrderSymbol()!=Symbol()) continue;
if (OrderType()==OP_SELL) result++;
}
return(result);
}
// Buy Stop count
int TotalBuyStop()
{
result=0;
for(i=0;i<OrdersTotal();i++)
{
if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if (OrderSymbol()!=Symbol()) continue;
if (OrderType()==OP_BUYSTOP) result++;
}
return(result);
}
// Sell Stop count
int TotalSellStop()
{
result=0;
for(i=0;i<OrdersTotal();i++)
{
if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if (OrderSymbol()!=Symbol()) continue;
if (OrderType()==OP_SELLSTOP) result++;
}
return(result);
}
// Account lots
double LotsCounting()
{
volume=Lots;
if (UseMM) volume=NormalizeDouble((PercentMM*AccountFreeMargin()/100000),1);
if (volume<MinLots) volume=MinLots;
return(volume);
}
// End