//+------------------------------------------------------------------+ //| Starter.mq4 | //| Copyright © 2005, MetaQuotes Software Corp. | //| http://www.metaquotes.net | //+------------------------------------------------------------------+ #property copyright "Copyright © 2005, MetaQuotes Software Corp." #property link "http://www.metaquotes.net" //#include extern double Lots = 0.1; extern double MaximumRisk = 0.03; extern double DecreaseFactor = 3; extern int Stop = 10; extern int SL = 0; //Для "эстетов" из форуму StopLoss //extern double Lots = 4; //Параметры Laguerre extern double GammaP = 0.7; // Некая "Гамма" из параметров "Laguerre" extern double StopL = 0.1; // "Порог" "Laguerre" для закрытия позиции extern int ShftL = 0; // Бар, на котором рассчитывается "Laguerre" //Параметры CCI extern int CCIperiod = 14; // Собственно период CCI extern int TypeCCI = 0; // "Ценовые константы" для расчтеиа CCI // 0-Close, 1-Open, 2-High, 3-Low, 4-Median, // 5-Typical, 6-WEIGHTED extern int DAlpha = 0; // Дельта CCI - "порог изменения скорости CCI" // в процентах extern int CCILevel = 100; // Классически - уровень, который должна // пересечь CCI, чтобы дать сигнал. // Классика +/-100, 0, в оригинальном // starter'е +/-5. Я закомментировал, т.к..... extern int ShftA1 = 0; // Бар для расчета "текущей" CCI extern int ShftA2 = 1; // Бар для расчета "предыдущей" CCI //Параметры MA extern double MAPeriod = 120; // Собственно период MA extern int TypeMA = 0; // "Ценовые константы" для расчтеиа MA // 0-Close, 1-Open, 2-High, 3-Low, 4-Median, // 5-Typical, 6-WEIGHTED extern int ShftMA = 0; // Бар для расчета "текущей" MA (Бар для // "предыдущей" MA = ShftMA+1 (в отличии от CCI)) extern double DeltaMA = 0.1; // Дельта MA ("текущего" и "предыдущего" бара) в "пипсах" //MagicNubber extern int MagicNumber = 20051016; // Я всегда выношу, чтобы можно было, // НАПРИМЕР, торговать на одной паре // с разными параметрами int handle; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- handle = FileOpen("StarterDebug.csv", FILE_CSV | FILE_WRITE); FileWrite(handle, "Time[0]", "TradeType", "Laguerre", "MA", "MA1", "DMA", "Alpha1", "Alpha2", "DAlpha"); //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- FileClose(handle); //---- return(0); } //+------------------------------------------------------------------+ //| Calculate optimal lot size | //+------------------------------------------------------------------+ double LotsOptimized() { double lot = Lots; int orders = HistoryTotal(); // history orders total int losses = 0; // number of losses orders without a break //---- select lot size lot = NormalizeDouble(AccountFreeMargin()*MaximumRisk / 500, 1); //---- calcuulate number of losses orders without a break if(DecreaseFactor > 0) { for(int i = orders - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) == false) { Print("Error in history!"); break; } //---- if(OrderSymbol() != Symbol() || OrderType() > OP_SELL) continue; //---- if(OrderProfit() > 0) break; //---- if(OrderProfit() < 0) losses++; } //---- if(losses > 1) lot = NormalizeDouble(lot - lot*losses / DecreaseFactor, 1); } //---- return lot size if(lot < 1) lot = 1; //---- if(lot > 1000) lot = 1000; return(lot); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double LaGuerre(double gamma, int shift) { double RSI; double L0[100]; double L1[100]; double L2[100]; double L3[100]; double CU, CD; //---- for(int i = shift + 99; i >= shift; i--) { L0[i] = (1.0 - gamma)*Close[i] + gamma*L0[i+1]; L1[i] = -gamma*L0[i] + L0[i+1] + gamma*L1[i+1]; L2[i] = -gamma*L1[i] + L1[i+1] + gamma*L2[i+1]; L3[i] = -gamma*L2[i] + L2[i+1] + gamma*L3[i+1]; CU = 0; CD = 0; if(L0[i] >= L1[i]) CU = L0[i] - L1[i]; else CD = L1[i] - L0[i]; //---- if(L1[i] >= L2[i]) CU = CU + L1[i] - L2[i]; else CD = CD + L2[i] - L1[i]; //---- if(L2[i] >= L3[i]) CU = CU + L2[i] - L3[i]; else CD = CD + L3[i] - L2[i]; //---- if(CU + CD != 0) RSI = CU / (CU + CD); } return(RSI); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { double Laguerre; double SLstop; double Alpha1, Alpha2; double MA, MA1; //+-- double Juice; int cnt, ticket, RealTotal, total; // Laguerre=iCustom(NULL, 0, "Laguerre", 0, 0); Laguerre = LaGuerre(GammaP, 0); Alpha1 = iCCI(NULL, 0, CCIperiod, TypeCCI, ShftA1); Alpha2 = iCCI(NULL, 0, CCIperiod, TypeCCI, ShftA2); MA = iMA(NULL, 0, MAPeriod, 0, MODE_EMA, TypeMA, ShftMA); MA1 = iMA(NULL, 0, MAPeriod, 0, MODE_EMA, TypeMA, ShftMA + 1); //+-- Juice=iCustom(NULL,0,"Juice",0,0); total = OrdersTotal(); // Ищем реальное чило торговых ордеров для нашего MagicNumber на нашей паре, // чтобы дать торговать себе и другим советникам for(cnt = 0; cnt < total; cnt++) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol()) RealTotal = RealTotal + 1; } if(RealTotal < 1) { // no opened orders identified if(AccountFreeMargin() < (1000*Lots)) { Print("We have no money. Free Margin = ", AccountFreeMargin()); return(0); } // check for long position (BUY) possibility if(//Из "оригинала" (Laguerre==0) && //Не просто рост MA, но и минимум некоторую дельту (MA - MA1 > DeltaMA * Point) && //Рост CCI (Alpha2 < Alpha1) && //Пересечение некоторого уровня +/-100, 0 "Снизу-вверх" (Alpha1 > -1 * CCILevel && Alpha2 < -1 * CCILevel) && // && //В оригинале (если честно - не понял. ИМХО имелось ввиду пересечение // или "подход" к) 0, но, если смотреть отладочный файл, то там .... // (Alpha1 < -5) //Рост CCI в % больше порога (MathAbs(Alpha1 - Alpha2) / MathMax(MathAbs(Alpha1), MathAbs(Alpha2))*100 > DAlpha) ) //+-- && Juice>JuiceLevel) { FileWrite(handle, "Buy", Time[0], Laguerre, MA, MA1, MA-MA1, Alpha1, Alpha2, MathAbs(Alpha1 - Alpha2) / MathMax(MathAbs(Alpha1), MathAbs(Alpha2))*100 ); FileFlush(handle); //Для "эстетов" StopLoss if(SL == 0) SLstop = 0; else SLstop = Ask - SL * Point; ticket = OrderSend(Symbol(), OP_BUY, LotsOptimized(), Ask, 3, SLstop, 0, "starter", MagicNumber, 0, Green); } // check for short position (SELL) possibility if(//Из "оригинала" (Laguerre==1) && //Не просто падение MA, но и минимум некоторую дельту (MA - MA1 < -1 * DeltaMA * Point) && //Падение CCI (Alpha2 > Alpha1) && //Пересечение некоторого уровня +/-100, 0 "Сверху-вниз" (Alpha1 < CCILevel && Alpha2 > CCILevel) // && //В оригинале (если честно - не понял. ИМХО имелось ввиду пересечение (или "подход" к) 0, но, если смотреть отладочный файл, то там .... // (Alpha1 > 5) && //Рост CCI в % больше порога (MathAbs(Alpha1 - Alpha2)/MathMax(MathAbs(Alpha1),MathAbs(Alpha2))*100 > DAlpha) ) //+-- && Juice>JuiceLevel) { FileWrite(handle, "Sell", Time[0], Laguerre, MA, MA1, MA-MA1, Alpha1, Alpha2, MathAbs(Alpha1 - Alpha2)/MathMax(MathAbs(Alpha1),MathAbs(Alpha2))*100 ); FileFlush(handle); //Для "эстетов" StopLoss if (SL == 0) SLstop = 0; else SLstop = Bid + SL * Point; ticket=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,SLstop,0,"starter",MagicNumber,0,Red); } } // it is important to enter the market correctly, // but it is more important to exit it correctly... for(cnt=0;cnt1-StopL) { OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close position return(0); // exit } // check for stop if(Stop>0) { if(Bid-OrderOpenPrice()>Point*Stop) { OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close position return(0); } } } else // go to short position { // should it be closed? if(Laguerre0) { if(OrderOpenPrice()-Ask>Point*Stop) { OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close position return(0); } } } } } return(0); } //+------------------------------------------------------------------+