//+------------------------------------------------------------------+ //| MyFirstIncludeFile.mqh | //| dilettantcorner | //| dilettantcorner@gmail.com | //+------------------------------------------------------------------+ #property copyright "dilettantcorner" #property link "dilettantcorner@gmail.com" #ifndef MY_EXPERT_FUNCTIONS_MQH #define MY_EXPERT_FUNCTIONS_MQH namespace std { //+------------------------------------------------------------------+ ulong Open_Buy_Pos(string symbol,double lot, int slipage, uint magic = NULL, string comment = NULL) { MqlTradeRequest reqwest; MqlTradeResult result; ZeroMemory(reqwest); ZeroMemory(result); reqwest.action = TRADE_ACTION_DEAL; reqwest.symbol = symbol; reqwest.type = ORDER_TYPE_BUY; reqwest.volume = NormalizeDouble(lot,2); ENUM_ORDER_TYPE_FILLING fill_type; GetFillMode(reqwest.symbol,fill_type); ::Print("Filling mode: ",fill_type); reqwest.type_filling = fill_type; if(SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_EXEMODE) == SYMBOL_TRADE_EXECUTION_INSTANT || SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_EXEMODE) == SYMBOL_TRADE_EXECUTION_REQUEST) { double current_ask = SymbolInfoDouble(reqwest.symbol,SYMBOL_ASK); reqwest.price = current_ask; reqwest.sl = 0; reqwest.tp = 0; reqwest.deviation = slipage; } if(comment != NULL && comment != "") reqwest.comment = comment; if(magic > 0) reqwest.magic = magic; for(int i = 0;i < 10;i++) { if(!OrderSend(reqwest,result)) { Print("Позиция Бай не открыта. Ошибка №",result.retcode); Sleep(500); } else { ulong deal_ticket = result.deal; if(deal_ticket == 0) break; if(deal_ticket > 0) { if(HistoryDealSelect(deal_ticket)) { long pos_ticket = HistoryDealGetInteger(deal_ticket,DEAL_POSITION_ID); return pos_ticket; } } } } return 0; } //+------------------------------------------------------------------+ ulong Open_Sell_Pos(string symbol,double lot, int slipage, uint magic = NULL, string comment = NULL) { MqlTradeRequest reqwest; MqlTradeResult result; ZeroMemory(reqwest); ZeroMemory(result); reqwest.action = TRADE_ACTION_DEAL; reqwest.symbol = symbol; reqwest.type = ORDER_TYPE_SELL; reqwest.volume = NormalizeDouble(lot,2); ENUM_ORDER_TYPE_FILLING fill_type; GetFillMode(reqwest.symbol,fill_type); ::Print("Filling mode: ",fill_type); reqwest.type_filling = fill_type; if(SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_EXEMODE) == SYMBOL_TRADE_EXECUTION_INSTANT || SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_EXEMODE) == SYMBOL_TRADE_EXECUTION_REQUEST) { double current_bid = SymbolInfoDouble(reqwest.symbol,SYMBOL_BID); reqwest.price = current_bid; reqwest.sl = 0; reqwest.tp = 0; reqwest.deviation = slipage; } if(comment != NULL && comment != "") reqwest.comment = comment; if(magic > 0) reqwest.magic = magic; for(int i = 0;i < 10;i++) { if(!OrderSend(reqwest,result)) { Print("Позиция Селл не открыта. Ошибка №",result.retcode); Sleep(500); } else { ulong deal_ticket = result.deal; if(deal_ticket == 0) break; if(deal_ticket > 0) { if(HistoryDealSelect(deal_ticket)) { long pos_ticket = HistoryDealGetInteger(deal_ticket,DEAL_POSITION_ID); return pos_ticket; } } } } return 0; } //+------------------------------------------------------------------+ ulong Set_Buy_Order(string symbol, double lot, double open_price, int stop_loss, int take_profit, uint magic = NULL, datetime expiration_time = 0, string comment = NULL) { MqlTradeRequest reqwest; MqlTradeResult result; ZeroMemory(reqwest); ZeroMemory(result); reqwest.action = TRADE_ACTION_PENDING; reqwest.symbol = symbol; reqwest.volume = NormalizeDouble(lot,2); reqwest.type_filling = ORDER_FILLING_RETURN; int digits = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_DIGITS); reqwest.price = NormalizeDouble(open_price,digits); double current_ask = SymbolInfoDouble(reqwest.symbol,SYMBOL_ASK); if(reqwest.price > current_ask) reqwest.type = ORDER_TYPE_BUY_STOP; else reqwest.type = ORDER_TYPE_BUY_LIMIT; int stop_level = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_STOPS_LEVEL); double point = SymbolInfoDouble(reqwest.symbol,SYMBOL_POINT); if(stop_loss > 0) { if(stop_loss < stop_level) stop_loss = stop_level; reqwest.sl = NormalizeDouble(reqwest.price - stop_loss * point,digits); } else reqwest.sl = 0; if(take_profit > 0) { if(take_profit < stop_level) take_profit = stop_level; reqwest.tp = NormalizeDouble(reqwest.price + take_profit * point,digits); } else reqwest.tp = 0; if(expiration_time == 0) { int symb_exp = (int)SymbolInfoInteger(symbol,SYMBOL_EXPIRATION_MODE); if((SYMBOL_EXPIRATION_GTC & symb_exp) != SYMBOL_EXPIRATION_GTC) reqwest.type_time = ORDER_TIME_DAY; else reqwest.type_time = ORDER_TIME_GTC; } if(comment != NULL && comment != "") reqwest.comment = comment; if(magic > 0) reqwest.magic = magic; for(int i = 0;i < 10;i++) { if(!OrderSend(reqwest,result)) { Print("Отложенный ордер Бай не установлен. Ошибка №",result.retcode); Sleep(500); } else { ulong order_ticket = result.order; if(order_ticket > 0) return order_ticket; } } return 0; } //+------------------------------------------------------------------+ ulong Set_Sell_Order(string symbol, double lot, double open_price, int stop_loss, int take_profit, uint magic = NULL, datetime expiration_time = 0, string comment = NULL) { MqlTradeRequest reqwest; MqlTradeResult result; ZeroMemory(reqwest); ZeroMemory(result); reqwest.action = TRADE_ACTION_PENDING; reqwest.symbol = symbol; reqwest.volume = NormalizeDouble(lot,2); reqwest.type_filling = ORDER_FILLING_RETURN; int digits = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_DIGITS); reqwest.price = NormalizeDouble(open_price,digits); double current_bid = SymbolInfoDouble(reqwest.symbol,SYMBOL_BID); if(reqwest.price < current_bid) reqwest.type = ORDER_TYPE_SELL_STOP; else reqwest.type = ORDER_TYPE_SELL_LIMIT; int stop_level = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_STOPS_LEVEL); double point = SymbolInfoDouble(reqwest.symbol,SYMBOL_POINT); if(stop_loss > 0) { if(stop_loss < stop_level) stop_loss = stop_level; reqwest.sl = NormalizeDouble(reqwest.price + stop_loss * point,digits); } else reqwest.sl = 0; if(take_profit > 0) { if(take_profit < stop_level) take_profit = stop_level; reqwest.tp = NormalizeDouble(reqwest.price - take_profit * point,digits); } else reqwest.tp = 0; if(expiration_time == 0) { int symb_exp = (int)SymbolInfoInteger(symbol,SYMBOL_EXPIRATION_MODE); if((SYMBOL_EXPIRATION_GTC & symb_exp) != SYMBOL_EXPIRATION_GTC) reqwest.type_time = ORDER_TIME_DAY; else reqwest.type_time = ORDER_TIME_GTC; } if(comment != NULL && comment != "") reqwest.comment = comment; if(magic > 0) reqwest.magic = magic; for(int i = 0;i < 10;i++) { if(!OrderSend(reqwest,result)) { Print("Отложенный ордер Селл не установлен. Ошибка №",result.retcode); Sleep(500); } else { ulong order_ticket = result.order; if(order_ticket > 0) return order_ticket; } } return 0; } //+------------------------------------------------------------------+ ulong Set_Buy_Order(string symbol, double lot, double open_price, double stop_loss, double take_profit, uint magic = NULL, datetime expiration_time = 0, string comment = NULL) { MqlTradeRequest reqwest; MqlTradeResult result; ZeroMemory(reqwest); ZeroMemory(result); reqwest.action = TRADE_ACTION_PENDING; reqwest.symbol = symbol; reqwest.volume = NormalizeDouble(lot,2); reqwest.type_filling = ORDER_FILLING_RETURN; int digits = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_DIGITS); reqwest.price = NormalizeDouble(open_price,digits); double current_ask = SymbolInfoDouble(reqwest.symbol,SYMBOL_ASK); if(reqwest.price > current_ask) reqwest.type = ORDER_TYPE_BUY_STOP; else reqwest.type = ORDER_TYPE_BUY_LIMIT; int stop_level = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_STOPS_LEVEL); double point = SymbolInfoDouble(reqwest.symbol,SYMBOL_POINT); if(stop_loss > 0) { double stop_dist = DistPrices(reqwest.price,stop_loss,symbol); if(stop_dist < stop_level) stop_loss = reqwest.price - stop_level * point; reqwest.sl = NormalizeDouble(stop_loss,digits); } else reqwest.sl = 0; if(take_profit > 0) { double stop_dist = DistPrices(reqwest.price,take_profit,symbol); if(stop_dist < stop_level) take_profit = reqwest.price + stop_level * point; reqwest.tp = NormalizeDouble(take_profit,digits); } else reqwest.tp = 0; if(expiration_time == 0) { int symb_exp = (int)SymbolInfoInteger(symbol,SYMBOL_EXPIRATION_MODE); if((SYMBOL_EXPIRATION_GTC & symb_exp) != SYMBOL_EXPIRATION_GTC) reqwest.type_time = ORDER_TIME_DAY; else reqwest.type_time = ORDER_TIME_GTC; } if(comment != NULL && comment != "") reqwest.comment = comment; if(magic > 0) reqwest.magic = magic; for(int i = 0;i < 10;i++) { if(!OrderSend(reqwest,result)) { Print("Отложенный ордер Бай не установлен. Ошибка №",result.retcode); Sleep(500); } else { ulong order_ticket = result.order; if(order_ticket > 0) return order_ticket; } } return 0; } //+------------------------------------------------------------------+ ulong Set_Sell_Order(string symbol, double lot, double open_price, double stop_loss, double take_profit, uint magic = NULL, datetime expiration_time = 0, string comment = NULL) { MqlTradeRequest reqwest; MqlTradeResult result; ZeroMemory(reqwest); ZeroMemory(result); reqwest.action = TRADE_ACTION_PENDING; reqwest.symbol = symbol; reqwest.volume = NormalizeDouble(lot,2); reqwest.type_filling = ORDER_FILLING_RETURN; int digits = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_DIGITS); reqwest.price = NormalizeDouble(open_price,digits); double current_bid = SymbolInfoDouble(reqwest.symbol,SYMBOL_BID); if(reqwest.price < current_bid) reqwest.type = ORDER_TYPE_SELL_STOP; else reqwest.type = ORDER_TYPE_SELL_LIMIT; int stop_level = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_STOPS_LEVEL); double point = SymbolInfoDouble(reqwest.symbol,SYMBOL_POINT); if(stop_loss > 0) { double stop_dist = DistPrices(reqwest.price,stop_loss,symbol); if(stop_dist < stop_level) stop_loss = reqwest.price + stop_level * point; reqwest.sl = NormalizeDouble(stop_loss,digits); } else reqwest.sl = 0; if(take_profit > 0) { double stop_dist = DistPrices(reqwest.price,take_profit,symbol); if(take_profit < stop_level) take_profit = reqwest.price + stop_level * point; reqwest.tp = NormalizeDouble(take_profit,digits); } else reqwest.tp = 0; if(expiration_time == 0) { int symb_exp = (int)SymbolInfoInteger(symbol,SYMBOL_EXPIRATION_MODE); if((SYMBOL_EXPIRATION_GTC & symb_exp) != SYMBOL_EXPIRATION_GTC) reqwest.type_time = ORDER_TIME_DAY; else reqwest.type_time = ORDER_TIME_GTC; } if(comment != NULL && comment != "") reqwest.comment = comment; if(magic > 0) reqwest.magic = magic; for(int i = 0;i < 10;i++) { if(!OrderSend(reqwest,result)) { Print("Отложенный ордер Селл не установлен. Ошибка №",result.retcode); Sleep(500); } else { ulong order_ticket = result.order; if(order_ticket > 0) return order_ticket; } } return 0; } //+------------------------------------------------------------------+ bool Position_SLTP(ulong position,double SL,double TP) { if(PositionSelectByTicket(position)) { double pos_op = PositionGetDouble(POSITION_PRICE_OPEN); string pos_symb = PositionGetString(POSITION_SYMBOL); ulong pos_mag = PositionGetInteger(POSITION_MAGIC); ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); int symb_digits = (int)SymbolInfoInteger(pos_symb,SYMBOL_DIGITS); double symb_point = SymbolInfoDouble(pos_symb,SYMBOL_POINT); int freez_level = (int)SymbolInfoInteger(pos_symb,SYMBOL_TRADE_FREEZE_LEVEL); MqlTradeRequest reqwest; MqlTradeResult result; ZeroMemory(reqwest); ZeroMemory(result); if(pos_type == POSITION_TYPE_BUY) { double current_bid = SymbolInfoDouble(pos_symb,SYMBOL_BID); if(SL < 0) reqwest.sl = 0; else if(SL > 0) { reqwest.sl = NormalizeDouble(SL,symb_digits); if(MathAbs(current_bid - reqwest.sl) / symb_point < freez_level) reqwest.sl = NormalizeDouble(current_bid + freez_level * symb_point,symb_digits); } if(TP < 0) reqwest.tp = 0; else if(TP > 0) { reqwest.tp = NormalizeDouble(TP,symb_digits); if(MathAbs(current_bid - reqwest.tp) / symb_point < freez_level) reqwest.tp = NormalizeDouble(current_bid + freez_level * symb_point,symb_digits); } } else { if(SL < 0) reqwest.sl = 0; else if(SL > 0) { reqwest.sl = NormalizeDouble(SL,symb_digits); double current_ask = SymbolInfoDouble(pos_symb,SYMBOL_ASK); if(MathAbs(current_ask - reqwest.sl) / symb_point < freez_level) reqwest.sl = NormalizeDouble(current_ask + freez_level * symb_point,symb_digits); } if(TP < 0) reqwest.tp = 0; else if(TP > 0) { reqwest.tp = NormalizeDouble(TP,symb_digits); double current_ask = SymbolInfoDouble(pos_symb,SYMBOL_ASK); if(MathAbs(current_ask - reqwest.tp) / symb_point < freez_level) reqwest.tp = NormalizeDouble(current_ask - freez_level * symb_point,symb_digits); } } reqwest.position = position; reqwest.magic = pos_mag; reqwest.symbol = pos_symb; reqwest.action = TRADE_ACTION_SLTP; for(int i = 0;i < 10;i++) { if(!OrderSend(reqwest,result)) { Print("Позиция №",position," не была модифицирована. Ошибка№",result.retcode); Sleep(500); } else return true; } } else Print("Позиция №",position," не найдена."); return false; } //+------------------------------------------------------------------+ bool Position_SLTP(ulong position,int SL,int TP) { if(PositionSelectByTicket(position)) { double pos_op = PositionGetDouble(POSITION_PRICE_OPEN); string pos_symb = PositionGetString(POSITION_SYMBOL); ulong pos_mag = PositionGetInteger(POSITION_MAGIC); ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); int symb_digits = (int)SymbolInfoInteger(pos_symb,SYMBOL_DIGITS); double symb_point = SymbolInfoDouble(pos_symb,SYMBOL_POINT); int freez_level = (int)SymbolInfoInteger(pos_symb,SYMBOL_TRADE_FREEZE_LEVEL); MqlTradeRequest reqwest; MqlTradeResult result; ZeroMemory(reqwest); ZeroMemory(result); if(pos_type == POSITION_TYPE_BUY) { if(SL < 0) reqwest.sl = 0; else if(SL > 0) { if(SL < freez_level) SL = freez_level; reqwest.sl = NormalizeDouble(pos_op - SL * symb_point,symb_digits); double current_bid = SymbolInfoDouble(pos_symb,SYMBOL_BID); if(MathAbs(current_bid - reqwest.sl) / symb_point < freez_level) reqwest.sl = NormalizeDouble(current_bid - SL * symb_point,symb_digits); } if(TP < 0) reqwest.tp = 0; else if(TP > 0) { if(TP < freez_level) TP = freez_level; reqwest.tp = NormalizeDouble(pos_op + TP * symb_point,symb_digits); double current_bid = SymbolInfoDouble(pos_symb,SYMBOL_BID); if(MathAbs(current_bid - reqwest.tp) / symb_point < freez_level) reqwest.tp = NormalizeDouble(current_bid + TP * symb_point,symb_digits); } } else { if(SL < 0) reqwest.sl = 0; else if(SL > 0) { if(SL < freez_level) SL = freez_level; reqwest.sl = NormalizeDouble(pos_op + SL * symb_point,symb_digits); double current_ask = SymbolInfoDouble(pos_symb,SYMBOL_ASK); if(MathAbs(current_ask - reqwest.sl) / symb_point < freez_level) reqwest.sl = NormalizeDouble(current_ask + SL * symb_point,symb_digits); } if(TP < 0) reqwest.tp = 0; else if(TP > 0) { if(TP < freez_level) TP = freez_level; reqwest.tp = NormalizeDouble(pos_op - TP * symb_point,symb_digits); double current_ask = SymbolInfoDouble(pos_symb,SYMBOL_ASK); if(MathAbs(current_ask - reqwest.tp) / symb_point < freez_level) reqwest.tp = NormalizeDouble(current_ask - TP * symb_point,symb_digits); } } reqwest.position = position; reqwest.magic = pos_mag; reqwest.symbol = pos_symb; reqwest.action = TRADE_ACTION_SLTP; for(int i = 0;i < 10;i++) { if(!OrderSend(reqwest,result)) { Print("Позиция №",position," не была модифицирована. Ошибка№",result.retcode); Sleep(500); } else return true; } } else Print("Позиция №",position," не найдена."); return false; } //+------------------------------------------------------------------+ int CountPositions(ulong magic , string symbol) { int count = 0; for(int i = 0;i < PositionsTotal();i++) { ulong pos = PositionGetTicket(i); if(PositionSelectByTicket(pos)) { ulong pos_mag = PositionGetInteger(POSITION_MAGIC); string pos_symb = PositionGetString(POSITION_SYMBOL); if(pos_mag == magic && pos_symb == symbol) count++; } } return count; } //+------------------------------------------------------------------+ int CountPositions(const MqlParam &Params[]) { uint magic = NULL; string symbol = ""; ENUM_POSITION_TYPE type = -1; int param_size = ArraySize(Params); for(int i = 0;i < param_size;i++) { if(Params[i].type == TYPE_UINT) magic = (uint)Params[i].integer_value; if(Params[i].type == TYPE_STRING) symbol = Params[i].string_value; if(Params[i].type == TYPE_INT) type = (ENUM_POSITION_TYPE)Params[i].integer_value; } int count = 0; long total_pos = PositionsTotal(); for(int i = 0;i < total_pos;i++) { ulong position = PositionGetTicket(i); if(PositionSelectByTicket(position)) { uint pos_magic = (uint)PositionGetInteger(POSITION_MAGIC); string pos_symbol = PositionGetString(POSITION_SYMBOL); ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); if((symbol == "" || symbol == pos_symbol) && (magic == NULL || magic == pos_magic) && (type == -1 || type == pos_type)) count++; } } return count; } //+------------------------------------------------------------------+ int GetPositionsTickets(const MqlParam &Params[] , ulong &Positions[]) { ::ArrayFree(Positions); int size = CountPositions(Params); ArrayResize(Positions,size); uint magic = NULL; string symbol = ""; ENUM_POSITION_TYPE type = -1; int param_size = ArraySize(Params); for(int i = 0;i < param_size;i++) { if(Params[i].type == TYPE_UINT) magic = (uint)Params[i].integer_value; if(Params[i].type == TYPE_STRING) symbol = Params[i].string_value; if(Params[i].type == TYPE_INT) type = (ENUM_POSITION_TYPE)Params[i].integer_value; } long total_pos = PositionsTotal(); int index = 0; for(int i = 0;i < total_pos;i++) { ulong position = PositionGetTicket(i); if(PositionSelectByTicket(position)) { uint pos_magic = (uint)PositionGetInteger(POSITION_MAGIC); string pos_symbol = PositionGetString(POSITION_SYMBOL); ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); if((symbol == "" || symbol == pos_symbol) && (magic == NULL || magic == pos_magic) && (type == -1 || type == pos_type)) { Positions[index] = position; index++; if(index >= size) break; } } } return size; } //+------------------------------------------------------------------+ int CountPositions(const MqlParam &Params[],const double level_1,const double level_2,const string ctrl_symbol) { double point = SymbolInfoDouble(ctrl_symbol,SYMBOL_POINT); if(level_1 / point == level_2 / point) { Print("Не верно заданы уровни"); return 0; } double upLevel = MathMax(level_1,level_2); double dnLevel; if(upLevel == level_1) dnLevel = level_2; else dnLevel = level_1; uint magic = NULL; string symbol = ""; ENUM_POSITION_TYPE type = -1; int param_size = ArraySize(Params); for(int i = 0;i < param_size;i++) { if(Params[i].type == TYPE_UINT) magic = (uint)Params[i].integer_value; if(Params[i].type == TYPE_STRING) { if(ctrl_symbol != Params[i].string_value) { Print("Ошибка указания символа"); return 0; } symbol = Params[i].string_value; } if(Params[i].type == TYPE_INT) type = (ENUM_POSITION_TYPE)Params[i].integer_value; } int count = 0; long total_pos = PositionsTotal(); for(int i = 0;i < total_pos;i++) { ulong position = PositionGetTicket(i); if(PositionSelectByTicket(position)) { uint pos_magic = (uint)PositionGetInteger(POSITION_MAGIC); string pos_symbol = PositionGetString(POSITION_SYMBOL); ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); if((symbol == "" || symbol == pos_symbol) && (magic == NULL || magic == pos_magic) && (type == -1 || type == pos_type)) { double op = PositionGetDouble(POSITION_PRICE_OPEN); if(op / point > dnLevel / point && op / point < upLevel / point) count++; } } } return count; } //+------------------------------------------------------------------+ int CountOrders(const MqlParam &Params[],const double level_1,const double level_2,const string ctrl_symbol) { double point = SymbolInfoDouble(ctrl_symbol,SYMBOL_POINT); if(level_1 / point == level_2 / point) { Print("Не верно заданы уровни"); return 0; } double upLevel = MathMax(level_1,level_2); double dnLevel; if(upLevel == level_1) dnLevel = level_2; else dnLevel = level_1; uint magic = NULL; string symbol = ""; ENUM_ORDER_TYPE type = -1; int param_size = ArraySize(Params); for(int i = 0;i < param_size;i++) { if(Params[i].type == TYPE_UINT) magic = (uint)Params[i].integer_value; if(Params[i].type == TYPE_STRING) { if(ctrl_symbol != Params[i].string_value) { Print("Ошибка указания символа"); return 0; } symbol = Params[i].string_value; } if(Params[i].type == TYPE_INT) type = (ENUM_ORDER_TYPE)Params[i].integer_value; } int count = 0; long total_ord = OrdersTotal(); if(total_ord == 0) return 0; for(int i = 0;i < total_ord;i++) { ulong order = OrderGetTicket(i); if(OrderSelect(order)) { uint ord_magic = (uint)OrderGetInteger(ORDER_MAGIC); string ord_symbol = OrderGetString(ORDER_SYMBOL); ENUM_ORDER_TYPE ord_type = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE); if((symbol == "" || symbol == ord_symbol) && (magic == NULL || magic == ord_magic) && (type == -1 || type == ord_type)) { double op = OrderGetDouble(ORDER_PRICE_OPEN); if(op / point > dnLevel / point && op / point < upLevel / point) count++; } } } return count; } //+------------------------------------------------------------------+ int DistPrices(double priceA , double priceB , string symbol = NULL) { return (int)(MathAbs(priceA - priceB) / SymbolInfoDouble(symbol,SYMBOL_POINT)); } //+------------------------------------------------------------------+ double LotSize(string symbol, ENUM_ORDER_TYPE type, double entry, double exit, double Foundation, double risk) { double lotMin = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN); double lotMax = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX); double lotStep = SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP); double lot = lotMin; double currencyRisk = (Foundation / 100) * risk; currencyRisk = floor(currencyRisk * 100) / 100; Print("Risk in money = ",currencyRisk); double profit = 0; if(OrderCalcProfit(type,symbol,lot,entry,exit,profit)) { if(MathAbs(profit) <= currencyRisk) { profit = MathAbs(profit); lot = (currencyRisk / profit) * lotMin; lot = floor(lot / lotStep) * lotStep; if(lot > lotMax) lot = lotMax; } else { Print("Риски превышают максимально доступное значение"); return lotMin; } } for(double i = lot;i >= lotMin;i -= lotStep) { if(OrderCalcProfit(type,symbol,lot,entry,exit,profit)) { if(MathAbs(profit) <= currencyRisk) { lot = i; break; } } } return NormalizeDouble(lot,2); } //+------------------------------------------------------------------+ double QoutNormalize(double value, string symbol) { double point = SymbolInfoDouble(symbol,SYMBOL_POINT); double tick_size = SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE); int digits = (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); int iValue = (int)(value / point); int step = (int)(tick_size / point); int max_step; if(step < 10) max_step = 10; else if(step >= 10 && step < 100) max_step = 100; else if(step >= 100 && step < 1000) max_step = 1000; else if(step >= 1000 && step < 10000) max_step = 10000; else max_step = 100000; int lost_value = iValue % max_step; if(lost_value % step == 0) { return (NormalizeDouble(iValue * point,digits)); } iValue /= max_step; for(int i = step;i < max_step;i += step) { if(lost_value < i) { lost_value = i; break; } else if(i + step >= max_step) { iValue++; lost_value = 0; break; } } iValue = iValue * max_step + lost_value; value = iValue * point; return NormalizeDouble(value,digits); } //+------------------------------------------------------------------+ double LotNormalize(double volume, string symbol) { double lotMin = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN); double lotMax = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX); double lotStep = SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP); if(volume < lotMin) return NormalizeDouble(lotMin,2); else if(volume > lotMax) return NormalizeDouble(lotMax,2); else { int i_volume = (int)(volume / lotStep); volume = i_volume * lotStep; } return NormalizeDouble(volume,2); } //+------------------------------------------------------------------+ int CountOrders(const MqlParam &Params[]) { uint magic = NULL; string symbol = ""; ENUM_ORDER_TYPE type = -1; int param_size = ArraySize(Params); for(int i = 0;i < param_size;i++) { if(Params[i].type == TYPE_UINT) magic = (uint)Params[i].integer_value; if(Params[i].type == TYPE_STRING) symbol = Params[i].string_value; if(Params[i].type == TYPE_INT) type = (ENUM_ORDER_TYPE)Params[i].integer_value; } int count = 0; long total_ord = OrdersTotal(); if(total_ord == 0) return 0; for(int i = 0;i < total_ord;i++) { ulong order = OrderGetTicket(i); //Print("cur order = ",order); if(OrderSelect(order)) { uint ord_magic = (uint)OrderGetInteger(ORDER_MAGIC); string ord_symbol = OrderGetString(ORDER_SYMBOL); ENUM_ORDER_TYPE ord_type = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE); if((symbol == "" || symbol == ord_symbol) && (magic == NULL || magic == ord_magic) && (type == -1 || type == ord_type)) count++; } } return count; } //+------------------------------------------------------------------+ int GetPendingTickets(const MqlParam &Params[] , ulong &Orders[]) { int size = CountOrders(Params); ArrayResize(Orders,size); uint magic = NULL; string symbol = ""; ENUM_ORDER_TYPE type = -1; int param_size = ArraySize(Params); for(int i = 0;i < param_size;i++) { if(Params[i].type == TYPE_UINT) magic = (uint)Params[i].integer_value; if(Params[i].type == TYPE_STRING) symbol = Params[i].string_value; if(Params[i].type == TYPE_INT) type = (ENUM_ORDER_TYPE)Params[i].integer_value; } long total_ord = OrdersTotal(); int index = 0; for(int i = 0;i < total_ord;i++) { ulong order = OrderGetTicket(i); if(OrderSelect(order)) { uint ord_magic = (uint)OrderGetInteger(ORDER_MAGIC); string ord_symbol = OrderGetString(ORDER_SYMBOL); ENUM_ORDER_TYPE ord_type = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE); if((symbol == "" || symbol == ord_symbol) && (magic == NULL || magic == ord_magic) && (type == -1 || type == ord_type)) { Orders[index] = order; index++; if(index >= size) break; } } } return size; } //+------------------------------------------------------------------+ int GetHandle(string symbol, ENUM_TIMEFRAMES tf, ENUM_INDICATOR ind, const MqlParam &Params[]) { if(ind == IND_CUSTOM && Params[0].type != TYPE_STRING) { Print("Отсутствует имя пользовательского индикатора."); return INVALID_HANDLE; } return IndicatorCreate(symbol,tf,ind,ArraySize(Params),Params); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ bool Order_Modify(ulong order,double entry,int SL,int TP) { if(OrderSelect(order)) { double ord_op = OrderGetDouble(ORDER_PRICE_OPEN); string ord_symb = OrderGetString(ORDER_SYMBOL); ulong ord_mag = OrderGetInteger(ORDER_MAGIC); ENUM_ORDER_TYPE ord_type = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE); int symb_digits = (int)SymbolInfoInteger(ord_symb,SYMBOL_DIGITS); double symb_point = SymbolInfoDouble(ord_symb,SYMBOL_POINT); int stop_level = (int)SymbolInfoInteger(ord_symb,SYMBOL_TRADE_STOPS_LEVEL); MqlTradeRequest reqwest; MqlTradeResult result; ZeroMemory(reqwest); ZeroMemory(result); if(ord_type == ORDER_TYPE_BUY_STOP || ord_type == ORDER_TYPE_BUY_LIMIT) { if(entry > 0) reqwest.price = NormalizeDouble(entry,symb_digits); else reqwest.price = NormalizeDouble(ord_op,symb_digits); double current_ask = SymbolInfoDouble(ord_symb,SYMBOL_ASK); if(reqwest.price <= current_ask) reqwest.type = ORDER_TYPE_BUY_LIMIT; else reqwest.type = ORDER_TYPE_BUY_STOP; if(SL < 0) reqwest.sl = 0; else if(SL > 0) { if(SL < stop_level) SL = stop_level; reqwest.sl = NormalizeDouble(reqwest.price - SL * symb_point,symb_digits); //double current_bid = SymbolInfoDouble(pos_symb,SYMBOL_BID); //if(MathAbs(current_bid - reqwest.sl) / symb_point < freez_level) // reqwest.sl = NormalizeDouble(current_bid - SL * symb_point,symb_digits); } if(TP < 0) reqwest.tp = 0; else if(TP > 0) { if(TP < stop_level) TP = stop_level; reqwest.tp = NormalizeDouble(reqwest.price + TP * symb_point,symb_digits); //double current_bid = SymbolInfoDouble(pos_symb,SYMBOL_BID); //if(MathAbs(current_bid - reqwest.tp) / symb_point < freez_level) // reqwest.tp = NormalizeDouble(current_bid + TP * symb_point,symb_digits); } } else { if(entry > 0) reqwest.price = NormalizeDouble(entry,symb_digits); else reqwest.price = NormalizeDouble(ord_op,symb_digits); double current_bid = SymbolInfoDouble(ord_symb,SYMBOL_BID); if(reqwest.price >= current_bid) reqwest.type = ORDER_TYPE_SELL_LIMIT; else reqwest.type = ORDER_TYPE_SELL_STOP; if(SL < 0) reqwest.sl = 0; else if(SL > 0) { if(SL < stop_level) SL = stop_level; reqwest.sl = NormalizeDouble(reqwest.price + SL * symb_point,symb_digits); //double current_ask = SymbolInfoDouble(pos_symb,SYMBOL_ASK); //if(MathAbs(current_ask - reqwest.sl) / symb_point < freez_level) // reqwest.sl = NormalizeDouble(current_ask + SL * symb_point,symb_digits); } if(TP < 0) reqwest.tp = 0; else if(TP > 0) { if(TP < stop_level) TP = stop_level; reqwest.tp = NormalizeDouble(reqwest.price - TP * symb_point,symb_digits); //double current_ask = SymbolInfoDouble(pos_symb,SYMBOL_ASK); //if(MathAbs(current_ask - reqwest.tp) / symb_point < freez_level) // reqwest.tp = NormalizeDouble(current_ask - TP * symb_point,symb_digits); } } reqwest.order = order; reqwest.magic = ord_mag; reqwest.symbol = ord_symb; reqwest.action = TRADE_ACTION_MODIFY; for(int i = 0;i < 10;i++) { if(!OrderSend(reqwest,result)) { Print("Ордер №",order," не был модифицирован. Ошибка№",result.retcode); Sleep(500); } else return true; } } else Print("Ордер №",order," не найден."); return false; } //+------------------------------------------------------------------+ bool Delete_Order(ulong order) { if(OrderSelect(order)) { MqlTradeRequest reqwest; MqlTradeResult result; ZeroMemory(reqwest); ZeroMemory(result); reqwest.action = TRADE_ACTION_REMOVE; reqwest.order = order; for(int i = 0;i < 10;i++) { if(!OrderSend(reqwest,result)) { Print("Ордер №",order," не был удален. Ошибка№",result.retcode); Sleep(500); } else return true; } } else Print("Ордер №",order," не онаружен."); return false; } //+------------------------------------------------------------------+ enum LAST_POSITION_OPTION { LAST_POSITION_UP, LAST_POSITION_DOWN, LAST_POSITION_TIME }; //+------------------------------------------------------------------+ ulong Ticket_Last_Buy(const ulong &Positions[] , LAST_POSITION_OPTION last_pos) { ulong ticket = 0; double open = 0; datetime time = 0; int size = ArraySize(Positions); for(int i = 0;i < size;i++) { ulong pos = Positions[i]; if(PositionSelectByTicket(pos)) { if(PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_BUY) continue; double pos_open = PositionGetDouble(POSITION_PRICE_OPEN); datetime pos_time = (datetime)PositionGetInteger(POSITION_TIME); if(last_pos == LAST_POSITION_DOWN) { if(open == 0 || pos_open < open) { open = pos_open; time = pos_time; ticket = pos; } } else if(last_pos == LAST_POSITION_UP) { if(open == 0 || pos_open > open) { open = pos_open; time = pos_time; ticket = pos; } } else if(last_pos == LAST_POSITION_TIME) { if(time == 0 || pos_time > time) { open = pos_open; time = pos_time; ticket = pos; } } } } return ticket; } //+------------------------------------------------------------------+ ulong Ticket_Last_Sell(const ulong &Positions[] , LAST_POSITION_OPTION last_pos) { ulong ticket = 0; double open = 0; datetime time = 0; int size = ArraySize(Positions); for(int i = 0;i < size;i++) { ulong pos = Positions[i]; //Print("Position sell = ",pos); if(PositionSelectByTicket(pos)) { if(PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_SELL) continue; double pos_open = PositionGetDouble(POSITION_PRICE_OPEN); datetime pos_time = (datetime)PositionGetInteger(POSITION_TIME); if(last_pos == LAST_POSITION_DOWN) { if(open == 0 || pos_open < open) { open = pos_open; time = pos_time; ticket = pos; } } else if(last_pos == LAST_POSITION_UP) { if(open == 0 || pos_open > open) { open = pos_open; time = pos_time; ticket = pos; } } else if(last_pos == LAST_POSITION_TIME) { if(time == 0 || pos_time > time) { open = pos_open; time = pos_time; ticket = pos; } } } } return ticket; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ double GetComission(ulong position) { if(!HistorySelectByPosition(position)) return 0; double comm = 0; int tot_deals = HistoryDealsTotal(); for(int i = 0;i < tot_deals;i++) { ulong deal = HistoryDealGetTicket(i); comm += HistoryDealGetDouble(deal,DEAL_COMMISSION); } return comm; } //+------------------------------------------------------------------+ double Profit(ulong position, double out_comission, bool subtotals = false) { double total_profit = 0; double profit = 0, swap = 0, comission = 0; double volume = 0; if(PositionSelectByTicket(position)) { profit = PositionGetDouble(POSITION_PROFIT); swap = PositionGetDouble(POSITION_SWAP); volume = PositionGetDouble(POSITION_VOLUME); } if(HistorySelectByPosition(position)) { int total_deals = HistoryDealsTotal(); for(int i = 0;i < total_deals;i++) { ulong deal = HistoryDealGetTicket(i); if(subtotals) { profit += HistoryDealGetDouble(deal,DEAL_PROFIT); swap += HistoryDealGetDouble(deal,DEAL_SWAP); } comission += HistoryDealGetDouble(deal,DEAL_COMMISSION); } } total_profit = (profit + swap + comission) - out_comission * volume; return NormalizeDouble(total_profit,2); } //+---------------------------------------------------------------+ double Profit_History(datetime begin_time , datetime end_time , string symbol , uint magic) { ulong Positions[]; MqlParam params[2]; params[0].type = TYPE_STRING; params[0].string_value = symbol; params[1].type = TYPE_UINT; params[1].integer_value = magic; GetPositionsTickets(params, Positions); double total_profit = 0; double profit = 0, swap = 0, comission = 0; if(HistorySelect(begin_time,end_time)) { for(int i = 0;i < HistoryDealsTotal();i++) { ulong deal = HistoryDealGetTicket(i); string deal_symbol = HistoryDealGetString(deal,DEAL_SYMBOL); ulong deal_magic = HistoryDealGetInteger(deal,DEAL_MAGIC); if(deal_symbol == symbol && deal_magic == magic) { for(int z = 0;z < ArraySize(Positions);z++) { ulong deal_pos = HistoryDealGetInteger(deal,DEAL_POSITION_ID); if(deal_pos == Positions[z]) { deal = 0; break; } } if(deal > 0) total_profit += HistoryDealGetDouble(deal,DEAL_PROFIT) + HistoryDealGetDouble(deal,DEAL_SWAP) + HistoryDealGetDouble(deal,DEAL_COMMISSION); } } } return NormalizeDouble(total_profit,2); } //+---------------------------------------------------------------+ bool Close_Position(ulong position, int slipage) { if(PositionSelectByTicket(position)) { string pos_symb = PositionGetString(POSITION_SYMBOL); ulong pos_mag = PositionGetInteger(POSITION_MAGIC); double pos_volume = PositionGetDouble(POSITION_VOLUME); ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); MqlTradeRequest reqwest; MqlTradeResult result; ZeroMemory(reqwest); ZeroMemory(result); if(pos_type == POSITION_TYPE_BUY) { reqwest.price = SymbolInfoDouble(pos_symb,SYMBOL_BID); reqwest.type = ORDER_TYPE_SELL; } else { reqwest.price = SymbolInfoDouble(pos_symb,SYMBOL_ASK); reqwest.type = ORDER_TYPE_BUY; } reqwest.position = position; reqwest.magic = pos_mag; reqwest.symbol = pos_symb; reqwest.volume = pos_volume; reqwest.deviation = slipage; reqwest.action = TRADE_ACTION_DEAL; for(int i = 0;i < 10;i++) { if(!OrderSend(reqwest,result)) { Print("Позиция №",position," не была закрыта. Ошибка№",result.retcode); Sleep(500); } else return true; } } else Print("Позиция №",position," не найдена."); return false; } //+------------------------------------------------------------------+ bool SetTralLevel(ulong position , int tralLevel) { if(PositionSelectByTicket(position)) { double pos_open = PositionGetDouble(POSITION_PRICE_OPEN); ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); double pos_sl = PositionGetDouble(POSITION_SL); string pos_symbol = PositionGetString(POSITION_SYMBOL); int pos_magic = (int)PositionGetInteger(POSITION_MAGIC); if(pos_type == POSITION_TYPE_BUY) { double close_price = SymbolInfoDouble(pos_symbol,SYMBOL_BID); double point = SymbolInfoDouble(pos_symbol,SYMBOL_POINT); if(close_price > pos_open) { double tral_level; if(pos_sl < pos_open) tral_level = pos_open + tralLevel * point; else tral_level = pos_sl + tralLevel * point; int stop_level = (int)SymbolInfoInteger(pos_symbol,SYMBOL_TRADE_STOPS_LEVEL); if(DistPrices(close_price,tral_level,pos_symbol) < stop_level) tral_level = close_price - stop_level * point; if(tral_level > pos_sl) { MqlTradeRequest reqwest; MqlTradeResult result; ZeroMemory(reqwest); ZeroMemory(result); reqwest.position = position; reqwest.action = TRADE_ACTION_SLTP; reqwest.sl = tral_level; reqwest.symbol = pos_symbol; reqwest.magic = pos_magic; if(OrderSend(reqwest,result)) return true; else Print("Ошибка тралирования ",result.retcode); } else return true; } } else { double close_price = SymbolInfoDouble(pos_symbol,SYMBOL_ASK); double point = SymbolInfoDouble(pos_symbol,SYMBOL_POINT); if(close_price < pos_open) { double tral_level; if(pos_sl < pos_open) tral_level = pos_open - tralLevel * point; else tral_level = pos_sl - tralLevel * point; int stop_level = (int)SymbolInfoInteger(pos_symbol,SYMBOL_TRADE_STOPS_LEVEL); if(DistPrices(close_price,tral_level,pos_symbol) < stop_level) tral_level = close_price + stop_level * point; if(tral_level > pos_sl) { MqlTradeRequest reqwest; MqlTradeResult result; ZeroMemory(reqwest); ZeroMemory(result); reqwest.position = position; reqwest.action = TRADE_ACTION_SLTP; reqwest.sl = tral_level; reqwest.symbol = pos_symbol; reqwest.magic = pos_magic; if(OrderSend(reqwest,result)) return true; else Print("Ошибка тралирования ",result.retcode); } else return true; } } } return false; } //+---------------------------------------------------------------+ bool Close_PartPosition(ulong position, int slipage, ulong opposing_pos) { if(!PositionSelectByTicket(position)) { Print(__FUNCTION__," Не найдена позиция для закрытия"); return false; } uint pos_magic = (uint)PositionGetInteger(POSITION_MAGIC); if(!PositionSelectByTicket(opposing_pos)) { Print(__FUNCTION__," Не найдена встречная позиция"); return false; } MqlTradeRequest reqwest; MqlTradeResult result; ZeroMemory(reqwest); ZeroMemory(result); reqwest.action = TRADE_ACTION_CLOSE_BY; reqwest.deviation = slipage; reqwest.position = position; reqwest.position_by = opposing_pos; reqwest.magic = pos_magic; if(OrderSend(reqwest,result)) return true; return false; } //+------------------------------------------------------------------+ /*double GetAveragePrice(const ulong &positions[], string symbol, double out_comm) { double totVolume = 0, totOpVolume = 0, totSwapCom = 0; int koef = 1; for(int i = 0,size = ::ArraySize(positions);i < size;i++) { if(!::PositionSelectByTicket(positions[i])) continue; if(::PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) koef = 1; else if(::PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) koef = -1; double volume = ::PositionGetDouble(POSITION_VOLUME); double op = ::PositionGetDouble(POSITION_PRICE_OPEN); totOpVolume += (volume * op * koef); totVolume += (volume * koef); //double commission = GetComission(positions[i]); totSwapCom += ::PositionGetDouble(POSITION_SWAP) /*+ commission *//*- out_comm * volume;*/ /*} if(totVolume == 0) return 0; double AvPrice = ::MathAbs(totOpVolume / totVolume); double point = ::SymbolInfoDouble(symbol,SYMBOL_POINT); if(totVolume > 0) AvPrice -= (totSwapCom / ::MathAbs(totVolume) * point); if(totVolume < 0) AvPrice += (totSwapCom / ::MathAbs(totVolume) * point); return ::NormalizeDouble(AvPrice,(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS)); }*/ //+------------------------------------------------------------------+ double GetPointValue(string symbol) { double point = SymbolInfoDouble(symbol,SYMBOL_POINT); double tickValue = SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_VALUE); double tickSize = SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE); double pointValue = tickValue * (point / tickSize); return pointValue; } //+------------------------------------------------------------------+ //flag = 0 - All volume; 1 - BUY only; 2 - SELL only double GetTotalVolume(const ulong &positions[], int flag = 0) { double tot_volume = 0; for(int i = 0,size = ArraySize(positions);i < size;i++) { if(!PositionSelectByTicket(positions[i])) continue; if(flag == 0) tot_volume += PositionGetDouble(POSITION_VOLUME); else { if(flag == 1) { if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) tot_volume += PositionGetDouble(POSITION_VOLUME); } else if(flag == 2) { if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) tot_volume += PositionGetDouble(POSITION_VOLUME); } } } return tot_volume; } //+------------------------------------------------------------------+ int GetIntFromDouble(double value, int digits) { int result = 0; if(digits == 1) result = (int)(value * 10); else if(digits == 2) result = (int)(value * 100); else if(digits == 3) result = (int)(value * 1000); else if(digits == 4) result = (int)(value * 10000); else if(digits == 5) result = (int)(value * 100000); return result; } //+------------------------------------------------------------------+ double GetDoubleFromInt(int value,int digits) { double result = 0.0; if(digits == 1) result = value * 0.1; else if(digits == 2) result = value * 0.01; else if(digits == 3) result = value * 0.001; else if(digits == 4) result = value * 0.0001; else if(digits == 5) result = value * 0.00001; return NormalizeDouble(result,digits); } //+------------------------------------------------------------------+ double CostPoint(string symbol, double volume, ENUM_POSITION_TYPE type) { double price = SymbolInfoDouble(symbol, SYMBOL_BID); if(type == POSITION_TYPE_SELL) price = SymbolInfoDouble(symbol, SYMBOL_ASK); if (price == 0) { PrintFormat("%s / ERROR: Добавьте в 'Обор рынка' %s", __FUNCTION__, symbol); return 0; } // определяем вспомогательные данные string xxx = StringSubstr(symbol, 0, 3); string yyy = StringSubstr(symbol, 3, 3); string tile = (StringLen(symbol) > 6) ? StringSubstr(symbol, 6) : ""; double contract = volume * SymbolInfoDouble(symbol, SYMBOL_TRADE_CONTRACT_SIZE); double costPoint = contract * SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); // определяем цену одного пункта if (yyy == "USD"); // обратная котировка // ничего не делаем else if (xxx == "USD") // прямая котировка costPoint = costPoint / price; else { // кросс-курс string symbol1 = yyy + "USD" + tile; price = SymbolInfoDouble(symbol1, SYMBOL_BID); if(type == POSITION_TYPE_SELL) price = SymbolInfoDouble(symbol, SYMBOL_ASK); if (price > 0) costPoint = costPoint * price; else { string symbol2 = "USD" + yyy + tile; price = SymbolInfoDouble(symbol2, SYMBOL_BID); if(type == POSITION_TYPE_SELL) price = SymbolInfoDouble(symbol, SYMBOL_ASK); if (price == 0) { PrintFormat("%s: Добавьте в 'Обор рынка' %s или %s", __FUNCTION__, symbol1, symbol2); return 0; } costPoint = costPoint / price; } } return costPoint; } //+---------------------------------------------------------------+ bool Close_PartPosition(ulong position, double close_volume, int slipage) { ResetLastError(); if(!PositionSelectByTicket(position)) { Print(__FUNCTION__," не смогла найти закрываемую позицию. Ошибка ",GetLastError()); return false; } string symbol = PositionGetString(POSITION_SYMBOL); uint magic = (uint)PositionGetInteger(POSITION_MAGIC); double lot = PositionGetDouble(POSITION_VOLUME); if(lot > close_volume) lot = close_volume; MqlTradeRequest reqwest; MqlTradeResult result; ZeroMemory(reqwest); ZeroMemory(result); if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { reqwest.type = ORDER_TYPE_SELL; reqwest.price = SymbolInfoDouble(symbol,SYMBOL_BID); } else { reqwest.type = ORDER_TYPE_BUY; reqwest.price = SymbolInfoDouble(symbol,SYMBOL_ASK); } reqwest.action = TRADE_ACTION_DEAL; reqwest.position = position; reqwest.symbol = symbol; reqwest.volume = lot; reqwest.magic = magic; reqwest.deviation = slipage; for(int i = 0;i < 10;i++) { if(!OrderSend(reqwest,result)) { Print("Частичное закрытие не удалось. Ошибка сервера ",result.retcode); Sleep(500); } else { return true; } } return false; } //+---------------------------------------------------------------+ ulong Ticket_Last_Buy(const ulong &Positions[] , LAST_POSITION_OPTION last_pos, const ulong ex_pos) { ulong ticket = 0; double open = 0; datetime time = 0; int size = ArraySize(Positions); for(int i = 0;i < size;i++) { ulong pos = Positions[i]; if(PositionSelectByTicket(pos)) { if(PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_BUY) continue; if(PositionGetInteger(POSITION_TICKET) == ex_pos) continue; double pos_open = PositionGetDouble(POSITION_PRICE_OPEN); datetime pos_time = (datetime)PositionGetInteger(POSITION_TIME); if(last_pos == LAST_POSITION_DOWN) { if(open == 0 || pos_open < open) { open = pos_open; time = pos_time; ticket = pos; } } else if(last_pos == LAST_POSITION_UP) { if(open == 0 || pos_open > open) { open = pos_open; time = pos_time; ticket = pos; } } else if(last_pos == LAST_POSITION_TIME) { if(time == 0 || pos_time > time) { open = pos_open; time = pos_time; ticket = pos; } } } } return ticket; } //+------------------------------------------------------------------+ ulong Ticket_Last_Sell(const ulong &Positions[] , LAST_POSITION_OPTION last_pos, const ulong ex_pos) { ulong ticket = 0; double open = 0; datetime time = 0; int size = ArraySize(Positions); for(int i = 0;i < size;i++) { ulong pos = Positions[i]; if(PositionSelectByTicket(pos)) { if(PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_SELL) continue; if(PositionGetInteger(POSITION_TICKET) == ex_pos) continue; double pos_open = PositionGetDouble(POSITION_PRICE_OPEN); datetime pos_time = (datetime)PositionGetInteger(POSITION_TIME); if(last_pos == LAST_POSITION_DOWN) { if(open == 0 || pos_open < open) { open = pos_open; time = pos_time; ticket = pos; } } else if(last_pos == LAST_POSITION_UP) { if(open == 0 || pos_open > open) { open = pos_open; time = pos_time; ticket = pos; } } else if(last_pos == LAST_POSITION_TIME) { if(time == 0 || pos_time > time) { open = pos_open; time = pos_time; ticket = pos; } } } } return ticket; } //+------------------------------------------------------------------+ ulong Ticket_Last_Buy(const ulong &Positions[] , LAST_POSITION_OPTION last_pos, const double ex_volume) { ulong ticket = 0; double open = 0; datetime time = 0; int size = ArraySize(Positions); for(int i = 0;i < size;i++) { ulong pos = Positions[i]; if(PositionSelectByTicket(pos)) { if(PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_BUY) continue; if(PositionGetDouble(POSITION_VOLUME) <= ex_volume) continue; double pos_open = PositionGetDouble(POSITION_PRICE_OPEN); datetime pos_time = (datetime)PositionGetInteger(POSITION_TIME); if(last_pos == LAST_POSITION_DOWN) { if(open == 0 || pos_open < open) { open = pos_open; time = pos_time; ticket = pos; } } else if(last_pos == LAST_POSITION_UP) { if(open == 0 || pos_open > open) { open = pos_open; time = pos_time; ticket = pos; } } else if(last_pos == LAST_POSITION_TIME) { if(time == 0 || pos_time > time) { open = pos_open; time = pos_time; ticket = pos; } } } } return ticket; } //+------------------------------------------------------------------+ ulong Ticket_Last_Sell(const ulong &Positions[] , LAST_POSITION_OPTION last_pos, const double ex_volume) { ulong ticket = 0; double open = 0; datetime time = 0; int size = ArraySize(Positions); for(int i = 0;i < size;i++) { ulong pos = Positions[i]; if(PositionSelectByTicket(pos)) { if(PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_SELL) continue; if(PositionGetDouble(POSITION_VOLUME) <= ex_volume) continue; double pos_open = PositionGetDouble(POSITION_PRICE_OPEN); datetime pos_time = (datetime)PositionGetInteger(POSITION_TIME); if(last_pos == LAST_POSITION_DOWN) { if(open == 0 || pos_open < open) { open = pos_open; time = pos_time; ticket = pos; } } else if(last_pos == LAST_POSITION_UP) { if(open == 0 || pos_open > open) { open = pos_open; time = pos_time; ticket = pos; } } else if(last_pos == LAST_POSITION_TIME) { if(time == 0 || pos_time > time) { open = pos_open; time = pos_time; ticket = pos; } } } } return ticket; } //+------------------------------------------------------------------+ /*double GetAveragePrice(const ulong &Positions[],string symbol,ENUM_POSITION_TYPE type,const double out_com) { for(int i = 0,size = ArraySize(Positions);i < size;i++) { if(!PositionSelectByTicket(Positions[i])) return 0; if(PositionGetInteger(POSITION_TYPE) != type) return 0; } double AvPrice = 0; return AvPrice; }*/ //+------------------------------------------------------------------+ enum ENUM_AVERAGE_DIRECTION { AVERAGE_DIRECTION_ALL = 0, AVERAGE_DIRECTION_BUY, AVERAGE_DIRECTION_SELL }; double GetAveragePrice(const ulong &Positions[], const double out_com, ENUM_AVERAGE_DIRECTION avDirection = AVERAGE_DIRECTION_ALL) { string symbol = ""; for(int i = 0,size = ArraySize(Positions);i < size;i++) { if(!PositionSelectByTicket(Positions[i])) return 0; if(symbol == "") symbol = PositionGetString(POSITION_SYMBOL); else if(symbol == PositionGetString(POSITION_SYMBOL)) continue; else if (symbol != "" && symbol != PositionGetString(POSITION_SYMBOL)) return 0; } double buyVolume = 0, sellVolume = 0, buyProfit = 0, sellProfit = 0; for(int i = 0,size = ArraySize(Positions);i < size;i++) { PositionSelectByTicket(Positions[i]); double lot = PositionGetDouble(POSITION_VOLUME); double profit = PositionGetDouble(POSITION_PROFIT); double swap = PositionGetDouble(POSITION_SWAP); double comission = GetComission(Positions[i]) + ((out_com * -1) * lot); double posProfit = profit + swap + comission; if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { buyVolume += lot; buyProfit += posProfit; } else { sellVolume += lot; sellProfit += posProfit; } } if(avDirection == AVERAGE_DIRECTION_ALL && buyVolume == sellVolume) return 0; else if(avDirection == AVERAGE_DIRECTION_BUY && buyVolume == 0) return 0; else if(avDirection == AVERAGE_DIRECTION_SELL && sellVolume == 0) return 0; double avPrice = 0; double tickValue = SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_VALUE); int digits = (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); double point = SymbolInfoDouble(symbol,SYMBOL_POINT); double bid = SymbolInfoDouble(symbol,SYMBOL_BID); double ask = SymbolInfoDouble(symbol,SYMBOL_ASK); double buyZeroLevel = bid - (buyProfit / (tickValue * buyVolume) * point); double sellZeroLevel = ask + (sellProfit / (tickValue * sellVolume) * point); buyZeroLevel = NormalizeDouble(buyZeroLevel,digits); sellZeroLevel = NormalizeDouble(sellZeroLevel,digits); if(buyVolume > sellVolume) avPrice = bid - ((buyProfit + sellProfit) / (tickValue * (buyVolume - sellVolume)) * point); else avPrice = ask + ((buyProfit + sellProfit) / (tickValue * (sellVolume - buyVolume)) * point); avPrice = NormalizeDouble(avPrice,digits); if(avDirection == AVERAGE_DIRECTION_BUY) return buyZeroLevel; else if(avDirection == AVERAGE_DIRECTION_SELL) return sellZeroLevel; else return avPrice; } //+------------------------------------------------------------------+ template string GetTypeName(const T &t){ return (typename(T)); } //+------------------------------------------------------------------+ template bool fileWriteBinStuct(const string &file, const T &fiboStruct){ int handle =::FileOpen(file,FILE_WRITE|FILE_BIN); ::ResetLastError(); if(handle == INVALID_HANDLE){ ::Print("Unable acces to file ",file," Error ",::GetLastError()); return false; } uint count = ::FileWriteStruct(handle,fiboStruct); if(count == 0){ ::Print("Unable write data to file ",file," Error ",::GetLastError()); return false; } ::FileClose(handle); return true; } //+------------------------------------------------------------------+ template bool fileReadBinStuct(const string &file, T &Struct){ int handle =::FileOpen(file,FILE_READ|FILE_BIN); ::ResetLastError(); if(handle == INVALID_HANDLE){ ::Print("Unable acces to file ",file," Error ",::GetLastError()); return false; } uint count = ::FileReadStruct(handle,Struct); if(count == 0){ ::Print("Unable read data from file ",file," Error ",::GetLastError()); return false; } ::FileClose(handle); return true; } //+------------------------------------------------------------------+ void GetFillMode(const string symbol,ENUM_ORDER_TYPE_FILLING &fill_type){ uint filling = (uint)::SymbolInfoInteger(symbol,SYMBOL_FILLING_MODE); if((filling&SYMBOL_FILLING_FOK) == SYMBOL_FILLING_FOK) fill_type = ORDER_FILLING_FOK; else if((filling&SYMBOL_FILLING_IOC) == SYMBOL_FILLING_IOC) fill_type = ORDER_FILLING_IOC; else fill_type = ORDER_FILLING_RETURN; } //------------------------------------------------------------------| // END OF NAMESPACE std | //------------------------------------------------------------------| } #endif