//+------------------------------------------------------------------+ //| Breakdowning martingail™ v 0.9.4.mq4 | //| Copyright © 2006, B@ss & Steve | //| albass@mail333.com | //+------------------------------------------------------------------+ #property copyright "Copyright © 2006, B@ss & Steve" #property link "albass@mail333.com, http://forum.alpari-idc.ru" //---- #include // если false, то при закрытии текущей серии, новые ордера не будут // открываться. extern bool TradeAllowed = true; // шаг в пунктах уровней extern int Shag = 20; // размер торгуемого лота, при выключенном ММ extern double startLots = 0.1; // включение MoneyManagement extern bool MoneyManagement = true; // логарифмический MoneyManagement extern bool LogariphmicMM = true; // размер лота в процентах от депозита extern double Riskfactor = 4; // размер нужного профита в процентах от депозита extern double ProfitPercent = 0.4; // включение оптимального закрытия ордеров (повышает доходность) extern bool OptimalTakeProfit = true; // закрытие ордеров по тейкпрофитам и стоп-лоссам extern bool Close_on_TP = false; /* два режима Close_on_TP: true - двигая первый уровень при достижении TP (если уровни обоих плечей равны) false - идентичный тому, если Close_on_TP выключен (если уровни обоих плечей равны, то TP=0)*/ extern bool Mode_Close_on_TP = true; // показывать служебную информацию по ордерам в журнале терминала extern bool ShowLog = false; //---- int timeOut = 5000; int maxLevel = 9; // максимальный открытый уровень double LotsLevel_2 = 1; // шаг приращения лотов с увеличением уровня double LotsLevel_3 = 2; double LotsLevel_4 = 4; double LotsLevel_5 = 8; double LotsLevel_6 = 16; double LotsLevel_7 = 32; double LotsLevel_8 = 64; double LotsLevel_9 = 128; //+------------------------------------------------------------------+ //| Функция проверяет наличие ордера с данным магическим номером | //+------------------------------------------------------------------+ bool isMgNum(int num) { int t, cnt1; t = OrdersTotal(); //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS, MODE_TRADES); //---- if(OrderMagicNumber() == num && OrderSymbol() == Symbol()) { return (True); // возвращаемое значение } } return (False); } //+------------------------------------------------------------------+ //| Функция удаления ордера по магическому номеру | //+------------------------------------------------------------------+ bool deleteOrderNum(int num) { int t, cnt1, err; bool tic; t = OrdersTotal(); //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS, MODE_TRADES); //---- if(OrderSymbol() == Symbol()) { // только для данного инструмента if(OrderMagicNumber() == num && (OrderType()==OP_BUYSTOP || OrderType() == OP_SELLSTOP)) { int start = GetTickCount(); tic = OrderDelete(OrderTicket()); Print("Время удаления ", (GetTickCount() - start) / 1000, " секунд."); //---- if(tic) PlaySound("timeout.wav"); //---- if(!tic) { err = GetLastError(); Print("Ошибка = ", err, " (", ErrorDescription(err), ")"); } return(True); // возвращаемое значение } } } return (False); } //+------------------------------------------------------------------+ //| Функция, проверяющая, активирован ли данный ордер в открытую | //| позицию | //+------------------------------------------------------------------+ bool isOrderActive(int num) // имя функции и список параметров { int t, cnt1; t = OrdersTotal(); //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS, MODE_TRADES); //---- if(OrderSymbol() == Symbol()) { //---- if(OrderMagicNumber()== num) { //---- if(OrderType() == OP_BUY || OrderType() == OP_SELL) { return(True); // возвращаемое значение } } } } return (False); } //+------------------------------------------------------------------+ //| Определение максимально открытых лотов по данному инструменту | //+------------------------------------------------------------------+ double getTopLots (int mode) // имя функции и список параметров { int t, cnt1; double topL, topL_buy, topL_sell; t = OrdersTotal(); topL = 0; for(cnt1 = 0; cnt1 < t; cnt1++) //---- { OrderSelect(cnt1, SELECT_BY_POS, MODE_TRADES); //---- if(OrderSymbol() == Symbol()) { //---- if(OrderType() == OP_BUY && mode == 1) // для бай { //---- if(OrderLots() > topL) { topL = OrderLots(); } } //---- if(OrderType() == OP_SELL && mode == 2) // для селл { if(OrderLots() > topL) { topL = OrderLots(); } } // разница в лотах между бай и селл (для вычисления профита нужного) if(mode == 3) { //---- if(OrderType() == OP_SELL && OrderLots() > topL_sell) { topL_sell = OrderLots(); } //---- if(OrderType() == OP_BUY && OrderLots() > topL_buy) { topL_buy = OrderLots(); } topL = MathAbs(topL_sell - topL_buy); } } } return (topL); } //+------------------------------------------------------------------+ //| Определение масимального уровня для длинных или коротких позиций| | //+------------------------------------------------------------------+ int getTopLevel (int mode) // имя функции и список параметров { int t, cnt1, tLev, cLev; t = OrdersTotal(); cLev = 0; tLev = 0; //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS, MODE_TRADES); //---- if(OrderSymbol() == Symbol()) { //---- if(OrderType() == OP_BUY || OrderType() == OP_SELL) { //только активированные позиции if(mode == 1) { //проверка уровня для лонгов if(OrderMagicNumber() == 851) cLev = 9; //---- if(OrderMagicNumber() == 841) cLev = 8; //---- if(OrderMagicNumber() == 831) cLev = 7; //---- if(OrderMagicNumber() == 821) cLev = 6; //---- if(OrderMagicNumber() == 811) cLev = 5; //---- if(OrderMagicNumber() == 801) cLev = 4; //---- if(OrderMagicNumber() == 791) cLev = 3; //---- if(OrderMagicNumber() == 781) cLev = 2; //---- if(OrderMagicNumber() == 771) cLev = 1; } else { //проверка уровня для шортов if(OrderMagicNumber() == 852) cLev = 9; //---- if(OrderMagicNumber() == 842) cLev = 8; //---- if(OrderMagicNumber() == 832) cLev = 7; //---- if(OrderMagicNumber() == 822) cLev = 6; //---- if(OrderMagicNumber() == 812) cLev = 5; //---- if(OrderMagicNumber() == 802) cLev = 4; //---- if(OrderMagicNumber() == 792) cLev = 3; //---- if(OrderMagicNumber() == 782) cLev = 2; //---- if(OrderMagicNumber() == 772) cLev = 1; } } } //---- if(cLev > tLev) tLev = cLev; } return (tLev); } //+------------------------------------------------------------------+ //| Определение, сколько лотов открывать по заданному номеру уровня | //+------------------------------------------------------------------+ double getLotByLevel (int level) // функция для вычисления лота по уровню { double lot1; lot1 = startLots; // значение по умолчанию // первые ордера - только для отсчета уровней, позиции размером 0,1 лота if(level == 1) lot1 = 0.1; //---- if(level == 2) lot1 = NormalizeDouble(startLots*LotsLevel_2, 1); //---- if(level == 3) lot1 = NormalizeDouble(startLots*LotsLevel_3, 1); //---- if(level == 4) lot1 = NormalizeDouble(startLots*LotsLevel_4, 1); //---- if(level == 5) lot1 = NormalizeDouble(startLots*LotsLevel_5, 1); //---- if(level == 6) lot1 = NormalizeDouble(startLots*LotsLevel_6, 1); //---- if(level == 7) lot1 = NormalizeDouble(startLots*LotsLevel_7, 1); //---- if(level == 8) lot1 = NormalizeDouble(startLots*LotsLevel_8, 1); //---- if(level == 9) lot1 = NormalizeDouble(startLots*LotsLevel_9, 1); return(lot1); } //+------------------------------------------------------------------+ //| Функция для получения цены открытия ордера по его магическому | //| номеру | //+------------------------------------------------------------------+ double getOrderPriceByNum (int num) { int t, cnt1; t = OrdersTotal(); //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS, MODE_TRADES); //---- if(OrderSymbol() == Symbol()) { //---- if(OrderMagicNumber() == num) { return(OrderOpenPrice()); } } } return (0); } //+------------------------------------------------------------------+ //| Функция для получения времени открытия ордера по его магическому| //| номеру | //+------------------------------------------------------------------+ datetime getOrderOpenTimeByNum (int num) { int t, cnt1; t = OrdersTotal(); //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS, MODE_TRADES); //---- if(OrderSymbol() == Symbol()) { //---- if(OrderMagicNumber() == num) { return(OrderOpenTime()); } } } return (0); } //+------------------------------------------------------------------+ //| Функция считает открытые лоты для лонгов по данному инструменту | //+------------------------------------------------------------------+ double getBuyLotsSum(int mode) { int t, cnt1; double sm; t = OrdersTotal(); sm = 0; //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS, MODE_TRADES); //---- if(mode != 1) { //---- if(OrderType() == OP_BUY && OrderSymbol() == Symbol()) { sm = sm + OrderLots(); } } else { //а здесь по всем открытым позициям счета if(OrderType() == OP_BUY) { sm = sm + OrderLots(); } } } return(sm); } //+------------------------------------------------------------------+ //| Функция считает открытые лоты для шортов по данному инструменту | //+------------------------------------------------------------------+ double getSellLotsSum(int mode) { int t, cnt1; double sm; t = OrdersTotal(); sm = 0; //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS, MODE_TRADES); //---- if(mode != 1) { //---- if(OrderType() == OP_SELL && OrderSymbol() == Symbol()) { sm = sm + OrderLots(); } } else { //а здесь по всем открытым позициям счета if(OrderType() == OP_SELL) { sm = sm + OrderLots(); } } } return(sm); } //+------------------------------------------------------------------+ //| Функция для модификации отложенных ордеров лонгов. Здесь | //| определяем максимальный магический номер открытого ордера для | //| лонгов | //+------------------------------------------------------------------+ int getMaxLongNum() { int t, cnt1; int topL; t = OrdersTotal(); topL = 0; //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS, MODE_TRADES); //---- if(OrderSymbol() == Symbol()) { //---- if(OrderType() == OP_BUY) { //---- if(OrderMagicNumber() > topL) topL = OrderMagicNumber(); } } } return (topL); } //+------------------------------------------------------------------+ //| Функция определяет максимальный магический номер открытого | //| ордера для шортов | //+------------------------------------------------------------------+ int getMaxShortNum() { int t, cnt1; int topL; t = OrdersTotal(); topL = 0; //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS, MODE_TRADES); //---- if(OrderSymbol() == Symbol()) { //---- if(OrderType() == OP_SELL) { //---- if(OrderMagicNumber() > topL) topL = OrderMagicNumber(); } } } return (topL); } //+------------------------------------------------------------------+ //| Функция определяет следующий магический номер по данному | //+------------------------------------------------------------------+ int getNextOrderNum(int n1) { //---- if(n1 == 771) return(781); //---- if(n1 == 781) return(791); //---- if(n1 == 791) return(801); //---- if(n1 == 801) return(811); //---- if(n1 == 811) return(821); //---- if(n1 == 821) return(831); //---- if(n1 == 831) return(841); //---- if(n1 == 841) return(851); //---- if(n1 == 772) return(782); //---- if(n1 == 782) return(792); //---- if(n1 == 792) return(802); //---- if(n1 == 802) return(812); //---- if(n1 == 812) return(822); //---- if(n1 == 822) return(832); //---- if(n1 == 832) return(842); //---- if(n1 == 842) return(852); return (0); } //+------------------------------------------------------------------+ //| Функция вычисления магического номера по номеру уровня | //+------------------------------------------------------------------+ int getNum(int dir, int level) { //---- if(dir == 1) { //для лонгов if(level == 1) return(771); //---- if(level == 2) return(781); //---- if(level == 3) return(791); //---- if(level == 4) return(801); //---- if(level == 5) return(811); //---- if(level == 6) return(821); //---- if(level == 7) return(831); //---- if(level == 8) return(841); //---- if(level == 9) return(851); } else { //---- if(level == 1) return(772); //---- if(level == 2) return(782); //---- if(level == 3) return(792); //---- if(level == 4) return(802); //---- if(level == 5) return(812); //---- if(level == 6) return(822); //---- if(level == 7) return(832); //---- if(level == 8) return(842); //---- if(level == 9) return(852); } } //+------------------------------------------------------------------+ //| Функция модификации отложенного ордера. Здесь получаем | //| вычисленные цены открытия и тэйкпрофита для отложенных ордеров | //| и если они отличаются от цен модифицируемого ордера, изменяем их| //+------------------------------------------------------------------+ int modOrder(int num, double oprice, double prprice) { int t, cnt1, err, start; bool tic; double p1, p2; t = OrdersTotal(); //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS, MODE_TRADES); //---- if(OrderSymbol() == Symbol() && OrderMagicNumber() == num) { //---- if((OrderOpenPrice() != oprice || OrderTakeProfit() != prprice) && oprice != 0) { //---- if(OrderType() == OP_BUYSTOP) { p1 = oprice; p2 = prprice; NormalizeDouble(p2, MarketInfo(Symbol(), MODE_DIGITS)); NormalizeDouble(p1, MarketInfo(Symbol(), MODE_DIGITS)); //---- if(NormalizeDouble(OrderOpenPrice(), Digits) != NormalizeDouble(p1, Digits) || NormalizeDouble(OrderTakeProfit(), Digits) != NormalizeDouble(p2, Digits)) { start = GetTickCount(); tic = OrderModify(OrderTicket(), p1, 0, p2, 0, Green); //---- if(ShowLog) { Print("модиф BUYSTOP ", OrderOpenPrice(), "->", p1, " t/p ", OrderTakeProfit(),"->", p2); Print("Время модификации ", (GetTickCount()-start)/1000, " секунд."); } //---- if(tic) PlaySound("alert.wav"); //---- if(!tic) { err = GetLastError(); Print("Ошибка = ", err, " (", ErrorDescription(err), ")"); } Sleep(timeOut); } } //---- if(OrderType() == OP_SELLSTOP) { p1 = oprice; p2 = prprice; NormalizeDouble(p2, MarketInfo(Symbol(), MODE_DIGITS)); NormalizeDouble(p1, MarketInfo(Symbol(), MODE_DIGITS)); //---- if(NormalizeDouble(OrderOpenPrice(), Digits) != NormalizeDouble(p1, Digits) || NormalizeDouble(OrderTakeProfit(), Digits) != NormalizeDouble(p2, Digits)) { start = GetTickCount(); tic = OrderModify(OrderTicket(), p1, 0, p2, 0, Green); //---- if(ShowLog) { Print("модиф SELLSTOP ", OrderOpenPrice(), "->", p1, " t/p ", OrderTakeProfit(),"->", p2); Print("Время модификации ", (GetTickCount()-start)/1000, " секунд."); } //---- if(tic) PlaySound("alert.wav"); //---- if(!tic) { err = GetLastError(); Print("Ошибка = ", err, " (", ErrorDescription(err), ")"); } Sleep(timeOut); } } } } } return (1); } //+------------------------------------------------------------------+ //| Функция подсчет профита по позициям в зависимости от режима. При| //| mode=1 только для текущего инструмента, при любом другом для | //| всех позиций счета | //+------------------------------------------------------------------+ double getAllProfit(int mode) { int t, cnt1; double pf; t = OrdersTotal(); pf = 0; //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS, MODE_TRADES); //---- if(mode == 1) { //---- if(OrderSymbol() == Symbol() && (OrderType() == OP_BUY || OrderType() == OP_SELL)) { pf = pf + OrderProfit() + OrderSwap() + OrderCommission(); } } else { //---- if(mode == 2 && OrderSymbol() == Symbol() && OrderType() == OP_BUY) { pf = pf + OrderProfit() + OrderSwap() + OrderCommission(); } //---- if(mode == 3 && OrderSymbol() == Symbol() && OrderType() == OP_SELL) { pf = pf + OrderProfit() + OrderSwap() + OrderCommission(); } } } return (pf); } //+------------------------------------------------------------------+ //| при любом другом для всех позиций счета | //+------------------------------------------------------------------+ double getDayProfit(int mode, int dayShift) { int t, cnt1, cyear, cmonth, cday; double pf; datetime ctm; t = HistoryTotal(); pf = 0; //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS, MODE_HISTORY); ctm = OrderCloseTime(); cyear = TimeYear(ctm); cmonth = TimeMonth(ctm); cday = TimeDay(ctm); //---- if(cyear == Year() && cmonth == Month() && cday == (Day() - dayShift)) { //---- if(mode==1) { //прибыль по лонгам и шортам if(OrderType() == OP_BUY || OrderType() == OP_SELL) { pf = pf + OrderProfit() + OrderSwap() + OrderCommission(); } } else { //---- if(mode == 2 && OrderType() == OP_BUY) { //прибыль только по лонгам pf = pf + OrderProfit() + OrderSwap() + OrderCommission(); } //---- if(mode == 3 && OrderType() == OP_SELL) { //прибыль только по шортам pf = pf + OrderProfit() + OrderSwap() + OrderCommission(); } } } } return (pf); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double getLevelPositions(int mode, int level) { int t, cnt1; double pf; t = HistoryTotal(); pf = 0; //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS, MODE_HISTORY); //---- if(OrderSymbol() == Symbol()) { //проверка инструмента if(OrderType() == OP_BUY || OrderType() == OP_SELL) { //---- if(mode == 1 && (OrderMagicNumber() == level || OrderMagicNumber() == (level + 1))) { //считаем только сделки одного уровня pf = pf + 1; } //---- if(mode == 2) { //счет сделок по всем уровням pf = pf + 1; } } } } return (pf); } //+------------------------------------------------------------------+ //| Расчет цены, по которой выставляется ордер SellStop | //+------------------------------------------------------------------+ double setPriceSellStop() { double topPrice, PriceSetka, HighestPriceInRange; int NumPoloski, NumBarsAfterOpenedOrder; datetime OpenOrderTime; topPrice = getOrderPriceByNum(getMaxShortNum()); OpenOrderTime = getOrderOpenTimeByNum(getMaxShortNum()); NumBarsAfterOpenedOrder = iBarShift(NULL, 0, OpenOrderTime, false); HighestPriceInRange = Highest(NULL, 0, MODE_HIGH, NumBarsAfterOpenedOrder, 0); // номер полоски под текущей ценой BID NumPoloski = MathAbs(MathFloor((Bid - topPrice) / (Shag*Point))); // значение цены, соответствующее этой полоске PriceSetka = topPrice + NumPoloski*Shag*Point; //---- if(HighestPriceInRange < PriceSetka + Shag*Point && PriceSetka >= topPrice+Shag*Point && Bid > topPrice) { return(NormalizeDouble(PriceSetka - Shag*Point,Digits)); } } //+------------------------------------------------------------------+ //| Расчет цены, по которой выставляется ордер BuyStop | //+------------------------------------------------------------------+ double setPriceBuyStop() { double lowPrice, PriceSetka, LowestPriceInRange; int NumPoloski, NumBarsAfterOpenedOrder; datetime OpenOrderTime; lowPrice = getOrderPriceByNum(getMaxLongNum()); OpenOrderTime = getOrderOpenTimeByNum(getMaxLongNum()); NumBarsAfterOpenedOrder = iBarShift(NULL, 0, OpenOrderTime, false); LowestPriceInRange = Lowest(NULL, 0, MODE_LOW, NumBarsAfterOpenedOrder, 0); // номер полоски над текущей ценой ASK NumPoloski = MathAbs(MathFloor((lowPrice - Ask) / (Shag*Point))); // значение цены, соответствующее этой полоске PriceSetka = lowPrice - NumPoloski*Shag*Point; //---- if(LowestPriceInRange > PriceSetka - Shag*Point && PriceSetka <= lowPrice - Shag*Point && Ask < lowPrice) { return(NormalizeDouble(PriceSetka + Shag*Point,Digits)); } } //+------------------------------------------------------------------+ //| Функция закрытия ордеров по достижению профита | //+------------------------------------------------------------------+ bool getProfitOrdersClose() { int cnt1, err, tic1,tic2, LotBy, LotBy1,i; bool ticdone; int T1[10], T2[10], a; a = 0; //---- for(cnt1 = 0; cnt1 < OrdersTotal(); cnt1++) { //проверяем, можно ли закрыть встречные ордера без потери спреда OrderSelect(cnt1, SELECT_BY_POS); tic1 = OrderTicket(); LotBy = OrderLots(); //---- if(OrderType() == OP_SELL) { //---- for(i = 0; i < OrdersTotal(); i++) { OrderSelect(i, SELECT_BY_POS); tic2 = OrderTicket(); LotBy1 = OrderLots(); //---- if(OrderType() == OP_BUY && LotBy == LotBy1 && OrderSelect(tic1, SELECT_BY_TICKET) && OrderSelect(tic2, SELECT_BY_TICKET)) { T1[a] = tic1; T2[a] = tic2; a++; } } } } for(cnt1 = 0; cnt1 < a; cnt1++) { // закрываем встречные ордера if(OrderSelect(T1[cnt1], SELECT_BY_TICKET) && OrderSelect(T2[cnt1], SELECT_BY_TICKET)) { ticdone = OrderCloseBy(T1[cnt1], T2[cnt1], Green); //---- if(!ticdone) { err = GetLastError(); //---- if(err != 0 && err != 1) Print ("Ошибка закрытия встречного ордера = ", ErrorDescription(err)); } Sleep(timeOut); } } for(cnt1 = OrdersTotal(); cnt1 >= 0; cnt1--) { // закрываем все оставшиеся ордера OrderSelect(cnt1, SELECT_BY_POS, MODE_TRADES); //---- if(OrderSymbol() == Symbol()) { //---- if(OrderType() == OP_BUY) { ticdone = OrderClose(OrderTicket(), OrderLots(), Ask, 3, Green); //---- if(ticdone) PlaySound("timeout.wav"); //---- if(!ticdone) { err = GetLastError(); if(err != 0) Print("Ошибка закрытия ордера = ", ErrorDescription(err)); } Sleep(timeOut); } //---- if(OrderType() == OP_SELL) { ticdone = OrderClose(OrderTicket(), OrderLots(), Bid, 3, Green); //---- if(ticdone) PlaySound("timeout.wav"); //---- if(!ticdone) { err = GetLastError(); //---- if(err != 0) Print("Ошибка закрытия ордера = ", ErrorDescription(err)); } Sleep(timeOut); } } } return (False); } //+------------------------------------------------------------------+ //| Сумма лотов всех открытых позиций в одну сторону для вычисления | //| значения тейкпрофита всей серии | //+------------------------------------------------------------------+ double getSumLots(int mode) { int i; double sumLots; //---- for(i = 0; i <= OrdersTotal(); i++) { OrderSelect(i, SELECT_BY_POS); //---- if(OrderType() == OP_BUY && mode == 1) { sumLots = sumLots + OrderLots(); } //---- if(OrderType() == OP_SELL && mode == 2) { sumLots = sumLots + OrderLots(); } } return(sumLots); } //+------------------------------------------------------------------+ //| Взвешенная цена для всех позиций в одну сторону для вычисления | //| значения тейкпрофита всей серии | //+------------------------------------------------------------------+ double getSumWeightedPrice(int mode) { int i; double sumWeightedPrice; //---- for(i = 0; i <= OrdersTotal(); i++) { OrderSelect(i, SELECT_BY_POS); //---- if(OrderType() == OP_BUY && mode == 1) { sumWeightedPrice = sumWeightedPrice + OrderLots()*OrderOpenPrice(); } //---- if(OrderType() == OP_SELL && mode == 2) { sumWeightedPrice = sumWeightedPrice + OrderLots()*OrderOpenPrice(); } } return(sumWeightedPrice); } //+------------------------------------------------------------------+ //| Определение цен закрытия всех ордеров, необходимых для | //| выставления тейкпрофитов и стоплоссов для ордеров | //+------------------------------------------------------------------+ double getOptimalTakeProfit(bool mode, bool SELL_BUY) { //с учетом открытого противоположного плеча double TempOptimalTP, TempOptimalTP_sell, TempOptimalTP_buy, NeedTP_points, lots; int i; double multiplier, profit_money, price_tick; //---- if(mode) { multiplier = MathSqrt(getTopLots(3)); } //---- if(!mode) { multiplier=1; } profit_money = AccountBalance()*ProfitPercent*multiplier / 100; price_tick = MarketInfo(Symbol(), MODE_TICKVALUE); // необходимое количество пунктов (при лоте=1) для достижения профита NeedTP_points = profit_money*Point / price_tick; lots = getSumLots(1) + getSumLots(2); //---- if(getSumLots(2) != 0) { TempOptimalTP_sell = (getSumWeightedPrice(2) - NeedTP_points) / getSumLots(2); } else { TempOptimalTP_sell=0; } // без учета открытого противоположного плеча //---- if(getSumLots(1) != 0) { TempOptimalTP_buy = (getSumWeightedPrice(1) + NeedTP_points) / getSumLots(1); } else { TempOptimalTP_buy = 0; } //без учета открытого противоположного плеча //---- if(!SELL_BUY) { //---- if(getTopLevel(1) == getTopLevel(2)) { TempOptimalTP = TempOptimalTP_buy; } else { //---- if(lots != 0) { TempOptimalTP = (TempOptimalTP_buy*getSumLots(1) + TempOptimalTP_sell*getSumLots(2) + NeedTP_points) / lots; } else { TempOptimalTP = 0; } } //с учетом открытого противоположного плеча return(NormalizeDouble(TempOptimalTP_buy, Digits)); } //---- if(SELL_BUY) { //---- if(getTopLevel(1) == getTopLevel(2)) { TempOptimalTP=TempOptimalTP_sell; } else { //---- if(lots != 0) { TempOptimalTP = (TempOptimalTP_buy*getSumLots(1) + TempOptimalTP_sell*getSumLots(2) - NeedTP_points) / lots; } else { TempOptimalTP = 0; } } // с учетом открытого противоположного плеча return(NormalizeDouble(TempOptimalTP_sell, Digits)); } } //+------------------------------------------------------------------+ //| Функция изменяет текущий тэйкпрофит для всех открытых позиций на| //| цену уровня требуемой доходности | | //+------------------------------------------------------------------+ void setNewTakeProfit() { int t, cnt1, err, start; bool tic; double priceTP_buy, priceTP_sell, priceSL_buy, priceSL_sell, s, spread; t = OrdersTotal(); s = MarketInfo(Symbol(), MODE_SPREAD); spread = s*Point; priceTP_buy = getOptimalTakeProfit(OptimalTakeProfit, false); priceTP_sell = getOptimalTakeProfit(OptimalTakeProfit, true); priceSL_buy = priceTP_sell; priceSL_sell = priceTP_buy; //---- if(getTopLevel(1) > getTopLevel(2)) { //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS); //---- if(OrderType() == OP_BUY && OrderTakeProfit() != priceTP_buy - spread) { start = GetTickCount(); tic = OrderModify(OrderTicket(), OrderOpenPrice(), 0, priceTP_buy - spread, 0, Green); //---- if(ShowLog) { Print("Устанавливаем новый TP OP_BUY -", OrderTakeProfit(), "->", priceTP_buy-spread, " lots= ", OrderLots(), " ticket= ", OrderTicket()); Print("Время модификации ", (GetTickCount() - start) / 1000, " секунд."); } //---- if(tic) PlaySound("alert.wav"); //---- if(!tic) { err = GetLastError(); Print("Ошибка = ", err, " (", ErrorDescription(err), ")"); } Sleep(timeOut); } //---- if(OrderType() == OP_SELL && OrderStopLoss() != priceSL_sell) { start = GetTickCount(); tic = OrderModify(OrderTicket(), OrderOpenPrice(), priceSL_sell, 0, 0, Yellow); //---- if(ShowLog) { Print("Устанавливаем новый SL OP_SELL -", OrderTakeProfit(), "->", priceSL_sell, " lots= ", OrderLots(), " ticket= ", OrderTicket()); Print("Время модификации ", (GetTickCount() - start) / 1000, " секунд."); } //---- if(tic) PlaySound("alert.wav"); //---- if(!tic) { err = GetLastError(); Print("Ошибка = ", err, " (", ErrorDescription(err), ")"); } Sleep(timeOut); } } } //---- if(getTopLevel(1) < getTopLevel(2)) { //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS); //---- if(OrderType() == OP_BUY && OrderStopLoss() != priceSL_buy) { start = GetTickCount(); tic = OrderModify(OrderTicket(), OrderOpenPrice(), priceSL_buy, 0, 0, Green); //---- if(ShowLog) { Print("Устанавливаем новый SL OP_BUY -", OrderTakeProfit(), "->", priceSL_buy, " lots= ", OrderLots(), " ticket= ", OrderTicket()); Print("Время модификации ", (GetTickCount() - start) / 1000, " секунд."); } //---- if(tic) PlaySound("alert.wav"); //---- if(!tic) { err = GetLastError(); Print("Ошибка = ", err, " (", ErrorDescription(err), ")"); } Sleep(timeOut); } //---- if(OrderType() == OP_SELL && OrderTakeProfit() != priceTP_sell + spread) { start = GetTickCount(); tic = OrderModify(OrderTicket(), OrderOpenPrice(), 0, priceTP_sell + spread, 0, Yellow); //---- if(ShowLog) { Print("Устанавливаем новый TP OP_SELL -", OrderTakeProfit(), "->", priceTP_sell + spread, " lots= ", OrderLots(), " ticket= ", OrderTicket()); Print("Время модификации ", (GetTickCount() - start) / 1000, " секунд."); } //---- if(tic) PlaySound("alert.wav"); //---- if(!tic) { err = GetLastError(); Print("Ошибка = ", err, " (", ErrorDescription(err), ")"); } Sleep(timeOut); } } } //---- if(getTopLevel(1) == getTopLevel(2) && !Mode_Close_on_TP) { //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS); //---- if(OrderType() == OP_BUY && OrderTakeProfit() != 0) { start = GetTickCount(); tic = OrderModify(OrderTicket(), OrderOpenPrice(), 0, 0, 0, Green); //---- if(ShowLog) { Print("Устанавливаем новый TP OP_BUY -", OrderTakeProfit(), "->", 0, " lots= ", OrderLots(), " ticket= ", OrderTicket()); Print("Время модификации ", (GetTickCount() - start) / 1000, " секунд."); } //---- if(tic) PlaySound("alert.wav"); //---- if(!tic) { err = GetLastError(); Print("Ошибка = ", err, " (", ErrorDescription(err), ")"); } Sleep(timeOut); } //---- if(OrderType() == OP_SELL && OrderTakeProfit() != 0) { start = GetTickCount(); tic = OrderModify(OrderTicket(), OrderOpenPrice(), 0, 0, 0, Yellow); //---- if(ShowLog) { Print("Устанавливаем новый TP OP_SELL -", OrderTakeProfit(), "->", 0, " lots= ", OrderLots(), " ticket= ", OrderTicket()); Print("Время модификации ", (GetTickCount() - start) / 1000, " секунд."); } //---- if(tic) PlaySound("alert.wav"); //---- if(!tic) { err = GetLastError(); Print("Ошибка = ", err, " (", ErrorDescription(err), ")"); } Sleep(timeOut); } } } //---- if(getTopLevel(1) == getTopLevel(2) && Mode_Close_on_TP) { //---- for(cnt1 = 0; cnt1 < t; cnt1++) { OrderSelect(cnt1, SELECT_BY_POS); //---- if(OrderType()==OP_BUY && OrderTakeProfit()!=priceTP_buy-spread) { start = GetTickCount(); tic = OrderModify(OrderTicket(), OrderOpenPrice(), 0, priceTP_buy - spread, 0, Green); //---- if(ShowLog) { Print("Устанавливаем новый TP OP_BUY -", OrderTakeProfit(), "->", priceTP_buy-spread, " lots= ", OrderLots(), " ticket= ", OrderTicket()); Print("Время модификации ", (GetTickCount() - start) / 1000, " секунд."); } //---- if(tic) PlaySound("alert.wav"); //---- if(!tic) { err = GetLastError(); Print("Ошибка = ", err, " (", ErrorDescription(err), ")"); } Sleep(timeOut); } //---- if(OrderType() == OP_SELL && OrderTakeProfit() != priceTP_sell + spread) { start = GetTickCount(); tic = OrderModify(OrderTicket(), OrderOpenPrice(), 0, priceTP_sell + spread, 0, Yellow); //---- if(ShowLog) { Print("Устанавливаем новый TP OP_SELL -", OrderTakeProfit(), "->", priceTP_sell+spread, " lots= ", OrderLots(), " ticket= ", OrderTicket()); Print("Время модификации ", (GetTickCount() - start) / 1000, " секунд."); } //---- if(tic) PlaySound("alert.wav"); //---- if(!tic) { err = GetLastError(); Print("Ошибка = ", err, " (", ErrorDescription(err), ")"); } Sleep(timeOut); } } } } //+------------------------------------------------------------------+ //| Breakdowning martingail™ v 0.9.4 | //+------------------------------------------------------------------+ int start() { double s, spread, allDeals=0,Risk, level; int total, err, i, start; string level_str; bool ticket; s = MarketInfo(Symbol(), MODE_SPREAD); spread = s*Point; // Включение манименеджмента (вычисление лотов) if(MoneyManagement == true && LogariphmicMM == true) { Risk = MathCeil(Riskfactor*100 / MathSqrt(AccountBalance())); //---- if(Risk >= 20) Risk = 20; startLots = MathCeil(AccountBalance()*Risk / 10000) / 10; //---- if(startLots > MarketInfo(Symbol(), MODE_MAXLOT)) { startLots = MarketInfo(Symbol(), MODE_MAXLOT); } //---- if(startLots < MarketInfo(Symbol(), MODE_MINLOT)) { startLots = MarketInfo(Symbol(), MODE_MINLOT); } } //---- if(MoneyManagement == true && LogariphmicMM == false) { startLots = NormalizeDouble(AccountBalance()*Riskfactor / 100000, 1); //---- if(startLots > MarketInfo(Symbol(), MODE_MAXLOT)) { startLots = MarketInfo(Symbol(), MODE_MAXLOT); } //---- if(startLots < MarketInfo(Symbol(), MODE_MINLOT)) { startLots = MarketInfo(Symbol(), MODE_MINLOT); } } //---- if(MoneyManagement == false && LogariphmicMM == false) { startLots = startLots; } //Распечатка различной информации на экране allDeals = getLevelPositions(2,0); //---- if(getTopLevel(1) > getTopLevel(2)) { level = getOptimalTakeProfit(OptimalTakeProfit, false) - spread; } //---- if(getTopLevel(1) < getTopLevel(2)) { level = getOptimalTakeProfit(OptimalTakeProfit, true) + spread; } //---- if(level != 0) { level_str = DoubleToStr(level, Digits); } else { level_str = " пока нет, ждем..."; } // распечатка уровня закрытия всех ордеров Comment("", "\n", " B R E A K D O W N I N G M A R T I N G A I L ™ v. 0.9.4", " Планируемый уровень закрытия серии : ",level_str,"\n", " Профит по лонгам = ", NormalizeDouble(getAllProfit(2),2)," $", "\n", " Профит по шортам = ", NormalizeDouble(getAllProfit(3),2)," $", "\n", " ---------------------------------------------------", "\n", " Профит сегодня = ", NormalizeDouble(getDayProfit(1, 0),2), " $","\n", " Профит вчера = ", NormalizeDouble(getDayProfit(1, 1),2)," $", "\n", " Профит позавчера = ", NormalizeDouble(getDayProfit(1, 2),2)," $", "\n", " ---------------------------------------------------", "\n", " Balance = ",NormalizeDouble(AccountBalance(),2)," $","\n", " Equity = ",NormalizeDouble(AccountEquity(),2)," $","\n", " Free Margin = ",NormalizeDouble(AccountFreeMargin(),2)," $","\n", " ______________________________", "\n", " Sell Lots = ", getSellLotsSum(1), " | Buy Lots = ", getBuyLotsSum(1), "\n" ); // проверка достаточного количества маржи на счете if(AccountFreeMargin() < (1000) && ShowLog) { Print("Мало денег на счете. Free Margin = ", AccountFreeMargin()); PlaySound("timeout.wav"); return(0); } total = OrdersTotal(); // выставление первого уровня, когда Mode_Close_on_TP=true или ордера первого уровня // стоят слишком далеко друг от друга if(MathAbs(getOrderPriceByNum(getNum(1, 1)) - getOrderPriceByNum(getNum(0, 1))) > (MarketInfo(Symbol(), MODE_SPREAD) + 10)*Point && Mode_Close_on_TP && Close_on_TP) { getProfitOrdersClose(); } //выставление первых ордеров серии, если таких еще нет if(isMgNum(getNum(1, 1)) == False && TradeAllowed) { start = GetTickCount(); ticket = OrderSend(Symbol(), OP_BUY, getLotByLevel(1), NormalizeDouble(Ask, Digits), 3, 0, 0, "первая лонг", getNum(1, 1), 0, Green); //---- if(ShowLog) { Print("Открытие первой позиции серии лонгов ", Symbol(), " ask= ", Ask, " ticket=", ticket); Print("Время открытия ордера ", (GetTickCount() - start) / 1000, " секунд."); } //---- if(ticket) PlaySound("alert.wav"); //---- if(!ticket) { err = GetLastError(); Print("Ошибка = ", err, " (",ErrorDescription(err), ")"); } Sleep(timeOut); } //---- if(isMgNum(getNum(0, 1)) == False && TradeAllowed) { start = GetTickCount(); ticket = OrderSend(Symbol(), OP_SELL, getLotByLevel(1), NormalizeDouble(Bid, Digits), 3, 0, 0, "первая шорт", getNum(0, 1), 0, Green); //---- if(ShowLog) { Print("Открытие первой позиции серии шортов ", Symbol(), " Bid= ", Bid, " ticket=", ticket); Print("Время открытия ордера ", (GetTickCount() - start) / 1000, " секунд."); } //---- if(ticket) PlaySound("alert.wav"); //---- if(!ticket) { err = GetLastError(); Print("Ошибка = ", err, " (", ErrorDescription(err), ")"); } Sleep(timeOut); } //выставляем ордера для лонгов if(getTopLevel(1) < maxLevel) { //---- for(i = 1; i < 9; i++) { //---- if(getTopLevel(1) == i && isMgNum(getNum(1, i + 1)) == False && isOrderActive(getNum(1, i)) == True && setPriceBuyStop() != 0 && getOrderPriceByNum(getMaxLongNum())!=setPriceBuyStop()) { start = GetTickCount(); ticket = OrderSend(Symbol(), OP_BUYSTOP, getLotByLevel(getTopLevel(1) + 1), setPriceBuyStop(), 3, 0, 0, StringConcatenate(i + 1, " лонг"), getNum(1, i + 1), 0, Green); //---- if(ShowLog) { Print("Время открытия ордера ", (GetTickCount() - start) / 1000, " секунд."); } //---- if(ticket) PlaySound("alert.wav"); //---- if(!ticket) { err = GetLastError(); Print("Ошибка = ", err, " (", ErrorDescription(err), ")"); } Sleep(timeOut); return(1); } } } //выставляем ордера для шортов if(getTopLevel(2) < maxLevel) { //---- for(i = 1; i < 9; i++) { //---- if(getTopLevel(2) == i && isMgNum(getNum(0, i + 1)) == False && isOrderActive(getNum(0, i)) == True && setPriceSellStop() != 0 && getOrderPriceByNum(getMaxShortNum()) != setPriceSellStop()) { start = GetTickCount(); ticket = OrderSend(Symbol(), OP_SELLSTOP, getLotByLevel(getTopLevel(2) + 1), setPriceSellStop(), 3, 0, 0, StringConcatenate(i + 1, " шорт"), getNum(0, i + 1), 0, Red); //---- if(ShowLog) { Print("Время открытия ордера ", (GetTickCount() - start) / 1000, " секунд."); } //---- if(ticket) PlaySound("alert.wav"); //---- if(!ticket) { err = GetLastError(); Print("Ошибка = ", err, " (", ErrorDescription(err), ")"); } Sleep(timeOut); return(1); } } } //модификация отложенных ордеров BuyStop и SellStop if(getOrderPriceByNum(getNextOrderNum(getMaxShortNum())) < setPriceSellStop() && setPriceSellStop() != 0) // для шортов { modOrder(getNextOrderNum(getMaxShortNum()), setPriceSellStop(), 0); } //---- if(getOrderPriceByNum(getNextOrderNum(getMaxLongNum())) > setPriceBuyStop() && setPriceBuyStop() != 0) // для лонгов { modOrder(getNextOrderNum(getMaxLongNum()), setPriceBuyStop(), 0); } //---- if(getAllProfit(1) > AccountBalance()*ProfitPercent*MathSqrt(getTopLots(3)) / 100 && !Close_on_TP) { //при достижении необходимого профита закрываем все ордера getProfitOrdersClose(); } //---- if(Close_on_TP) { //проверяем, можно ли изменить уровни тейкпрофита и стоплосса для всех открытых ордеров setNewTakeProfit(); } // Удаление всех лишних ордеров в случае, если серия закрылась профитом, то есть если // нет открытых ордеров первой ступени. Удаление лишних лонгов, если нет ордера первой ступени if(isOrderActive(getNum(1, 1)) == False) { //---- for(i = getNum(1, 2); i < getNum(1, 9); i += 10) { //начинаем перебирать все со второго уровня deleteOrderNum(i); } } //---- if(isOrderActive(getNum(0, 1)) == False) { //для шортов for(i = getNum(0, 2); i < getNum(0, 9); i += 10) { deleteOrderNum(i); } } return(0); } //+------------------------------------------------------------------+ // the end.