1593 lines
61 KiB
Plaintext
1593 lines
61 KiB
Plaintext
//+------------------------------------------------------------------+
|
|
//| TradeAlgorithms.mqh |
|
|
//| Copyright © 2013, Nikolay Kositsin |
|
|
//| Khabarovsk, farria@mail.redcom.ru |
|
|
//+------------------------------------------------------------------+
|
|
//| Òîðãîâûå àëãîðèòìû äëÿ áðîêåðîâ ïðåäëàãàþùèõ íå íóëåâîé ñïðåä! |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "2013, Nikolay Kositsin"
|
|
#property link "farria@mail.redcom.ru"
|
|
#property version "1.21"
|
|
//+------------------------------------------------------------------+
|
|
//| Ïåðå÷èñëåíèå äëÿ âàðèàíòîâ ðàñ÷¸òà ëîòà |
|
|
//+------------------------------------------------------------------+
|
|
enum MarginMode //Òèï êîíñòàíòû äëÿ ïåðåìåííîé Margin_Mode òîðãîâûõ ôóíêöèé
|
|
{
|
|
FREEMARGIN=0, //MM îò ñâîáîäíûõ ñðåäñòâ íà ñ÷¸òå
|
|
BALANCE, //MM îò áàëàíñà ñðåäñòâ íà ñ÷¸òå
|
|
LOSSFREEMARGIN, //MM ïî óáûòêàì îò ñâîáîäíûõ ñðåäñòâ íà ñ÷¸òå
|
|
LOSSBALANCE, //MM ïî óáûòêàì îò áàëàíñà ñðåäñòâ íà ñ÷¸òå
|
|
LOT //Ëîò áåç èçìåíåíèÿ
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Àëãîðèòì îïðåäåëåíèÿ ìîìåíòà ïîÿâëåíèÿ íîâîãî áàðà |
|
|
//+------------------------------------------------------------------+
|
|
class CIsNewBar
|
|
{
|
|
//----
|
|
public:
|
|
//---- ôóíêöèÿ îïðåäåëåíèÿ ìîìåíòà ïîÿâëåíèÿ íîâîãî áàðà
|
|
bool IsNewBar(string symbol,ENUM_TIMEFRAMES timeframe)
|
|
{
|
|
//---- ïîëó÷èì âðåìÿ ïîÿâëåíèÿ òåêóùåãî áàðà
|
|
datetime TNew=datetime(SeriesInfoInteger(symbol,timeframe,SERIES_LASTBAR_DATE));
|
|
|
|
if(TNew!=m_TOld && TNew) // ïðîâåðêà íà ïîÿâëåíèå íîâîãî áàðà
|
|
{
|
|
m_TOld=TNew;
|
|
return(true); // ïîÿâèëñÿ íîâûé áàð!
|
|
}
|
|
//----
|
|
return(false); // íîâûõ áàðîâ ïîêà íåò!
|
|
};
|
|
|
|
//---- êîíñòðóêòîð êëàññà
|
|
CIsNewBar(){m_TOld=-1;};
|
|
|
|
protected: datetime m_TOld;
|
|
//----
|
|
};
|
|
//+==================================================================+
|
|
//| Àëãîðèòìû äëÿ òîðãîâûõ îïåðàöèé |
|
|
//+==================================================================+
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Îòêðûâàåì äëèííóþ ïîçèöèþ |
|
|
//+------------------------------------------------------------------+
|
|
bool BuyPositionOpen
|
|
(
|
|
bool &BUY_Signal, // ôëàã ðàçðåøåíèÿ íà ñäåëêó
|
|
const string symbol, // òîðãîâàÿ ïàðà ñäåëêè
|
|
const datetime &TimeLevel, // âðåìÿ, ïîñëå êîòîðîãî áóäåò îñóùåñòâëåíà ñëåäóùàÿ ñäåëêà ïîñëå òåêóùåé
|
|
double Money_Management, // MM
|
|
int Margin_Mode, // ñïîñîá ðàñ÷¸òà âåëè÷èíû ëîòà
|
|
uint deviation, // ñëèïïàæ
|
|
int StopLoss, // ñòîïëîññ â ïóíêòàõ
|
|
int Takeprofit // òåéêïðîôèò â ïóíêòàõ
|
|
)
|
|
//BuyPositionOpen(BUY_Signal,symbol,TimeLevel,Money_Management,deviation,Margin_Mode,StopLoss,Takeprofit);
|
|
{
|
|
//----
|
|
if(!BUY_Signal) return(true);
|
|
|
|
ENUM_POSITION_TYPE PosType=POSITION_TYPE_BUY;
|
|
//---- Ïðîâåðêà íà èñòå÷åíèå âðåìåííîãî ëèìèòà äëÿ ïðåäûäóùåé ñäåëêè è ïîëíîòû îáú¸ìà
|
|
if(!TradeTimeLevelCheck(symbol,PosType,TimeLevel)) return(true);
|
|
|
|
//---- Ïðîâåðêà íà íà íàëè÷èå îòêðûòîé ïîçèöèè
|
|
if(PositionSelect(symbol)) return(true);
|
|
|
|
//----
|
|
double volume=BuyLotCount(symbol,Money_Management,Margin_Mode,StopLoss,deviation);
|
|
if(volume<=0)
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâåðíûé îáú¸ì äëÿ ñòðóêòóðû òîðãîâîãî çàïðîñà");
|
|
return(false);
|
|
}
|
|
|
|
//---- Îáúÿâëåíèå ñòðóêòóð òîðãîâîãî çàïðîñà è ðåçóëüòàòà òîðãîâîãî çàïðîñà
|
|
MqlTradeRequest request;
|
|
MqlTradeResult result;
|
|
//---- Îáúÿâëåíèå ñòðóêòóðû ðåçóëüòàòà ïðîâåðêè òîðãîâîãî çàïðîñà
|
|
MqlTradeCheckResult check;
|
|
|
|
//---- îáíóëåíèå ñòðóêòóð
|
|
ZeroMemory(request);
|
|
ZeroMemory(result);
|
|
ZeroMemory(check);
|
|
|
|
long digit;
|
|
double point,Ask;
|
|
//----
|
|
if(!SymbolInfoInteger(symbol,SYMBOL_DIGITS,digit)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_POINT,point)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_ASK,Ask)) return(true);
|
|
|
|
//---- Èíèöèàëèçàöèÿ ñòðóêòóðû òîðãîâîãî çàïðîñà MqlTradeRequest äëÿ îòêðûâàíèÿ BUY ïîçèöèè
|
|
request.type = ORDER_TYPE_BUY;
|
|
request.price = Ask;
|
|
request.action = TRADE_ACTION_DEAL;
|
|
request.symbol = symbol;
|
|
request.volume = volume;
|
|
|
|
//---- Îïðåäåëåíèå ðàññòîÿíèÿ äî ñòîïëîññà â åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
if(StopLoss)
|
|
{
|
|
if(!StopCorrect(symbol,StopLoss))return(false);
|
|
double dStopLoss=StopLoss*point;
|
|
request.sl=NormalizeDouble(request.price-dStopLoss,int(digit));
|
|
}
|
|
else request.sl=0.0;
|
|
|
|
//---- Îïðåäåëåíèå ðàññòîÿíèÿ äî òåéêïðîôèòà åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
if(Takeprofit)
|
|
{
|
|
if(!StopCorrect(symbol,Takeprofit))return(false);
|
|
double dTakeprofit=Takeprofit*point;
|
|
request.tp=NormalizeDouble(request.price+dTakeprofit,int(digit));
|
|
}
|
|
else request.tp=0.0;
|
|
|
|
//----
|
|
request.deviation=deviation;
|
|
request.type_filling=ORDER_FILLING_FOK;
|
|
|
|
//---- Ïðîâåðêà òîðãîâîãî çàïðîñà íà êîððåêòíîñòü
|
|
if(!OrderCheck(request,check))
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâåðíûå äàííûå äëÿ ñòðóêòóðû òîðãîâîãî çàïðîñà!");
|
|
Print(__FUNCTION__,"(): OrderCheck(): ",ResultRetcodeDescription(check.retcode));
|
|
return(false);
|
|
}
|
|
|
|
string comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Îòêðûâàåì Buy ïîçèöèþ ïî ",symbol," ============ >>>");
|
|
Print(comment);
|
|
|
|
//---- Îòêðûâàåì BUY ïîçèöèþ è äåëàåì ïðîâåðêó ðåçóëüòàòà òîðãîâîãî çàïðîñà
|
|
if(!OrderSend(request,result) || result.retcode!=TRADE_RETCODE_DONE)
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâîçìîæíî ñîâåðøèòü ñäåëêó!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
return(false);
|
|
}
|
|
else
|
|
if(result.retcode==TRADE_RETCODE_DONE)
|
|
{
|
|
TradeTimeLevelSet(symbol,PosType,TimeLevel);
|
|
BUY_Signal=false;
|
|
comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Buy ïîçèöèÿ ïî ",symbol," îòêðûòà ============ >>>");
|
|
Print(comment);
|
|
PlaySound("ok.wav");
|
|
}
|
|
else
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâîçìîæíî ñîâåðøèòü ñäåëêó!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
}
|
|
//----
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Îòêðûâàåì êîðîòêóþ ïîçèöèþ |
|
|
//+------------------------------------------------------------------+
|
|
bool SellPositionOpen
|
|
(
|
|
bool &SELL_Signal, // ôëàã ðàçðåøåíèÿ íà ñäåëêó
|
|
const string symbol, // òîðãîâàÿ ïàðà ñäåëêè
|
|
const datetime &TimeLevel, // âðåìÿ, ïîñëå êîòîðîãî áóäåò îñóùåñòâëåíà ñëåäóùàÿ ñäåëêà ïîñëå òåêóùåé
|
|
double Money_Management, // MM
|
|
int Margin_Mode, // ñïîñîá ðàñ÷¸òà âåëè÷èíû ëîòà
|
|
uint deviation, // ñëèïïàæ
|
|
int StopLoss, // ñòîïëîññ â ïóíêòàõ
|
|
int Takeprofit // òåéêïðîôèò â ïóíêòàõ
|
|
)
|
|
//SellPositionOpen(SELL_Signal,symbol,TimeLevel,Money_Management,deviation,Margin_Mode,StopLoss,Takeprofit);
|
|
{
|
|
//----
|
|
if(!SELL_Signal) return(true);
|
|
|
|
ENUM_POSITION_TYPE PosType=POSITION_TYPE_SELL;
|
|
//---- Ïðîâåðêà íà èñòå÷åíèå âðåìåííîãî ëèìèòà äëÿ ïðåäûäóùåé ñäåëêè è ïîëíîòû îáú¸ìà
|
|
if(!TradeTimeLevelCheck(symbol,PosType,TimeLevel)) return(true);
|
|
|
|
//---- Ïðîâåðêà íà íà íàëè÷èå îòêðûòîé ïîçèöèè
|
|
if(PositionSelect(symbol)) return(true);
|
|
|
|
//----
|
|
double volume=SellLotCount(symbol,Money_Management,Margin_Mode,StopLoss,deviation);
|
|
if(volume<=0)
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâåðíûé îáú¸ì äëÿ ñòðóêòóðû òîðãîâîãî çàïðîñà");
|
|
return(false);
|
|
}
|
|
|
|
//---- Îáúÿâëåíèå ñòðóêòóð òîðãîâîãî çàïðîñà è ðåçóëüòàòà òîðãîâîãî çàïðîñà
|
|
MqlTradeRequest request;
|
|
MqlTradeResult result;
|
|
//---- Îáúÿâëåíèå ñòðóêòóðû ðåçóëüòàòà ïðîâåðêè òîðãîâîãî çàïðîñà
|
|
MqlTradeCheckResult check;
|
|
|
|
//---- îáíóëåíèå ñòðóêòóð
|
|
ZeroMemory(request);
|
|
ZeroMemory(result);
|
|
ZeroMemory(check);
|
|
|
|
long digit;
|
|
double point,Bid;
|
|
//----
|
|
if(!SymbolInfoInteger(symbol,SYMBOL_DIGITS,digit)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_POINT,point)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_BID,Bid)) return(true);
|
|
|
|
//---- Èíèöèàëèçàöèÿ ñòðóêòóðû òîðãîâîãî çàïðîñà MqlTradeRequest äëÿ îòêðûâàíèÿ SELL ïîçèöèè
|
|
request.type = ORDER_TYPE_SELL;
|
|
request.price = Bid;
|
|
request.action = TRADE_ACTION_DEAL;
|
|
request.symbol = symbol;
|
|
request.volume = volume;
|
|
|
|
//---- Îïðåäåëåíèå ðàññòîÿíèÿ äî ñòîïëîññà â åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
if(StopLoss!=0)
|
|
{
|
|
if(!StopCorrect(symbol,StopLoss))return(false);
|
|
double dStopLoss=StopLoss*point;
|
|
request.sl=NormalizeDouble(request.price+dStopLoss,int(digit));
|
|
}
|
|
else request.sl=0.0;
|
|
|
|
//---- Îïðåäåëåíèå ðàññòîÿíèÿ äî òåéêïðîôèòà åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
if(Takeprofit!=0)
|
|
{
|
|
if(!StopCorrect(symbol,Takeprofit))return(false);
|
|
double dTakeprofit=Takeprofit*point;
|
|
request.tp=NormalizeDouble(request.price-dTakeprofit,int(digit));
|
|
}
|
|
else request.tp=0.0;
|
|
//----
|
|
request.deviation=deviation;
|
|
request.type_filling=ORDER_FILLING_FOK;
|
|
|
|
//---- Ïðîâåðêà òîðãîâîãî çàïðîñà íà êîððåêòíîñòü
|
|
if(!OrderCheck(request,check))
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâåðíûå äàííûå äëÿ ñòðóêòóðû òîðãîâîãî çàïðîñà!");
|
|
Print(__FUNCTION__,"(): OrderCheck(): ",ResultRetcodeDescription(check.retcode));
|
|
return(false);
|
|
}
|
|
|
|
string comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Îòêðûâàåì Sell ïîçèöèþ ïî ",symbol," ============ >>>");
|
|
Print(comment);
|
|
|
|
//---- Îòêðûâàåì SELL ïîçèöèþ è äåëàåì ïðîâåðêó ðåçóëüòàòà òîðãîâîãî çàïðîñà
|
|
if(!OrderSend(request,result) || result.retcode!=TRADE_RETCODE_DONE)
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâîçìîæíî ñîâåðøèòü ñäåëêó!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
return(false);
|
|
}
|
|
else
|
|
if(result.retcode==TRADE_RETCODE_DONE)
|
|
{
|
|
TradeTimeLevelSet(symbol,PosType,TimeLevel);
|
|
SELL_Signal=false;
|
|
comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Sell ïîçèöèÿ ïî ",symbol," îòêðûòà ============ >>>");
|
|
Print(comment);
|
|
PlaySound("ok.wav");
|
|
}
|
|
else
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâîçìîæíî ñîâåðøèòü ñäåëêó!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
}
|
|
//----
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Îòêðûâàåì äëèííóþ ïîçèöèþ |
|
|
//+------------------------------------------------------------------+
|
|
bool BuyPositionOpen
|
|
(
|
|
bool &BUY_Signal, // ôëàã ðàçðåøåíèÿ íà ñäåëêó
|
|
const string symbol, // òîðãîâàÿ ïàðà ñäåëêè
|
|
const datetime &TimeLevel, // âðåìÿ, ïîñëå êîòîðîãî áóäåò îñóùåñòâëåíà ñëåäóùàÿ ñäåëêà ïîñëå òåêóùåé
|
|
double Money_Management, // MM
|
|
int Margin_Mode, // ñïîñîá ðàñ÷¸òà âåëè÷èíû ëîòà
|
|
uint deviation, // ñëèïïàæ
|
|
double dStopLoss, // ñòîïëîññ â åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
double dTakeprofit // òåéêïðîôèò â åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
)
|
|
//BuyPositionOpen(BUY_Signal,symbol,TimeLevel,Money_Management,deviation,Margin_Mode,StopLoss,Takeprofit);
|
|
{
|
|
//----
|
|
if(!BUY_Signal) return(true);
|
|
|
|
ENUM_POSITION_TYPE PosType=POSITION_TYPE_BUY;
|
|
//---- Ïðîâåðêà íà èñòå÷åíèå âðåìåííîãî ëèìèòà äëÿ ïðåäûäóùåé ñäåëêè è ïîëíîòû îáú¸ìà
|
|
if(!TradeTimeLevelCheck(symbol,PosType,TimeLevel)) return(true);
|
|
|
|
//---- Ïðîâåðêà íà íà íàëè÷èå îòêðûòîé ïîçèöèè
|
|
if(PositionSelect(symbol)) return(true);
|
|
|
|
//---- Îáúÿâëåíèå ñòðóêòóð òîðãîâîãî çàïðîñà è ðåçóëüòàòà òîðãîâîãî çàïðîñà
|
|
MqlTradeRequest request;
|
|
MqlTradeResult result;
|
|
//---- Îáúÿâëåíèå ñòðóêòóðû ðåçóëüòàòà ïðîâåðêè òîðãîâîãî çàïðîñà
|
|
MqlTradeCheckResult check;
|
|
|
|
//---- îáíóëåíèå ñòðóêòóð
|
|
ZeroMemory(request);
|
|
ZeroMemory(result);
|
|
ZeroMemory(check);
|
|
|
|
long digit;
|
|
double point,Ask;
|
|
//----
|
|
if(!SymbolInfoInteger(symbol,SYMBOL_DIGITS,digit)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_POINT,point)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_ASK,Ask)) return(true);
|
|
|
|
//---- êîððåêöèÿ ðàññòîÿíèé äî ñòîïëîññà è òåéêïðîôèòà â åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
if(!dStopCorrect(symbol,dStopLoss,dTakeprofit,PosType)) return(false);
|
|
int StopLoss=int((Ask-dStopLoss)/point);
|
|
//----
|
|
double volume=BuyLotCount(symbol,Money_Management,Margin_Mode,StopLoss,deviation);
|
|
if(volume<=0)
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâåðíûé îáú¸ì äëÿ ñòðóêòóðû òîðãîâîãî çàïðîñà");
|
|
return(false);
|
|
}
|
|
|
|
//---- Èíèöèàëèçàöèÿ ñòðóêòóðû òîðãîâîãî çàïðîñà MqlTradeRequest äëÿ îòêðûâàíèÿ BUY ïîçèöèè
|
|
request.type = ORDER_TYPE_BUY;
|
|
request.price = Ask;
|
|
request.action = TRADE_ACTION_DEAL;
|
|
request.symbol = symbol;
|
|
request.volume = volume;
|
|
request.sl=dStopLoss;
|
|
request.tp=dTakeprofit;
|
|
request.deviation=deviation;
|
|
request.type_filling=ORDER_FILLING_FOK;
|
|
|
|
//---- Ïðîâåðêà òîðãîâîãî çàïðîñà íà êîððåêòíîñòü
|
|
if(!OrderCheck(request,check))
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâåðíûå äàííûå äëÿ ñòðóêòóðû òîðãîâîãî çàïðîñà!");
|
|
Print(__FUNCTION__,"(): OrderCheck(): ",ResultRetcodeDescription(check.retcode));
|
|
return(false);
|
|
}
|
|
|
|
string comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Îòêðûâàåì Buy ïîçèöèþ ïî ",symbol," ============ >>>");
|
|
Print(comment);
|
|
|
|
//---- Îòêðûâàåì BUY ïîçèöèþ è äåëàåì ïðîâåðêó ðåçóëüòàòà òîðãîâîãî çàïðîñà
|
|
if(!OrderSend(request,result) || result.retcode!=TRADE_RETCODE_DONE)
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâîçìîæíî ñîâåðøèòü ñäåëêó!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
return(false);
|
|
}
|
|
else
|
|
if(result.retcode==TRADE_RETCODE_DONE)
|
|
{
|
|
TradeTimeLevelSet(symbol,PosType,TimeLevel);
|
|
BUY_Signal=false;
|
|
comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Buy ïîçèöèÿ ïî ",symbol," îòêðûòà ============ >>>");
|
|
Print(comment);
|
|
PlaySound("ok.wav");
|
|
}
|
|
else
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâîçìîæíî ñîâåðøèòü ñäåëêó!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
}
|
|
//----
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Îòêðûâàåì êîðîòêóþ ïîçèöèþ |
|
|
//+------------------------------------------------------------------+
|
|
bool SellPositionOpen
|
|
(
|
|
bool &SELL_Signal, // ôëàã ðàçðåøåíèÿ íà ñäåëêó
|
|
const string symbol, // òîðãîâàÿ ïàðà ñäåëêè
|
|
const datetime &TimeLevel, // âðåìÿ, ïîñëå êîòîðîãî áóäåò îñóùåñòâëåíà ñëåäóùàÿ ñäåëêà ïîñëå òåêóùåé
|
|
double Money_Management, // MM
|
|
int Margin_Mode, // ñïîñîá ðàñ÷¸òà âåëè÷èíû ëîòà
|
|
uint deviation, // ñëèïïàæ
|
|
double dStopLoss, // ñòîïëîññ â åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
double dTakeprofit // òåéêïðîôèò â åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
)
|
|
//SellPositionOpen(SELL_Signal,symbol,TimeLevel,Money_Management,deviation,Margin_Mode,StopLoss,Takeprofit);
|
|
{
|
|
//----
|
|
if(!SELL_Signal) return(true);
|
|
|
|
ENUM_POSITION_TYPE PosType=POSITION_TYPE_SELL;
|
|
//---- Ïðîâåðêà íà èñòå÷åíèå âðåìåííîãî ëèìèòà äëÿ ïðåäûäóùåé ñäåëêè è ïîëíîòû îáú¸ìà
|
|
if(!TradeTimeLevelCheck(symbol,PosType,TimeLevel)) return(true);
|
|
|
|
//---- Ïðîâåðêà íà íà íàëè÷èå îòêðûòîé ïîçèöèè
|
|
if(PositionSelect(symbol)) return(true);
|
|
|
|
//---- Îáúÿâëåíèå ñòðóêòóð òîðãîâîãî çàïðîñà è ðåçóëüòàòà òîðãîâîãî çàïðîñà
|
|
MqlTradeRequest request;
|
|
MqlTradeResult result;
|
|
//---- Îáúÿâëåíèå ñòðóêòóðû ðåçóëüòàòà ïðîâåðêè òîðãîâîãî çàïðîñà
|
|
MqlTradeCheckResult check;
|
|
|
|
//---- îáíóëåíèå ñòðóêòóð
|
|
ZeroMemory(request);
|
|
ZeroMemory(result);
|
|
ZeroMemory(check);
|
|
|
|
long digit;
|
|
double point,Bid;
|
|
//----
|
|
if(!SymbolInfoInteger(symbol,SYMBOL_DIGITS,digit)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_POINT,point)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_BID,Bid)) return(true);
|
|
|
|
//---- êîððåêöèÿ ðàññòîÿíèé äî ñòîïëîññà è òåéêïðîôèòà â åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
if(!dStopCorrect(symbol,dStopLoss,dTakeprofit,PosType)) return(false);
|
|
int StopLoss=int((dStopLoss-Bid)/point);
|
|
//----
|
|
double volume=SellLotCount(symbol,Money_Management,Margin_Mode,StopLoss,deviation);
|
|
if(volume<=0)
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâåðíûé îáú¸ì äëÿ ñòðóêòóðû òîðãîâîãî çàïðîñà");
|
|
return(false);
|
|
}
|
|
|
|
//---- Èíèöèàëèçàöèÿ ñòðóêòóðû òîðãîâîãî çàïðîñà MqlTradeRequest äëÿ îòêðûâàíèÿ SELL ïîçèöèè
|
|
request.type = ORDER_TYPE_SELL;
|
|
request.price = Bid;
|
|
request.action = TRADE_ACTION_DEAL;
|
|
request.symbol = symbol;
|
|
request.volume = volume;
|
|
request.deviation=deviation;
|
|
request.type_filling=ORDER_FILLING_FOK;
|
|
|
|
//---- Ïðîâåðêà òîðãîâîãî çàïðîñà íà êîððåêòíîñòü
|
|
if(!OrderCheck(request,check))
|
|
{
|
|
Print(__FUNCTION__,"(): OrderCheck(): Íåâåðíûå äàííûå äëÿ ñòðóêòóðû òîðãîâîãî çàïðîñà!");
|
|
Print(__FUNCTION__,"(): OrderCheck(): ",ResultRetcodeDescription(check.retcode));
|
|
return(false);
|
|
}
|
|
|
|
string comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Îòêðûâàåì Sell ïîçèöèþ ïî ",symbol," ============ >>>");
|
|
Print(comment);
|
|
|
|
//---- Îòêðûâàåì SELL ïîçèöèþ è äåëàåì ïðîâåðêó ðåçóëüòàòà òîðãîâîãî çàïðîñà
|
|
if(!OrderSend(request,result) || result.retcode!=TRADE_RETCODE_DONE)
|
|
{
|
|
Print(__FUNCTION__,"(): OrderSend(): Íåâîçìîæíî ñîâåðøèòü ñäåëêó!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
return(false);
|
|
}
|
|
else
|
|
if(result.retcode==TRADE_RETCODE_DONE)
|
|
{
|
|
TradeTimeLevelSet(symbol,PosType,TimeLevel);
|
|
SELL_Signal=false;
|
|
comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Sell ïîçèöèÿ ïî ",symbol," îòêðûòà ============ >>>");
|
|
Print(comment);
|
|
PlaySound("ok.wav");
|
|
}
|
|
else
|
|
{
|
|
Print(__FUNCTION__,"(): OrderSend(): Íåâîçìîæíî ñîâåðøèòü ñäåëêó!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
}
|
|
//----
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Çàêðûâàåì äëèííóþ ïîçèöèþ |
|
|
//+------------------------------------------------------------------+
|
|
bool BuyPositionClose
|
|
(
|
|
bool &Signal, // ôëàã ðàçðåøåíèÿ íà ñäåëêó
|
|
const string symbol, // òîðãîâàÿ ïàðà ñäåëêè
|
|
uint deviation // ñëèïïàæ
|
|
)
|
|
{
|
|
//----
|
|
if(!Signal) return(true);
|
|
|
|
//---- Îáúÿâëåíèå ñòðóêòóð òîðãîâîãî çàïðîñà è ðåçóëüòàòà òîðãîâîãî çàïðîñà
|
|
MqlTradeRequest request;
|
|
MqlTradeResult result;
|
|
//---- Îáúÿâëåíèå ñòðóêòóðû ðåçóëüòàòà ïðîâåðêè òîðãîâîãî çàïðîñà
|
|
MqlTradeCheckResult check;
|
|
|
|
//---- îáíóëåíèå ñòðóêòóð
|
|
ZeroMemory(request);
|
|
ZeroMemory(result);
|
|
ZeroMemory(check);
|
|
|
|
//---- Ïðîâåðêà íà íàëè÷èå îòêðûòîé BUY ïîçèöèè
|
|
if(PositionSelect(symbol))
|
|
{
|
|
if(PositionGetInteger(POSITION_TYPE)!=POSITION_TYPE_BUY) return(false);
|
|
}
|
|
else return(false);
|
|
|
|
double MaxLot,volume,Bid;
|
|
//---- ïîëó÷åíèå äàííûõ äëÿ ðàñ÷¸òà
|
|
if(!PositionGetDouble(POSITION_VOLUME,volume)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX,MaxLot)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_BID,Bid)) return(true);
|
|
|
|
//---- ïðîâåðêà ëîòà íà ìàêñèìàëüíîå äîïóñòèìîå çíà÷åíèå
|
|
if(volume>MaxLot) volume=MaxLot;
|
|
|
|
//---- Èíèöèàëèçàöèÿ ñòðóêòóðû òîðãîâîãî çàïðîñà MqlTradeRequest äëÿ çàêðûâàíèÿ BUY ïîçèöèè
|
|
request.type = ORDER_TYPE_SELL;
|
|
request.price = Bid;
|
|
request.action = TRADE_ACTION_DEAL;
|
|
request.symbol = symbol;
|
|
request.volume = volume;
|
|
request.sl = 0.0;
|
|
request.tp = 0.0;
|
|
request.deviation=deviation;
|
|
request.type_filling=ORDER_FILLING_FOK;
|
|
|
|
//---- Ïðîâåðêà òîðãîâîãî çàïðîñà íà êîððåêòíîñòü
|
|
if(!OrderCheck(request,check))
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâåðíûå äàííûå äëÿ ñòðóêòóðû òîðãîâîãî çàïðîñà!");
|
|
Print(__FUNCTION__,"(): OrderCheck(): ",ResultRetcodeDescription(check.retcode));
|
|
return(false);
|
|
}
|
|
//----
|
|
string comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Çàêðûâàåì Buy ïîçèöèþ ïî ",symbol," ============ >>>");
|
|
Print(comment);
|
|
|
|
//---- Îòïðàâêà ïðèêàçà íà çàêðûâàíèå ïîçèöèè íà òîðãîâûé ñåðâåð
|
|
if(!OrderSend(request,result) || result.retcode!=TRADE_RETCODE_DONE)
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâîçìîæíî çàêðûòü ïîçèöèþ!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
return(false);
|
|
}
|
|
else
|
|
if(result.retcode==TRADE_RETCODE_DONE)
|
|
{
|
|
Signal=false;
|
|
comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Buy ïîçèöèÿ ïî ",symbol," çàêðûòà ============ >>>");
|
|
Print(comment);
|
|
PlaySound("ok.wav");
|
|
}
|
|
else
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâîçìîæíî çàêðûòü ïîçèöèþ!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
}
|
|
//----
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Çàêðûâàåì êîðîòêóþ ïîçèöèþ |
|
|
//+------------------------------------------------------------------+
|
|
bool SellPositionClose
|
|
(
|
|
bool &Signal, // ôëàã ðàçðåøåíèÿ íà ñäåëêó
|
|
const string symbol, // òîðãîâàÿ ïàðà ñäåëêè
|
|
uint deviation // ñëèïïàæ
|
|
)
|
|
{
|
|
//----
|
|
if(!Signal) return(true);
|
|
|
|
//---- Îáúÿâëåíèå ñòðóêòóð òîðãîâîãî çàïðîñà è ðåçóëüòàòà òîðãîâîãî çàïðîñà
|
|
MqlTradeRequest request;
|
|
MqlTradeResult result;
|
|
//---- Îáúÿâëåíèå ñòðóêòóðû ðåçóëüòàòà ïðîâåðêè òîðãîâîãî çàïðîñà
|
|
MqlTradeCheckResult check;
|
|
|
|
//---- îáíóëåíèå ñòðóêòóð
|
|
ZeroMemory(request);
|
|
ZeroMemory(result);
|
|
ZeroMemory(check);
|
|
|
|
//---- Ïðîâåðêà íà íàëè÷èå îòêðûòîé SELL ïîçèöèè
|
|
if(PositionSelect(symbol))
|
|
{
|
|
if(PositionGetInteger(POSITION_TYPE)!=POSITION_TYPE_SELL)return(false);
|
|
}
|
|
else return(false);
|
|
|
|
double MaxLot,volume,Ask;
|
|
//---- ïîëó÷åíèå äàííûõ äëÿ ðàñ÷¸òà
|
|
if(!PositionGetDouble(POSITION_VOLUME,volume)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX,MaxLot)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_ASK,Ask)) return(true);
|
|
|
|
//---- ïðîâåðêà ëîòà íà ìàêñèìàëüíîå äîïóñòèìîå çíà÷åíèå
|
|
if(volume>MaxLot) volume=MaxLot;
|
|
|
|
//---- Èíèöèàëèçàöèÿ ñòðóêòóðû òîðãîâîãî çàïðîñà MqlTradeRequest äëÿ çàêðûâàíèÿ SELL ïîçèöèè
|
|
request.type = ORDER_TYPE_BUY;
|
|
request.price = Ask;
|
|
request.action = TRADE_ACTION_DEAL;
|
|
request.symbol = symbol;
|
|
request.volume = volume;
|
|
request.sl = 0.0;
|
|
request.tp = 0.0;
|
|
request.deviation=deviation;
|
|
request.type_filling=ORDER_FILLING_FOK;
|
|
|
|
//---- Ïðîâåðêà òîðãîâîãî çàïðîñà íà êîððåêòíîñòü
|
|
if(!OrderCheck(request,check))
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâåðíûå äàííûå äëÿ ñòðóêòóðû òîðãîâîãî çàïðîñà!");
|
|
Print(__FUNCTION__,"(): OrderCheck(): ",ResultRetcodeDescription(check.retcode));
|
|
return(false);
|
|
}
|
|
//----
|
|
string comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Çàêðûâàåì Sell ïîçèöèþ ïî ",symbol," ============ >>>");
|
|
Print(comment);
|
|
|
|
//---- Îòïðàâêà ïðèêàçà íà çàêðûâàíèå ïîçèöèè íà òîðãîâûé ñåðâåð
|
|
if(!OrderSend(request,result) || result.retcode!=TRADE_RETCODE_DONE)
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâîçìîæíî çàêðûòü ïîçèöèþ!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
return(false);
|
|
}
|
|
else
|
|
if(result.retcode==TRADE_RETCODE_DONE)
|
|
{
|
|
Signal=false;
|
|
}
|
|
else
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâîçìîæíî çàêðûòü ïîçèöèþ!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Sell ïîçèöèÿ ïî ",symbol," çàêðûòà ============ >>>");
|
|
Print(comment);
|
|
PlaySound("ok.wav");
|
|
}
|
|
//----
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Ìîäèôèöèðóåì äëèííóþ ïîçèöèþ |
|
|
//+------------------------------------------------------------------+
|
|
bool BuyPositionModify
|
|
(
|
|
bool &Modify_Signal, // ôëàã ðàçðåøåíèÿ ìîäèôèêàöèè
|
|
const string symbol, // òîðãîâàÿ ïàðà ñäåëêè
|
|
uint deviation, // ñëèïïàæ
|
|
int StopLoss, // ñòîïëîññ â ïóíêòàõ
|
|
int Takeprofit // òåéêïðîôèò â ïóíêòàõ
|
|
)
|
|
//BuyPositionModify(Modify_Signal,symbol,deviation,StopLoss,Takeprofit);
|
|
{
|
|
//----
|
|
if(!Modify_Signal) return(true);
|
|
|
|
ENUM_POSITION_TYPE PosType=POSITION_TYPE_BUY;
|
|
|
|
//---- Ïðîâåðêà íà íà íàëè÷èå îòêðûòîé ïîçèöèè
|
|
if(!PositionSelect(symbol)) return(true);
|
|
|
|
//---- Îáúÿâëåíèå ñòðóêòóð òîðãîâîãî çàïðîñà è ðåçóëüòàòà òîðãîâîãî çàïðîñà
|
|
MqlTradeRequest request;
|
|
MqlTradeResult result;
|
|
|
|
//---- Îáúÿâëåíèå ñòðóêòóðû ðåçóëüòàòà ïðîâåðêè òîðãîâîãî çàïðîñà
|
|
MqlTradeCheckResult check;
|
|
|
|
//---- îáíóëåíèå ñòðóêòóð
|
|
ZeroMemory(request);
|
|
ZeroMemory(result);
|
|
ZeroMemory(check);
|
|
|
|
long digit;
|
|
double point,Ask;
|
|
//----
|
|
if(!SymbolInfoInteger(symbol,SYMBOL_DIGITS,digit)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_POINT,point)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_ASK,Ask)) return(true);
|
|
|
|
//---- Èíèöèàëèçàöèÿ ñòðóêòóðû òîðãîâîãî çàïðîñà MqlTradeRequest äëÿ îòêðûâàíèÿ BUY ïîçèöèè
|
|
request.type = ORDER_TYPE_BUY;
|
|
request.price = Ask;
|
|
request.action = TRADE_ACTION_SLTP;
|
|
request.symbol = symbol;
|
|
|
|
//---- Îïðåäåëåíèå ðàññòîÿíèÿ äî ñòîïëîññà â åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
if(StopLoss)
|
|
{
|
|
if(!StopCorrect(symbol,StopLoss))return(false);
|
|
double dStopLoss=StopLoss*point;
|
|
request.sl=NormalizeDouble(request.price-dStopLoss,int(digit));
|
|
if(request.sl<PositionGetDouble(POSITION_SL)) request.sl=PositionGetDouble(POSITION_SL);
|
|
}
|
|
else request.sl=PositionGetDouble(POSITION_SL);
|
|
|
|
//---- Îïðåäåëåíèå ðàññòîÿíèÿ äî òåéêïðîôèòà åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
if(Takeprofit)
|
|
{
|
|
if(!StopCorrect(symbol,Takeprofit))return(false);
|
|
double dTakeprofit=Takeprofit*point;
|
|
request.tp=NormalizeDouble(request.price+dTakeprofit,int(digit));
|
|
if(request.tp<PositionGetDouble(POSITION_TP)) request.tp=PositionGetDouble(POSITION_TP);
|
|
}
|
|
else request.tp=PositionGetDouble(POSITION_TP);
|
|
|
|
//----
|
|
if(request.tp==PositionGetDouble(POSITION_TP) && request.sl==PositionGetDouble(POSITION_SL)) return(true);
|
|
request.deviation=deviation;
|
|
request.type_filling=ORDER_FILLING_FOK;
|
|
|
|
//---- Ïðîâåðêà òîðãîâîãî çàïðîñà íà êîððåêòíîñòü
|
|
if(!OrderCheck(request,check))
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâåðíûå äàííûå äëÿ ñòðóêòóðû òîðãîâîãî çàïðîñà!");
|
|
Print(__FUNCTION__,"(): OrderCheck(): ",ResultRetcodeDescription(check.retcode));
|
|
return(false);
|
|
}
|
|
|
|
string comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Ìîäèôèöèðóåì Buy ïîçèöèþ ïî ",symbol," ============ >>>");
|
|
Print(comment);
|
|
|
|
//---- Ìîäèôèöèðóåì BUY ïîçèöèþ è äåëàåì ïðîâåðêó ðåçóëüòàòà òîðãîâîãî çàïðîñà
|
|
if(!OrderSend(request,result) || result.retcode!=TRADE_RETCODE_DONE)
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâîçìîæíî ìîäèôèöèðîâàòü ïîçèöèþ!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
return(false);
|
|
}
|
|
else
|
|
if(result.retcode==TRADE_RETCODE_DONE)
|
|
{
|
|
Modify_Signal=false;
|
|
comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Buy ïîçèöèÿ ïî ",symbol," ìîäèôèöèðîâàíà ============ >>>");
|
|
Print(comment);
|
|
PlaySound("ok.wav");
|
|
}
|
|
else
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâîçìîæíî ìîäèôèöèðîâàòü ïîçèöèþ!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
}
|
|
//----
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Ìîäèôèöèðóåì êîðîòêóþ ïîçèöèþ |
|
|
//+------------------------------------------------------------------+
|
|
bool SellPositionModify
|
|
(
|
|
bool &Modify_Signal, // ôëàã ðàçðåøåíèÿ ìîäèôèêàöèè
|
|
const string symbol, // òîðãîâàÿ ïàðà ñäåëêè
|
|
uint deviation, // ñëèïïàæ
|
|
int StopLoss, // ñòîïëîññ â ïóíêòàõ
|
|
int Takeprofit // òåéêïðîôèò â ïóíêòàõ
|
|
)
|
|
//SellPositionModify(Modify_Signal,symbol,deviation,StopLoss,Takeprofit);
|
|
{
|
|
//----
|
|
if(!Modify_Signal) return(true);
|
|
|
|
ENUM_POSITION_TYPE PosType=POSITION_TYPE_SELL;
|
|
|
|
//---- Ïðîâåðêà íà íà íàëè÷èå îòêðûòîé ïîçèöèè
|
|
if(!PositionSelect(symbol)) return(true);
|
|
|
|
//---- Îáúÿâëåíèå ñòðóêòóð òîðãîâîãî çàïðîñà è ðåçóëüòàòà òîðãîâîãî çàïðîñà
|
|
MqlTradeRequest request;
|
|
MqlTradeResult result;
|
|
|
|
//---- Îáúÿâëåíèå ñòðóêòóðû ðåçóëüòàòà ïðîâåðêè òîðãîâîãî çàïðîñà
|
|
MqlTradeCheckResult check;
|
|
|
|
//---- îáíóëåíèå ñòðóêòóð
|
|
ZeroMemory(request);
|
|
ZeroMemory(result);
|
|
ZeroMemory(check);
|
|
//----
|
|
long digit;
|
|
double point,Bid;
|
|
//----
|
|
if(!SymbolInfoInteger(symbol,SYMBOL_DIGITS,digit)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_POINT,point)) return(true);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_BID,Bid)) return(true);
|
|
|
|
//---- Èíèöèàëèçàöèÿ ñòðóêòóðû òîðãîâîãî çàïðîñà MqlTradeRequest äëÿ îòêðûâàíèÿ BUY ïîçèöèè
|
|
request.type = ORDER_TYPE_SELL;
|
|
request.price = Bid;
|
|
request.action = TRADE_ACTION_SLTP;
|
|
request.symbol = symbol;
|
|
|
|
//---- Îïðåäåëåíèå ðàññòîÿíèÿ äî ñòîïëîññà â åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
if(StopLoss!=0)
|
|
{
|
|
if(!StopCorrect(symbol,StopLoss))return(false);
|
|
double dStopLoss=StopLoss*point;
|
|
request.sl=NormalizeDouble(request.price+dStopLoss,int(digit));
|
|
double laststop=PositionGetDouble(POSITION_SL);
|
|
if(request.sl>laststop && laststop) request.sl=PositionGetDouble(POSITION_SL);
|
|
}
|
|
else request.sl=PositionGetDouble(POSITION_SL);
|
|
|
|
//---- Îïðåäåëåíèå ðàññòîÿíèÿ äî òåéêïðîôèòà åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
if(Takeprofit!=0)
|
|
{
|
|
if(!StopCorrect(symbol,Takeprofit))return(false);
|
|
double dTakeprofit=Takeprofit*point;
|
|
request.tp=NormalizeDouble(request.price-dTakeprofit,int(digit));
|
|
double lasttake=PositionGetDouble(POSITION_TP);
|
|
if(request.tp>lasttake && lasttake) request.tp=PositionGetDouble(POSITION_TP);
|
|
}
|
|
else request.tp=PositionGetDouble(POSITION_TP);
|
|
|
|
//----
|
|
if(request.tp==PositionGetDouble(POSITION_TP) && request.sl==PositionGetDouble(POSITION_SL)) return(true);
|
|
request.deviation=deviation;
|
|
request.type_filling=ORDER_FILLING_FOK;
|
|
|
|
//---- Ïðîâåðêà òîðãîâîãî çàïðîñà íà êîððåêòíîñòü
|
|
if(!OrderCheck(request,check))
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâåðíûå äàííûå äëÿ ñòðóêòóðû òîðãîâîãî çàïðîñà!");
|
|
Print(__FUNCTION__,"(): OrderCheck(): ",ResultRetcodeDescription(check.retcode));
|
|
return(false);
|
|
}
|
|
|
|
string comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Ìîäèôèöèðóåì Sell ïîçèöèþ ïî ",symbol," ============ >>>");
|
|
Print(comment);
|
|
|
|
//---- Ìîäèôèöèðóåì SELL ïîçèöèþ è äåëàåì ïðîâåðêó ðåçóëüòàòà òîðãîâîãî çàïðîñà
|
|
if(!OrderSend(request,result) || result.retcode!=TRADE_RETCODE_DONE)
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâîçìîæíî ìîäèôèöèðîâàòü ïîçèöèþ!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
return(false);
|
|
}
|
|
else
|
|
if(result.retcode==TRADE_RETCODE_DONE)
|
|
{
|
|
Modify_Signal=false;
|
|
comment="";
|
|
StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Sell ïîçèöèÿ ïî ",symbol," ìîäèôèöèðîâàíà ============ >>>");
|
|
Print(comment);
|
|
PlaySound("ok.wav");
|
|
}
|
|
else
|
|
{
|
|
Print(__FUNCTION__,"(): Íåâîçìîæíî ìîäèôèöèðîâàòü ïîçèöèþ!");
|
|
Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));
|
|
}
|
|
//----
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| GetTimeLevelName() function |
|
|
//+------------------------------------------------------------------+
|
|
string GetTimeLevelName(string symbol,ENUM_POSITION_TYPE trade_operation)
|
|
{
|
|
//----
|
|
string G_Name_;
|
|
//----
|
|
if(MQL5InfoInteger(MQL5_TESTING)
|
|
|| MQL5InfoInteger(MQL5_OPTIMIZATION)
|
|
|| MQL5InfoInteger(MQL5_DEBUGGING))
|
|
StringConcatenate(G_Name_,"TimeLevel_",AccountInfoInteger(ACCOUNT_LOGIN),"_",symbol,"_",trade_operation,"_Test_");
|
|
else StringConcatenate(G_Name_,"TimeLevel_",AccountInfoInteger(ACCOUNT_LOGIN),"_",symbol,"_",trade_operation);
|
|
//----
|
|
return(G_Name_);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| TradeTimeLevelCheck() function |
|
|
//+------------------------------------------------------------------+
|
|
bool TradeTimeLevelCheck
|
|
(
|
|
string symbol,
|
|
ENUM_POSITION_TYPE trade_operation,
|
|
datetime TradeTimeLevel
|
|
)
|
|
{
|
|
//----
|
|
if(TradeTimeLevel>0)
|
|
{
|
|
//---- Ïðîâåðêà íà èñòå÷åíèå âðåìåííîãî ëèìèòà äëÿ ïðåäûäóùåé ñäåëêè
|
|
if(TimeCurrent()<GlobalVariableGet(GetTimeLevelName(symbol,trade_operation))) return(false);
|
|
}
|
|
//----
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| TradeTimeLevelSet() function |
|
|
//+------------------------------------------------------------------+
|
|
void TradeTimeLevelSet
|
|
(
|
|
string symbol,
|
|
ENUM_POSITION_TYPE trade_operation,
|
|
datetime TradeTimeLevel
|
|
)
|
|
{
|
|
//----
|
|
GlobalVariableSet(GetTimeLevelName(symbol,trade_operation),TradeTimeLevel);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| TradeTimeLevelSet() function |
|
|
//+------------------------------------------------------------------+
|
|
datetime TradeTimeLevelGet
|
|
(
|
|
string symbol,
|
|
ENUM_POSITION_TYPE trade_operation
|
|
)
|
|
{
|
|
//----
|
|
return(datetime(GlobalVariableGet(GetTimeLevelName(symbol,trade_operation))));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| TimeLevelGlobalVariableDel() function |
|
|
//+------------------------------------------------------------------+
|
|
void TimeLevelGlobalVariableDel
|
|
(
|
|
string symbol,
|
|
ENUM_POSITION_TYPE trade_operation
|
|
)
|
|
{
|
|
//----
|
|
if(MQL5InfoInteger(MQL5_TESTING)
|
|
|| MQL5InfoInteger(MQL5_OPTIMIZATION)
|
|
|| MQL5InfoInteger(MQL5_DEBUGGING))
|
|
GlobalVariableDel(GetTimeLevelName(symbol,trade_operation));
|
|
//----
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| GlobalVariableDel_() function |
|
|
//+------------------------------------------------------------------+
|
|
void GlobalVariableDel_(string symbol)
|
|
{
|
|
//----
|
|
TimeLevelGlobalVariableDel(symbol,POSITION_TYPE_BUY);
|
|
TimeLevelGlobalVariableDel(symbol,POSITION_TYPE_SELL);
|
|
//----
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Ðàñ÷¸ò ðàçìåðà ëîòà äëÿ îòêðûâàíèÿ ëîíãà |
|
|
//+------------------------------------------------------------------+
|
|
/* |
|
|
Âíåøíÿÿ ïåðåìåííàÿ Margin_Mode îïðåäåëÿåò ñïîñîá ðàñ÷¸òà âåëè÷èíû |
|
|
ëîòà |
|
|
0 - MM ïî ñâîáîäíûì ñðåäñòâàì íà ñ÷¸òå |
|
|
1 - MM ïî áàëàíñó ñðåäñòâ íà ñ÷¸òå |
|
|
2 - MM ïî óáûòêàì îò ñâîáîäíûõ ñðåäñòâ íà ñ÷¸òå |
|
|
3 - MM ïî óáûòêàì îò áàëàíñà ñðåäñòâ íà ñ÷¸òå |
|
|
ïî óìîë÷àíèþ - MM ïî ñâîáîäíûì ñðåäñòâàì íà ñ÷¸òå |
|
|
//+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
|
|
åñëè Money_Management ìåíüøå íóëÿ, òî òîðãîâàÿ ôóíêöèÿ â êà÷åñòâå |
|
|
âåëè÷èíû ëîòà èñïîëüçóåò îêðóãë¸ííóþ äî áëèæàéøåãî ñòàíäàðòíîãî |
|
|
çíà÷åíèÿ àáñîëþòíóþ âåëè÷èíó Money_Management. |
|
|
*/// |
|
|
//+------------------------------------------------------------------+
|
|
double BuyLotCount
|
|
(
|
|
string symbol,
|
|
double Money_Management,
|
|
int Margin_Mode,
|
|
int STOPLOSS,
|
|
uint Slippage_
|
|
)
|
|
// BuyLotCount_(string symbol, double Money_Management, int Margin_Mode, int STOPLOSS,Slippage_)
|
|
{
|
|
//----
|
|
double margin,Lot;
|
|
|
|
//---1+ ÐÀÑ×¨Ò ÂÅËÈ×ÈÍÛ ËÎÒÀ ÄËß ÎÒÊÐÛÂÀÍÈß ÏÎÇÈÖÈÈ
|
|
if(Money_Management<0) Lot=MathAbs(Money_Management);
|
|
else
|
|
switch(Margin_Mode)
|
|
{
|
|
//---- Ðàñ÷¸ò ëîòà îò ñâîáîäíûõ ñðåäñòâ íà ñ÷¸òå
|
|
case 0:
|
|
margin=AccountInfoDouble(ACCOUNT_FREEMARGIN)*Money_Management;
|
|
Lot=GetLotForOpeningPos(symbol,POSITION_TYPE_BUY,margin);
|
|
break;
|
|
|
|
//---- Ðàñ÷¸ò ëîòà îò áàëàíñà ñðåäñòâ íà ñ÷¸òå
|
|
case 1:
|
|
margin=AccountInfoDouble(ACCOUNT_BALANCE)*Money_Management;
|
|
Lot=GetLotForOpeningPos(symbol,POSITION_TYPE_BUY,margin);
|
|
break;
|
|
|
|
//---- Ðàñ÷¸ò ëîòà ïî óáûòêàì îò ñâîáîäíûõ ñðåäñòâ íà ñ÷¸òå
|
|
case 2:
|
|
{
|
|
if(STOPLOSS<=0)
|
|
{
|
|
Print(__FUNCTION__,": Íåâåðíûé ñòîïëîññ!!!");
|
|
STOPLOSS=0;
|
|
}
|
|
//----
|
|
long digit;
|
|
double point,price_open;
|
|
//----
|
|
if(!SymbolInfoInteger(symbol,SYMBOL_DIGITS,digit)) return(-1);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_POINT,point)) return(-1);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_ASK,price_open)) return(-1);
|
|
|
|
//---- Îïðåäåëåíèå ðàññòîÿíèÿ äî ñòîïëîññà â åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
if(!StopCorrect(symbol,STOPLOSS)) return(TRADE_RETCODE_ERROR);
|
|
double price_close=NormalizeDouble(price_open-STOPLOSS*point,int(digit));
|
|
|
|
double profit;
|
|
if(!OrderCalcProfit(ORDER_TYPE_BUY,symbol,1,price_open,price_close,profit)) return(-1);
|
|
if(!profit) return(-1);
|
|
|
|
//---- Ðàñ÷¸ò ïîòåðü îò ñâîáîäíûõ ñðåäñòâ íà ñ÷¸òå
|
|
double Loss=AccountInfoDouble(ACCOUNT_FREEMARGIN)*Money_Management;
|
|
if(!Loss) return(-1);
|
|
|
|
Lot=Loss/MathAbs(profit);
|
|
break;
|
|
}
|
|
|
|
//---- Ðàñ÷¸ò ëîòà ïî óáûòêàì îò áàëàíñà ñðåäñòâ íà ñ÷¸òå
|
|
case 3:
|
|
{
|
|
if(STOPLOSS<=0)
|
|
{
|
|
Print(__FUNCTION__,": Íåâåðíûé ñòîïëîññ!!!");
|
|
STOPLOSS=0;
|
|
}
|
|
//----
|
|
long digit;
|
|
double point,price_open;
|
|
//----
|
|
if(!SymbolInfoInteger(symbol,SYMBOL_DIGITS,digit)) return(-1);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_POINT,point)) return(-1);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_ASK,price_open)) return(-1);
|
|
|
|
//---- Îïðåäåëåíèå ðàññòîÿíèÿ äî ñòîïëîññà â åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
if(!StopCorrect(symbol,STOPLOSS)) return(TRADE_RETCODE_ERROR);
|
|
double price_close=NormalizeDouble(price_open-STOPLOSS*point,int(digit));
|
|
|
|
double profit;
|
|
if(!OrderCalcProfit(ORDER_TYPE_BUY,symbol,1,price_open,price_close,profit)) return(-1);
|
|
if(!profit) return(-1);
|
|
|
|
//---- Ðàñ÷¸ò ïîòåðü îò áàëàíñà ñðåäñòâ íà ñ÷¸òå
|
|
double Loss=AccountInfoDouble(ACCOUNT_BALANCE)*Money_Management;
|
|
if(!Loss) return(-1);
|
|
|
|
Lot=Loss/MathAbs(profit);
|
|
break;
|
|
}
|
|
|
|
//---- Ðàñ÷¸ò ëîòà áåç èçìåíåíèÿ
|
|
case 4:
|
|
{
|
|
Lot=MathAbs(Money_Management);
|
|
break;
|
|
}
|
|
|
|
//---- Ðàñ÷¸ò ëîòà îò ñâîáîäíûõ ñðåäñòâ íà ñ÷¸òå ïî óìîë÷àíèþ
|
|
default:
|
|
{
|
|
margin=AccountInfoDouble(ACCOUNT_FREEMARGIN)*Money_Management;
|
|
Lot=GetLotForOpeningPos(symbol,POSITION_TYPE_BUY,margin);
|
|
}
|
|
}
|
|
//---1+
|
|
|
|
//---- íîðìèðîâàíèå âåëè÷èíû ëîòà äî áëèæàéøåãî ñòàíäàðòíîãî çíà÷åíèÿ
|
|
if(!LotCorrect(symbol,Lot,POSITION_TYPE_BUY)) return(-1);
|
|
//----
|
|
return(Lot);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Ðàñ÷¸ò ðàçìåðà ëîòà äëÿ îòêðûâàíèÿ øîðòà |
|
|
//+------------------------------------------------------------------+
|
|
/* |
|
|
Âíåøíÿÿ ïåðåìåííàÿ Margin_Mode îïðåäåëÿåò ñïîñîá ðàñ÷¸òà âåëè÷èíû |
|
|
ëîòà |
|
|
0 - MM ïî ñâîáîäíûì ñðåäñòâàì íà ñ÷¸òå |
|
|
1 - MM ïî áàëàíñó ñðåäñòâ íà ñ÷¸òå |
|
|
2 - MM ïî óáûòêàì îò ñâîáîäíûõ ñðåäñòâ íà ñ÷¸òå |
|
|
3 - MM ïî óáûòêàì îò áàëàíñà ñðåäñòâ íà ñ÷¸òå |
|
|
ïî óìîë÷àíèþ - MM ïî ñâîáîäíûì ñðåäñòâàì íà ñ÷¸òå |
|
|
//+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
|
|
åñëè Money_Management ìåíüøå íóëÿ, òî òîðãîâàÿ ôóíêöèÿ â êà÷åñòâå |
|
|
âåëè÷èíû ëîòà èñïîëüçóåò îêðóãë¸ííóþ äî áëèæàéøåãî ñòàíäàðòíîãî |
|
|
çíà÷åíèÿ àáñîëþòíóþ âåëè÷èíó Money_Management. |
|
|
*/// |
|
|
//+------------------------------------------------------------------+
|
|
double SellLotCount
|
|
(
|
|
string symbol,
|
|
double Money_Management,
|
|
int Margin_Mode,
|
|
int STOPLOSS,
|
|
uint Slippage_
|
|
)
|
|
// (string symbol, double Money_Management, int Margin_Mode, int STOPLOSS)
|
|
{
|
|
//----
|
|
double margin,Lot;
|
|
|
|
//---1+ ÐÀÑ×¨Ò ÂÅËÈ×ÈÍÛ ËÎÒÀ ÄËß ÎÒÊÐÛÂÀÍÈß ÏÎÇÈÖÈÈ
|
|
if(Money_Management<0) Lot=MathAbs(Money_Management);
|
|
else
|
|
switch(Margin_Mode)
|
|
{
|
|
//---- Ðàñ÷¸ò ëîòà îò ñâîáîäíûõ ñðåäñòâ íà ñ÷¸òå
|
|
case 0:
|
|
margin=AccountInfoDouble(ACCOUNT_FREEMARGIN)*Money_Management;
|
|
Lot=GetLotForOpeningPos(symbol,POSITION_TYPE_SELL,margin);
|
|
break;
|
|
|
|
//---- Ðàñ÷¸ò ëîòà îò áàëàíñà ñðåäñòâ íà ñ÷¸òå
|
|
case 1:
|
|
margin=AccountInfoDouble(ACCOUNT_BALANCE)*Money_Management;
|
|
Lot=GetLotForOpeningPos(symbol,POSITION_TYPE_SELL,margin);
|
|
break;
|
|
|
|
//---- Ðàñ÷¸ò ëîòà ïî óáûòêàì îò ñâîáîäíûõ ñðåäñòâ íà ñ÷¸òå
|
|
case 2:
|
|
{
|
|
if(STOPLOSS<=0)
|
|
{
|
|
Print(__FUNCTION__,": Íåâåðíûé ñòîïëîññ!!!");
|
|
STOPLOSS=0;
|
|
}
|
|
//----
|
|
long digit;
|
|
double point,price_open;
|
|
//----
|
|
if(!SymbolInfoInteger(symbol,SYMBOL_DIGITS,digit)) return(-1);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_POINT,point)) return(-1);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_BID,price_open)) return(-1);
|
|
|
|
//---- Îïðåäåëåíèå ðàññòîÿíèÿ äî ñòîïëîññà â åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
if(!StopCorrect(symbol,STOPLOSS)) return(TRADE_RETCODE_ERROR);
|
|
double price_close=NormalizeDouble(price_open+STOPLOSS*point,int(digit));
|
|
|
|
double profit;
|
|
if(!OrderCalcProfit(ORDER_TYPE_SELL,symbol,1,price_open,price_close,profit)) return(-1);
|
|
if(!profit) return(-1);
|
|
|
|
//---- Ðàñ÷¸ò ïîòåðü îò ñâîáîäíûõ ñðåäñòâ íà ñ÷¸òå
|
|
double Loss=AccountInfoDouble(ACCOUNT_FREEMARGIN)*Money_Management;
|
|
if(!Loss) return(-1);
|
|
|
|
Lot=Loss/MathAbs(profit);
|
|
break;
|
|
}
|
|
|
|
//---- Ðàñ÷¸ò ëîòà ïî óáûòêàì îò áàëàíñà ñðåäñòâ íà ñ÷¸òå
|
|
case 3:
|
|
{
|
|
if(STOPLOSS<=0)
|
|
{
|
|
Print(__FUNCTION__,": Íåâåðíûé ñòîïëîññ!!!");
|
|
STOPLOSS=0;
|
|
}
|
|
//----
|
|
long digit;
|
|
double point,price_open;
|
|
//----
|
|
if(!SymbolInfoInteger(symbol,SYMBOL_DIGITS,digit)) return(-1);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_POINT,point)) return(-1);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_BID,price_open)) return(-1);
|
|
|
|
//---- Îïðåäåëåíèå ðàññòîÿíèÿ äî ñòîïëîññà â åäèíèöàõ öåíîâîãî ãðàôèêà
|
|
if(!StopCorrect(symbol,STOPLOSS)) return(TRADE_RETCODE_ERROR);
|
|
double price_close=NormalizeDouble(price_open+STOPLOSS*point,int(digit));
|
|
|
|
double profit;
|
|
if(!OrderCalcProfit(ORDER_TYPE_SELL,symbol,1,price_open,price_close,profit)) return(-1);
|
|
if(!profit) return(-1);
|
|
|
|
//---- Ðàñ÷¸ò ïîòåðü îò áàëàíñà ñðåäñòâ íà ñ÷¸òå
|
|
double Loss=AccountInfoDouble(ACCOUNT_BALANCE)*Money_Management;
|
|
if(!Loss) return(-1);
|
|
|
|
Lot=Loss/MathAbs(profit);
|
|
break;
|
|
}
|
|
|
|
//---- Ðàñ÷¸ò ëîòà áåç èçìåíåíèÿ
|
|
case 4:
|
|
{
|
|
Lot=MathAbs(Money_Management);
|
|
break;
|
|
}
|
|
|
|
//---- Ðàñ÷¸ò ëîòà îò ñâîáîäíûõ ñðåäñòâ íà ñ÷¸òå ïî óìîë÷àíèþ
|
|
default:
|
|
{
|
|
margin=AccountInfoDouble(ACCOUNT_FREEMARGIN)*Money_Management;
|
|
Lot=GetLotForOpeningPos(symbol,POSITION_TYPE_SELL,margin);
|
|
}
|
|
}
|
|
//---1+
|
|
|
|
//---- íîðìèðîâàíèå âåëè÷èíû ëîòà äî áëèæàéøåãî ñòàíäàðòíîãî çíà÷åíèÿ
|
|
if(!LotCorrect(symbol,Lot,POSITION_TYPE_SELL)) return(-1);
|
|
//----
|
|
return(Lot);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| êîððåêöèÿ ðàçìåðà îòëîæåííîãî îðäåðà äî äîïóñòèìîãî çíà÷åíèÿ |
|
|
//+------------------------------------------------------------------+
|
|
bool StopCorrect(string symbol,int &Stop)
|
|
{
|
|
//----
|
|
long Extrem_Stop;
|
|
if(!SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL,Extrem_Stop)) return(false);
|
|
if(Stop<Extrem_Stop) Stop=int(Extrem_Stop);
|
|
//----
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| êîððåêöèÿ ðàçìåðà îòëîæåííîãî îðäåðà äî äîïóñòèìîãî çíà÷åíèÿ |
|
|
//+------------------------------------------------------------------+
|
|
bool dStopCorrect
|
|
(
|
|
string symbol,
|
|
double &dStopLoss,
|
|
double &dTakeprofit,
|
|
ENUM_POSITION_TYPE trade_operation
|
|
)
|
|
// dStopCorrect(symbol,dStopLoss,dTakeprofit,trade_operation)
|
|
{
|
|
//----
|
|
if(!dStopLoss && !dTakeprofit) return(true);
|
|
|
|
if(dStopLoss<0)
|
|
{
|
|
Print(__FUNCTION__,"(): Îòðèöàòåëüíîå çíà÷åíèå ñòîïëîññà!");
|
|
return(false);
|
|
}
|
|
|
|
if(dTakeprofit<0)
|
|
{
|
|
Print(__FUNCTION__,"(): Îòðèöàòåëüíîå çíà÷åíèå òåéêïðîôèòà!");
|
|
return(false);
|
|
}
|
|
//----
|
|
int Stop;
|
|
long digit;
|
|
double point,dStop,ExtrStop,ExtrTake;
|
|
|
|
//---- ïîëó÷àåì ìèíèìàëüíîå ðàññòîÿíèå äî îòëîæåííîãî îðäåðà
|
|
Stop=0;
|
|
if(!StopCorrect(symbol,Stop))return(false);
|
|
//----
|
|
if(!SymbolInfoInteger(symbol,SYMBOL_DIGITS,digit)) return(false);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_POINT,point)) return(false);
|
|
dStop=Stop*point;
|
|
|
|
//---- êîððåêöèÿ ðàçìåðà îòëîæåííîãî îðäåðà äëÿ ëîíãà
|
|
if(trade_operation==POSITION_TYPE_BUY)
|
|
{
|
|
double Ask;
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_ASK,Ask)) return(false);
|
|
|
|
ExtrStop=NormalizeDouble(Ask-dStop,int(digit));
|
|
ExtrTake=NormalizeDouble(Ask+dStop,int(digit));
|
|
|
|
if(dStopLoss>ExtrStop && dStopLoss) dStopLoss=ExtrStop;
|
|
if(dTakeprofit<ExtrTake && dTakeprofit) dTakeprofit=ExtrTake;
|
|
}
|
|
|
|
//---- êîððåêöèÿ ðàçìåðà îòëîæåííîãî îðäåðà äëÿ øîðòà
|
|
if(trade_operation==POSITION_TYPE_SELL)
|
|
{
|
|
double Bid;
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_BID,Bid)) return(false);
|
|
|
|
ExtrStop=NormalizeDouble(Bid+dStop,int(digit));
|
|
ExtrTake=NormalizeDouble(Bid-dStop,int(digit));
|
|
|
|
if(dStopLoss<ExtrStop && dStopLoss) dStopLoss=ExtrStop;
|
|
if(dTakeprofit>ExtrTake && dTakeprofit) dTakeprofit=ExtrTake;
|
|
}
|
|
//----
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| êîððåêöèÿ ðàçìåðà ëîòà äî áëèæàéøåãî äîïóñòèìîãî çíà÷åíèÿ |
|
|
//+------------------------------------------------------------------+
|
|
bool LotCorrect
|
|
(
|
|
string symbol,
|
|
double &Lot,
|
|
ENUM_POSITION_TYPE trade_operation
|
|
)
|
|
//LotCorrect(string symbol, double& Lot, ENUM_POSITION_TYPE trade_operation)
|
|
{
|
|
//---- ïîëó÷åíèå äàííûõ äëÿ ðàñ÷¸òà
|
|
double Step,MaxLot,MinLot;
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP,Step)) return(false);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX,MaxLot)) return(false);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN,MinLot)) return(false);
|
|
|
|
//---- íîðìèðîâàíèå âåëè÷èíû ëîòà äî áëèæàéøåãî ñòàíäàðòíîãî çíà÷åíèÿ
|
|
Lot=Step*MathFloor(Lot/Step);
|
|
|
|
//---- ïðîâåðêà ëîòà íà ìèíèìàëüíîå äîïóñòèìîå çíà÷åíèå
|
|
if(Lot<MinLot) Lot=MinLot;
|
|
//---- ïðîâåðêà ëîòà íà ìàêñèìàëüíîå äîïóñòèìîå çíà÷åíèå
|
|
if(Lot>MaxLot) Lot=MaxLot;
|
|
|
|
//---- ïðîâåðêà ñðåäñòâ íà äîñòàòî÷íîñòü
|
|
if(!LotFreeMarginCorrect(symbol,Lot,trade_operation))return(false);
|
|
//----
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| îãðàíè÷åíèå ðàçìåðà ëîòà âîçìîæíîñòÿìè äåïîçèòà |
|
|
//+------------------------------------------------------------------+
|
|
bool LotFreeMarginCorrect
|
|
(
|
|
string symbol,
|
|
double &Lot,
|
|
ENUM_POSITION_TYPE trade_operation
|
|
)
|
|
//(string symbol, double& Lot, ENUM_POSITION_TYPE trade_operation)
|
|
{
|
|
//---- ïðîâåðêà ñðåäñòâ íà äîñòàòî÷íîñòü
|
|
double freemargin=AccountInfoDouble(ACCOUNT_FREEMARGIN);
|
|
if(freemargin<=0) return(false);
|
|
|
|
//---- ïîëó÷åíèå äàííûõ äëÿ ðàñ÷¸òà
|
|
double Step,MaxLot,MinLot;
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP,Step)) return(false);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX,MaxLot)) return(false);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN,MinLot)) return(false);
|
|
|
|
double ExtremLot=GetLotForOpeningPos(symbol,trade_operation,freemargin);
|
|
//---- íîðìèðîâàíèå âåëè÷èíû ëîòà äî áëèæàéøåãî ñòàíäàðòíîãî çíà÷åíèÿ
|
|
ExtremLot=Step*MathFloor(ExtremLot/Step);
|
|
|
|
if(ExtremLot<MinLot) return(false); // íåäîñòàòî÷íî äåíåã äàæå íà ìèíèìàëüíûé ëîò!
|
|
if(Lot>ExtremLot) Lot=ExtremLot; // óðåçàåì ðàçìåð ëîòà äî òîãî, ÷òî åñòü íà äåïîçèòå!
|
|
if(Lot>MaxLot) Lot=MaxLot; // óðåçàåì ðàçìåð ëîòà äî ìàñèìàëüíî äîïóñòèìîãî
|
|
//----
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| ðàñ÷¸ò ðàçìåð ëîòà äëÿ îòêðûâàíèÿ ïîçèöèè ñ ìàðæîé lot_margin |
|
|
//+------------------------------------------------------------------+
|
|
double GetLotForOpeningPos(string symbol,ENUM_POSITION_TYPE direction,double lot_margin)
|
|
{
|
|
//----
|
|
double price=0.0,n_margin;
|
|
if(direction==POSITION_TYPE_BUY) if(!SymbolInfoDouble(symbol,SYMBOL_ASK,price)) return(0);
|
|
if(direction==POSITION_TYPE_SELL) if(!SymbolInfoDouble(symbol,SYMBOL_BID,price)) return(0);
|
|
if(!price) return(NULL);
|
|
|
|
if(!OrderCalcMargin(ENUM_ORDER_TYPE(direction),symbol,1,price,n_margin) || !n_margin) return(0);
|
|
double lot=lot_margin/n_margin;
|
|
|
|
//---- ïîëó÷åíèå òîðãîâûõ êîíñòàíò
|
|
double LOTSTEP,MaxLot,MinLot;
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP,LOTSTEP)) return(0);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX,MaxLot)) return(0);
|
|
if(!SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN,MinLot)) return(0);
|
|
|
|
//---- íîðìèðîâàíèå âåëè÷èíû ëîòà äî áëèæàéøåãî ñòàíäàðòíîãî çíà÷åíèÿ
|
|
lot=LOTSTEP*MathFloor(lot/LOTSTEP);
|
|
|
|
//---- ïðîâåðêà ëîòà íà ìèíèìàëüíîå äîïóñòèìîå çíà÷åíèå
|
|
if(lot<MinLot) lot=0;
|
|
//---- ïðîâåðêà ëîòà íà ìàêñèìàëüíîå äîïóñòèìîå çíà÷åíèå
|
|
if(lot>MaxLot) lot=MaxLot;
|
|
//----
|
|
return(lot);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| âîçâðàò ñèìâîëà ñ çàäàííûìè âàëþòàìè çàëîãà è êîòèðîâêè |
|
|
//+------------------------------------------------------------------+
|
|
string GetSymbolByCurrencies(string margin_currency,string profit_currency)
|
|
{
|
|
//---- ïåðåáåðåì â öèêëå âñå ñèìâîëû, êîòîðûå ïðåäñòàâëåíû â îêíå "Îáçîð ðûíêà"
|
|
int total=SymbolsTotal(true);
|
|
for(int numb=0; numb<total; numb++)
|
|
{
|
|
//---- ïîëó÷èì èìÿ ñèìâîëà ïî íîìåðó â ñïèñêå "Îáçîð ðûíêà"
|
|
string symbolname=SymbolName(numb,true);
|
|
|
|
//---- ïîëó÷èì âàëþòó çàëîãà
|
|
string m_cur=SymbolInfoString(symbolname,SYMBOL_CURRENCY_MARGIN);
|
|
|
|
//---- ïîëó÷èì âàëþòó êîòèðîâêè (â ÷åì èçìåðÿåòñÿ ïðèáûëü ïðè èçìåíåíèè öåíû)
|
|
string p_cur=SymbolInfoString(symbolname,SYMBOL_CURRENCY_PROFIT);
|
|
|
|
//---- åñëè ñèìâîë ïîäîøåë ïî îáåèì çàäàííûì âàëþòàì, âåðíåì èìÿ ñèìâîëà
|
|
if(m_cur==margin_currency && p_cur==profit_currency) return(symbolname);
|
|
}
|
|
//----
|
|
return(NULL);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| âîçâðàò ñòðèíãîâîãî ðåçóëüòàòà òîðãîâîé îïåðàöèè ïî åãî êîäó |
|
|
//+------------------------------------------------------------------+
|
|
string ResultRetcodeDescription(int retcode)
|
|
{
|
|
string str;
|
|
//----
|
|
switch(retcode)
|
|
{
|
|
case TRADE_RETCODE_REQUOTE: str="Ðåêâîòà"; break;
|
|
case TRADE_RETCODE_REJECT: str="Çàïðîñ îòâåðãíóò"; break;
|
|
case TRADE_RETCODE_CANCEL: str="Çàïðîñ îòìåíåí òðåéäåðîì"; break;
|
|
case TRADE_RETCODE_PLACED: str="Îðäåð ðàçìåùåí"; break;
|
|
case TRADE_RETCODE_DONE: str="Çàÿâêà âûïîëíåíà"; break;
|
|
case TRADE_RETCODE_DONE_PARTIAL: str="Çàÿâêà âûïîëíåíà ÷àñòè÷íî"; break;
|
|
case TRADE_RETCODE_ERROR: str="Îøèáêà îáðàáîòêè çàïðîñà"; break;
|
|
case TRADE_RETCODE_TIMEOUT: str="Çàïðîñ îòìåíåí ïî èñòå÷åíèþ âðåìåíè";break;
|
|
case TRADE_RETCODE_INVALID: str="Íåïðàâèëüíûé çàïðîñ"; break;
|
|
case TRADE_RETCODE_INVALID_VOLUME: str="Íåïðàâèëüíûé îáúåì â çàïðîñå"; break;
|
|
case TRADE_RETCODE_INVALID_PRICE: str="Íåïðàâèëüíàÿ öåíà â çàïðîñå"; break;
|
|
case TRADE_RETCODE_INVALID_STOPS: str="Íåïðàâèëüíûå ñòîïû â çàïðîñå"; break;
|
|
case TRADE_RETCODE_TRADE_DISABLED: str="Òîðãîâëÿ çàïðåùåíà"; break;
|
|
case TRADE_RETCODE_MARKET_CLOSED: str="Ðûíîê çàêðûò"; break;
|
|
case TRADE_RETCODE_NO_MONEY: str="Íåò äîñòàòî÷íûõ äåíåæíûõ ñðåäñòâ äëÿ âûïîëíåíèÿ çàïðîñà"; break;
|
|
case TRADE_RETCODE_PRICE_CHANGED: str="Öåíû èçìåíèëèñü"; break;
|
|
case TRADE_RETCODE_PRICE_OFF: str="Îòñóòñòâóþò êîòèðîâêè äëÿ îáðàáîòêè çàïðîñà"; break;
|
|
case TRADE_RETCODE_INVALID_EXPIRATION: str="Íåâåðíàÿ äàòà èñòå÷åíèÿ îðäåðà â çàïðîñå"; break;
|
|
case TRADE_RETCODE_ORDER_CHANGED: str="Ñîñòîÿíèå îðäåðà èçìåíèëîñü"; break;
|
|
case TRADE_RETCODE_TOO_MANY_REQUESTS: str="Ñëèøêîì ÷àñòûå çàïðîñû"; break;
|
|
case TRADE_RETCODE_NO_CHANGES: str="Â çàïðîñå íåò èçìåíåíèé"; break;
|
|
case TRADE_RETCODE_SERVER_DISABLES_AT: str="Àâòîòðåéäèíã çàïðåùåí ñåðâåðîì"; break;
|
|
case TRADE_RETCODE_CLIENT_DISABLES_AT: str="Àâòîòðåéäèíã çàïðåùåí êëèåíòñêèì òåðìèíàëîì"; break;
|
|
case TRADE_RETCODE_LOCKED: str="Çàïðîñ çàáëîêèðîâàí äëÿ îáðàáîòêè"; break;
|
|
case TRADE_RETCODE_FROZEN: str="Îðäåð èëè ïîçèöèÿ çàìîðîæåíû"; break;
|
|
case TRADE_RETCODE_INVALID_FILL: str="Óêàçàí íåïîääåðæèâàåìûé òèï èñïîëíåíèÿ îðäåðà ïî îñòàòêó "; break;
|
|
case TRADE_RETCODE_CONNECTION: str="Íåò ñîåäèíåíèÿ ñ òîðãîâûì ñåðâåðîì"; break;
|
|
case TRADE_RETCODE_ONLY_REAL: str="Îïåðàöèÿ ðàçðåøåíà òîëüêî äëÿ ðåàëüíûõ ñ÷åòîâ"; break;
|
|
case TRADE_RETCODE_LIMIT_ORDERS: str="Äîñòèãíóò ëèìèò íà êîëè÷åñòâî îòëîæåííûõ îðäåðîâ"; break;
|
|
case TRADE_RETCODE_LIMIT_VOLUME: str="Äîñòèãíóò ëèìèò íà îáúåì îðäåðîâ è ïîçèöèé äëÿ äàííîãî ñèìâîëà"; break;
|
|
default: str="Íåèçâåñòíûé ðåçóëüòàò";
|
|
}
|
|
//----
|
|
return(str);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| HistoryLoader.mqh |
|
|
//| Copyright © 2009, MetaQuotes Software Corp. |
|
|
//| http://www.metaquotes.net/ |
|
|
//+------------------------------------------------------------------+
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Çàãðóçêà èñòîðèè äëÿ ìóëüòèâàëþòíîãî ýêñïåðòà |
|
|
//+------------------------------------------------------------------+
|
|
int LoadHistory(datetime StartDate, // ñòàðòîâàÿ äàòà äëÿ ïîäãðóçêè èñòîðèè
|
|
string LoadedSymbol, // ñèìâîë çàïðàøèâàåìûõ èñòîðè÷åñêèõ äàííûõ
|
|
ENUM_TIMEFRAMES LoadedPeriod) // òàéìôðåéì çàïðàøèâàåìûõ èñòîðè÷åñêèõ äàííûõ
|
|
{
|
|
//----+
|
|
//Print(__FUNCTION__, ": Start load ", LoadedSymbol+ " , " + EnumToString(LoadedPeriod) + " from ", StartDate);
|
|
int res=CheckLoadHistory(LoadedSymbol,LoadedPeriod,StartDate);
|
|
switch(res)
|
|
{
|
|
case -1 : Print(__FUNCTION__, "(", LoadedSymbol, " ", EnumToString(LoadedPeriod), "): Unknown symbol ", LoadedSymbol); break;
|
|
case -2 : Print(__FUNCTION__, "(", LoadedSymbol, " ", EnumToString(LoadedPeriod), "): Requested bars more than max bars in chart "); break;
|
|
case -3 : Print(__FUNCTION__, "(", LoadedSymbol, " ", EnumToString(LoadedPeriod), "): Program was stopped "); break;
|
|
case -4 : Print(__FUNCTION__, "(", LoadedSymbol, " ", EnumToString(LoadedPeriod), "): Indicator shouldn't load its own data "); break;
|
|
case -5 : Print(__FUNCTION__, "(", LoadedSymbol, " ", EnumToString(LoadedPeriod), "): Load failed "); break;
|
|
case 0 : /* Print(__FUNCTION__, "(", LoadedSymbol, " ", EnumToString(LoadedPeriod), "): Loaded OK "); */ break;
|
|
case 1 : /* Print(__FUNCTION__, "(", LoadedSymbol, " ", EnumToString(LoadedPeriod), "): Loaded previously "); */ break;
|
|
case 2 : /* Print(__FUNCTION__, "(", LoadedSymbol, " ", EnumToString(LoadedPeriod), "): Loaded previously and built "); */ break;
|
|
default : { /* Print(__FUNCTION__, "(", LoadedSymbol, " ", EnumToString(LoadedPeriod), "): Unknown result "); */}
|
|
}
|
|
/*
|
|
if (res > 0)
|
|
{
|
|
bars = Bars(LoadedSymbol, LoadedPeriod);
|
|
Print(__FUNCTION__, "(", LoadedSymbol, " ", GetPeriodName(LoadedPeriod), "): First date ", first_date, " - ", bars, " bars");
|
|
}
|
|
*/
|
|
//----+
|
|
return(res);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| ïðîâåðêà èñòîðèè äëÿ ïîäãðóçêè |
|
|
//+------------------------------------------------------------------+
|
|
int CheckLoadHistory(string symbol,ENUM_TIMEFRAMES period,datetime start_date)
|
|
{
|
|
//----+
|
|
datetime first_date=0;
|
|
datetime times[100];
|
|
//--- check symbol & period
|
|
if(symbol == NULL || symbol == "") symbol = Symbol();
|
|
if(period == PERIOD_CURRENT) period = Period();
|
|
//--- check if symbol is selected in the MarketWatch
|
|
if(!SymbolInfoInteger(symbol,SYMBOL_SELECT))
|
|
{
|
|
if(GetLastError()==ERR_MARKET_UNKNOWN_SYMBOL) return(-1);
|
|
if(!SymbolSelect(symbol,true)) Print(__FUNCTION__,"(): Íå óäàëîñü äîáàâèòü ñèìâîë ",symbol," â îêíî MarketWatch!!!");
|
|
}
|
|
//--- check if data is present
|
|
SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date);
|
|
if(first_date>0 && first_date<=start_date) return(1);
|
|
//--- don't ask for load of its own data if it is an indicator
|
|
if(MQL5InfoInteger(MQL5_PROGRAM_TYPE)==PROGRAM_INDICATOR && Period()==period && Symbol()==symbol)
|
|
return(-4);
|
|
//--- second attempt
|
|
if(SeriesInfoInteger(symbol,PERIOD_M1,SERIES_TERMINAL_FIRSTDATE,first_date))
|
|
{
|
|
//--- there is loaded data to build timeseries
|
|
if(first_date>0)
|
|
{
|
|
//--- force timeseries build
|
|
CopyTime(symbol,period,first_date+PeriodSeconds(period),1,times);
|
|
//--- check date
|
|
if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date))
|
|
if(first_date>0 && first_date<=start_date) return(2);
|
|
}
|
|
}
|
|
//--- max bars in chart from terminal options
|
|
int max_bars=TerminalInfoInteger(TERMINAL_MAXBARS);
|
|
//--- load symbol history info
|
|
datetime first_server_date=0;
|
|
while(!SeriesInfoInteger(symbol,PERIOD_M1,SERIES_SERVER_FIRSTDATE,first_server_date) && !IsStopped())
|
|
Sleep(5);
|
|
//--- fix start date for loading
|
|
if(first_server_date>start_date) start_date=first_server_date;
|
|
if(first_date>0 && first_date<first_server_date)
|
|
Print(__FUNCTION__,"(): Warning: first server date ",first_server_date," for ",symbol,
|
|
" does not match to first series date ",first_date);
|
|
//--- load data step by step
|
|
int fail_cnt=0;
|
|
while(!IsStopped())
|
|
{
|
|
//--- wait for timeseries build
|
|
while(!SeriesInfoInteger(symbol,period,SERIES_SYNCHRONIZED) && !IsStopped())
|
|
Sleep(5);
|
|
//--- ask for built bars
|
|
int bars=Bars(symbol,period);
|
|
if(bars>0)
|
|
{
|
|
if(bars>=max_bars) return(-2);
|
|
//--- ask for first date
|
|
if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date))
|
|
if(first_date>0 && first_date<=start_date) return(0);
|
|
}
|
|
//--- copying of next part forces data loading
|
|
int copied=CopyTime(symbol,period,bars,100,times);
|
|
if(copied>0)
|
|
{
|
|
//--- check for data
|
|
if(times[0]<=start_date) return(0);
|
|
if(bars+copied>=max_bars) return(-2);
|
|
fail_cnt=0;
|
|
}
|
|
else
|
|
{
|
|
//--- no more than 100 failed attempts
|
|
fail_cnt++;
|
|
if(fail_cnt>=100) return(-5);
|
|
Sleep(10);
|
|
}
|
|
}
|
|
//----+ stopped
|
|
return(-3);
|
|
}
|
|
//+------------------------------------------------------------------+
|