//+------------------------------------------------------------------+ //| 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); } // the end.