//+------------------------------------------------------------------+ //| 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>>"); 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()ExtrStop && dStopLoss) dStopLoss=ExtrStop; if(dTakeprofitExtrTake && 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(LotMaxLot) 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(ExtremLotExtremLot) 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(lotMaxLot) lot=MaxLot; //---- return(lot); } //+------------------------------------------------------------------+ //| возврат символа с заданными валютами залога и котировки | //+------------------------------------------------------------------+ string GetSymbolByCurrencies(string margin_currency,string profit_currency) { //---- переберем в цикле все символы, которые представлены в окне "Обзор рынка" int total=SymbolsTotal(true); for(int numb=0; numb 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_date0) { 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); } //+------------------------------------------------------------------+