- NormalizeDouble() braucht niemand! Double-Zahlen sind eh 'ganz lang' - siehe die immer wiederkehrenden Fragen zur Gleichheit zwei 'Doubletten'. Nimm in Print() stattdessen DoubleToString() oder mit #define:
#define d2s(q) DoubleToString(q,_Digits)
Dann werden die Zeilen nicht so lang! - Versuch doch einmal die erst ArraySetAsSeries(..) und dann die Wertezuweisung über CopyBuffer(..) zu machen - allerdings habe ich damit (noch) keine Erfahrung!
kannst Du mir den Punkt 2 nochmal genauer erklären, den versteh ich nicht ganz,
ArraySetAsSeries(...) gehört in die OnInit(). Es braucht nur einmal ausgeführt werden.
Im Debugger siehst du Symbole hinter der Definition, die Auskunft über die Art der Indizierung liefern. I-Indikatorbuffer S-Series.
Handles von iCustom gehören überprüft!
if(TMAHandleweek==INVALID_HANDLE) { Alert("*ERROR* creating .... handle"); return(INIT_FAILED); }
Das Ergebnis von CopyBuffer gehört überprüft!
#define TO_COPY 5 if(CopyBuffer(TMAHandleweek,0,0,TO_COPY,TMAweek )!=TO_COPY) return; // auf den nächsten tick warten if(CopyBuffer(TMAHandleweek,2,0,TO_COPY,TMAweekUp)!=TO_COPY) return; // falls die Indikatoren noch nicht bereit sind if(CopyBuffer(TMAHandleweek,3,0,TO_COPY,TMAweekLo)!=TO_COPY) return; // ist ja alles Ereignisgesteuert
PS: CopyBuffer arbeitet immer richtig siehe F1. Der Zeitpunkt von ArraySetAsSeries() ist erst beim Zugriff auf das Array relevant.
Stell den Kursor im Editor auf CopyBuffer und drück F1 und dann orientiere Dich an dem Beispiel - da gibt es keine humoristischen Übersetzungen ;)
Dort steht CopyBuffer in OnCalculate(..){..} dem Indik.-Pendant zu OnTick() - also ja!
der CopyBuffer muss aber in der OnTick stehen @Otto, sehe ich das so richtig?
amando
Hallo Zusammen,
ich bin auch recht neu was das Coden von EAs und Indikatoren angeht. Mein Problem zu diesem Thema:
Wenn ich in meinem EA anstatt OnTick() nun OnNewBar() (siehe code) verwende, scheint das CopyBuffer() nicht mehr innerhalb von OnNewBar() verwendbar zu sein, solange sich das iCustom() handle innerhalb OnInit() befindet. Fehlermeldung ist dann immer, dass das handle ein undeclared identifier ist.
#include <Lib_CisNewBar.mqh> CisNewBar current_chart; // instance of the CisNewBar class: current chart //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- int period_seconds=PeriodSeconds(_Period); // Number of seconds in current chart period datetime new_time=TimeCurrent()/period_seconds*period_seconds; // Time of bar opening on current chart if(current_chart.isNewBar(new_time)) OnNewBar(); // When new bar appears - launch the NewBar event handler }
Hat jemand eine Idee, wie ich diese Problematik umgehen kann? Auf einem Chart und im Strategy Tester wird mir mein Indikator graphisch und von den Werten her sauber angezeigt (z.B. im Data Window). Ich weiß nur nicht wie ich die Werte in meinen EA bekomme, sodass ich darauf basierend entry und exit rules definieren kann. Ich habe bisher keinen Forumseintrag oder Artikel gesehen in dem dies thematisiert wird.
Ich wäre für jede Hilfe dankbar.
Hallo Zusammen,
ich bin auch recht neu was das Coden von EAs und Indikatoren angeht. Mein Problem zu diesem Thema:
Wenn ich in meinem EA anstatt OnTick() nun OnNewBar() (siehe code) verwende, scheint das CopyBuffer() nicht mehr innerhalb von OnNewBar() verwendbar zu sein, solange sich das iCustom() handle innerhalb OnInit() befindet. Fehlermeldung ist dann immer, dass das handle ein undeclared identifier ist.
Hat jemand eine Idee, wie ich diese Problematik umgehen kann? Auf einem Chart und im Strategy Tester wird mir mein Indikator graphisch und von den Werten her sauber angezeigt (z.B. im Data Window). Ich weiß nur nicht wie ich die Werte in meinen EA bekomme, sodass ich darauf basierend entry und exit rules definieren kann. Ich habe bisher keinen Forumseintrag oder Artikel gesehen in dem dies thematisiert wird.
Ich wäre für jede Hilfe dankbar.
Ich bin mir nicht sicher, ob ich dir helfen kann. Kenne die CisNewbar Library nicht. Kopier vielleicht mal den ganzen Code hierhin. VIelleicht liegt es ja an einem anderen Teil
Liebe Grüße
Ich war im Urlaub und hatte leider keine Möglichkeit hier bisher den Code zu posten.
Hier ist der Code des EAs:
#include <Trade\PositionInfo.mqh> #include <Trade\Trade.mqh> #include <Trade\SymbolInfo.mqh> #include <Trade\AccountInfo.mqh> #include <OnNewBar.mqh> #include <Lib_CisNewBar.mqh> CPositionInfo m_position; // trade position object CTrade m_trade; // trading object CSymbolInfo m_symbol; // symbol info object CAccountInfo m_account; // account info wrapper ulong m_magic = 16384; double ExtTakeProfit = 0.0; double ExtTrailingStop = 0.0; double ExtStopLoss = 0.0; //+------------------------------------------------------------------+ //| Expert external inputs | //+------------------------------------------------------------------+ input double InpTakeProfit = 1000; // TakeProfit input double InpTrailingStop = 1000; // TrailingStop input double InpStopLoss = 1000; // StopLoss input double Lots = 0.1; // Lot input int SMA1 = 20; // SMA1 input int SMA2 = 50; // SMA2 input int MA1_StDev=5; input int MA2_StDev=10; input int MA3_StDev=20; input int MA4_StDev=50; input int MA5_StDev=100; input int StDevMA1=5; input int StDevMA2=100; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //SetMarginMode(); //if(!IsHedging()) // { // Print("Hedging only!"); // return(INIT_FAILED); // } //--- m_symbol.Name(Symbol()); // sets symbol name if(!RefreshRates()) { Print("Error RefreshRates. Bid=",DoubleToString(m_symbol.Bid(),Digits()), ", Ask=",DoubleToString(m_symbol.Ask(),Digits())); return(INIT_FAILED); } //--- m_trade.SetExpertMagicNumber(m_magic); // sets magic number //--- tuning for 3 or 5 digits int digits_adjust=1; if(m_symbol.Digits()==3 || m_symbol.Digits()==5) digits_adjust=10; ExtTakeProfit = InpTakeProfit * digits_adjust; ExtTrailingStop = InpTrailingStop * digits_adjust; ExtStopLoss = InpStopLoss * digits_adjust; //--- create handle of the several indicators int handle_MA1 = iMA(_Symbol,_Period,SMA1,0,MODE_SMA,PRICE_CLOSE); int handle_MA2 = iMA(_Symbol,_Period,SMA2,0,MODE_SMA,PRICE_CLOSE); int StDev_line = iCustom(_Symbol, _Period, "MA StDev2.ex5", MA1_StDev, MA2_StDev, MA3_StDev, MA4_StDev, MA5_StDev, StDevMA1, StDevMA2); double StDev_line_Array[], StDev_line_Array2[], StDev_line_Array3[]; ArraySetAsSeries(StDev_line_Array,true); ArraySetAsSeries(StDev_line_Array2,true); ArraySetAsSeries(StDev_line_Array3,true); CopyBuffer(StDev_line,0,0,5,StDev_line_Array); CopyBuffer(StDev_line,1,0,5,StDev_line_Array2); CopyBuffer(StDev_line,2,0,5,StDev_line_Array3); Comment ("StDev_line_Array[0]: ",StDev_line_Array[0],"StDev_line_Array[1]: ",StDev_line_Array[1]," StDev_line_Array2[0]: ",StDev_line_Array2[0]," StDev_line_Array2[1]: ",StDev_line_Array2[1], " StDev_line_Array3[0]: ",StDev_line_Array3[0], " StDev_line_Array3[1]: ",StDev_line_Array3[1]); if(StDev_line==INVALID_HANDLE) { Alert("*ERROR* creating .... handle"); return(INIT_FAILED); } //--- if the handle is not created if(handle_MA1==INVALID_HANDLE)//RSI_line==INVALID_HANDLE)//handle_green==INVALID_HANDLE || handle_red==INVALID_HANDLE || handle_yellow==INVALID_HANDLE)// || handle_1MA2==INVALID_HANDLE || handle_MA2_high==INVALID_HANDLE || handle_MA2_low==INVALID_HANDLE) // || handle_15MA1==INVALID_HANDLE || handle_15MA2==INVALID_HANDLE|| handle_RSI_fast==INVALID_HANDLE || handle_RSI_slow==INVALID_HANDLE { //--- tell about the failure and output the error code PrintFormat("Failed to create handle of the iADX indicator for the symbol %s/%s, error code %d", Symbol(), EnumToString(Period()), GetLastError()); //--- the indicator is stopped early return(INIT_FAILED); } if(Bars(Symbol(),Period())<100) { Print("bars less than 100"); return(INIT_FAILED); } if(ExtTakeProfit<10) { Print("ExtTakeProfit less than 10"); return(INIT_FAILED); // check ExtTakeProfit } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnNewBar() { PrintFormat("New bar: %s",TimeToString(TimeCurrent(),TIME_SECONDS)); //-----Create array for several MACDs----- double MA1_Array[], MA2_Array[], MA1_StDev_Array[], MA2_StDev_Array[], MA3_StDev_Array[], MA4_StDev_Array[], MA5_StDev_Array[];//, StDev_line_Array[], StDev_line_Array2[], StDev_line_Array3[]; //--- create handle of the indicator MA int handle_MA1 = iMA(_Symbol,_Period,SMA1,0,MODE_SMA,PRICE_CLOSE); int handle_MA2 = iMA(_Symbol,_Period,SMA2,0,MODE_SMA,PRICE_CLOSE); //-----Sort price arrays from the current candle downwards----- ArraySetAsSeries(MA1_Array,true); ArraySetAsSeries(MA2_Array,true); ArraySetAsSeries(MA1_StDev_Array,true); ArraySetAsSeries(MA2_StDev_Array,true); ArraySetAsSeries(MA3_StDev_Array,true); ArraySetAsSeries(MA4_StDev_Array,true); ArraySetAsSeries(MA5_StDev_Array,true); //-----Copy Buffer----- CopyBuffer(handle_MA1,0,1,5,MA1_Array); CopyBuffer(handle_MA2,0,1,5,MA2_Array); int total=0; for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open positions if(m_position.SelectByIndex(i)) if(m_position.Symbol()==Symbol() && m_position.Magic()==m_magic) total++; if(total==0) { //--- no opened positions identified if(m_account.FreeMargin()<(1000*Lots)) { Print("We have no money. Free Margin = ",m_account.FreeMargin()); return; } //-----BUY SIGNAL----- if( (StDev_line_Array[0]>StDev_line_Array2[0] && StDev_line_Array[1]<StDev_line_Array2[1] ) { if(!RefreshRates()) return; if(m_trade.Buy(Lots,m_symbol.Name(),m_symbol.Ask(),m_symbol.Ask()-ExtStopLoss*Point(), m_symbol.Ask()+ExtTakeProfit*Point(),"OPEN LONG")) { Print("BUY order opened : ",m_trade.ResultPrice()); } else { Print("Error opening BUY. Result Retcode: ",m_trade.ResultRetcode(), ", description of result: ",m_trade.ResultRetcodeDescription(), ", ticket of deal: ",m_trade.ResultDeal()); return; } } //-----SELL SIGNAL----- if( (StDev_line_Array[0]<StDev_line_Array2[0] && StDev_line_Array[1]>StDev_line_Array2[1] ) { if(!RefreshRates()) return; if(m_trade.Sell(Lots,m_symbol.Name(),m_symbol.Bid(),m_symbol.Bid()+ExtStopLoss*Point(), m_symbol.Bid()-ExtTakeProfit*Point(),"OPEN SHORT")) { Print("SELL order opened : ",m_trade.ResultPrice()); } else Print("Error opening Sell. Result Retcode: ",m_trade.ResultRetcode(), ", description of result: ",m_trade.ResultRetcodeDescription(), ", ticket of deal: ",m_trade.ResultDeal()); return; } return; } for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open positions if(m_position.SelectByIndex(i)) if(m_position.Symbol()==Symbol() && m_position.Magic()==m_magic) { if(m_position.PositionType()==POSITION_TYPE_BUY) // long position is opened { if( (StDev_line_Array[0]<StDev_line_Array2[0] && StDev_line_Array[1]>StDev_line_Array2[1] { m_trade.PositionClose(m_position.Ticket()); // close position return; // exit } if(ExtTrailingStop>0) { if(!RefreshRates()) return; if(m_symbol.Bid()-m_position.PriceOpen()>Point()*ExtTrailingStop) // Warum Multiplikation? { if(m_position.StopLoss()<m_symbol.Bid()-Point()*ExtTrailingStop) { m_trade.PositionModify(m_position.Ticket(),m_symbol.Bid()-Point()*ExtTrailingStop, m_position.TakeProfit()); return; } } } } else { if( (StDev_line_Array[0]>StDev_line_Array2[0] && StDev_line_Array[1]<StDev_line_Array2[1] { m_trade.PositionClose(m_position.Ticket()); // close position return; // exit } if(ExtTrailingStop>0) { if(!RefreshRates()) return; if((m_position.PriceOpen()-m_symbol.Ask())>(Point()*ExtTrailingStop)) { if((m_position.StopLoss()>(m_symbol.Ask()+Point()*ExtTrailingStop)) || (m_position.StopLoss()==0)) { m_trade.PositionModify(m_position.Ticket(),m_symbol.Ask()+Point()*ExtTrailingStop, m_position.TakeProfit()); return; } } } } } return; } //+------------------------------------------------------------------+ //| Refreshes the symbol quotes data | //+------------------------------------------------------------------+ bool RefreshRates() { //--- refresh rates if(!m_symbol.RefreshRates()) return(false); //--- protection against the return value of "zero" if(m_symbol.Ask()==0 || m_symbol.Bid()==0) return(false); //--- return(true); }
Un hier ist der Code des custom indicator:
#include <MovingAverages.mqh> #property indicator_separate_window #property indicator_buffers 10 #property indicator_plots 3 //--- plot StDev_of_MAs #property indicator_label1 "StDev_of_MAs" #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 #property indicator_label2 "MA1 StDev_of_MAs" #property indicator_type2 DRAW_LINE #property indicator_color2 clrBlue #property indicator_style2 STYLE_SOLID #property indicator_width2 1 #property indicator_label3 "MA2 StDev_of_MAs" #property indicator_type3 DRAW_LINE #property indicator_color3 clrBlack #property indicator_style3 STYLE_SOLID #property indicator_width3 1 //--- input parameters input int MA1=5; input int MA2=10; input int MA3=20; input int MA4=50; input int MA5=100; input int MAStDev1=5; input int MAStDev2=100; //--- indicator buffers double StDev_of_MAsBuffer[]; double MA1Buffer[]; double MA2Buffer[]; double MA3Buffer[]; double MA4Buffer[]; double MA5Buffer[]; double PriceBuffer[]; double AverageBuffer[]; double AverageStDev1[]; double AverageStDev2[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,StDev_of_MAsBuffer,INDICATOR_DATA); SetIndexBuffer(1,AverageStDev1,INDICATOR_DATA); SetIndexBuffer(2,AverageStDev2,INDICATOR_DATA); SetIndexBuffer(3,MA1Buffer,INDICATOR_CALCULATIONS); SetIndexBuffer(4,MA2Buffer,INDICATOR_CALCULATIONS); SetIndexBuffer(5,MA3Buffer,INDICATOR_CALCULATIONS); SetIndexBuffer(6,MA4Buffer,INDICATOR_CALCULATIONS); SetIndexBuffer(7,MA5Buffer,INDICATOR_CALCULATIONS); SetIndexBuffer(8,PriceBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(9,AverageBuffer,INDICATOR_CALCULATIONS); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ /*int OnCalculate(const int rates_total, // size of the price[] array const int prev_calculated, // number of available bars at the previous call const int begin, // from what index in price[] authentic data start const double& price[]) // array, on which the indicator will be calculated */ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- Create price buffer for(int i=1;i<rates_total;i++) { /*PriceBuffer[i]=price[i];*/ PriceBuffer[i]=close[i]; } //--- Calculate MA buffers SimpleMAOnBuffer(rates_total, prev_calculated, 1, // index, starting from which data for smoothing are available MA1, // period of the exponential average PriceBuffer, // buffer to calculate average MA1Buffer); // into this buffer locate value of the average SimpleMAOnBuffer(rates_total, prev_calculated, 1, MA2, PriceBuffer, MA2Buffer); SimpleMAOnBuffer(rates_total, prev_calculated, 1, MA3, PriceBuffer, MA3Buffer); SimpleMAOnBuffer(rates_total, prev_calculated, 1, MA4, PriceBuffer, MA4Buffer); SimpleMAOnBuffer(rates_total, prev_calculated, 1, MA5, PriceBuffer, MA5Buffer); //--- Calculation of the indicator for(int i=MA5+MAStDev2-1;i<rates_total;i++) { AverageBuffer[i]=((MA1Buffer[i]+MA2Buffer[i]+MA3Buffer[i]+MA4Buffer[i]+MA5Buffer[i])/5); StDev_of_MAsBuffer[i]=100*MathPow((MathPow(MA1Buffer[i]+AverageBuffer[i],2)+MathPow(MA2Buffer[i]+AverageBuffer[i],2)+MathPow(MA3Buffer[i]+AverageBuffer[i],2)+MathPow(MA4Buffer[i]+AverageBuffer[i],2)+MathPow(MA5Buffer[i]+AverageBuffer[i],2))/5,0.5); } SimpleMAOnBuffer(rates_total, prev_calculated, 1, // index, starting from which data for smoothing are available MAStDev1, // period of the exponential average StDev_of_MAsBuffer, // buffer to calculate average AverageStDev1); // into this buffer locate value of the average SimpleMAOnBuffer(rates_total, prev_calculated, 1, // index, starting from which data for smoothing are available MAStDev2, // period of the exponential average StDev_of_MAsBuffer, // buffer to calculate average AverageStDev2); // into this buffer locate value of the average //--- //--- return value of prev_calculated for next call return(rates_total); } void OnDeinit(const int reason) { //--- Das Chart nach der Löschung des Indikators leeren Comment(""); }
Ich würde gerne nochmals darauf hinweisen, dass ich ein absolut blutiger Anfänger bin und ich mir das alles selber beigebracht habe. Den Code habe ich mir im Prinzip immer stückchenweise von anderen öffentlichen Programmen "geklaut" und eben so modifiziert, dass es meine Trading Idee wiedergibt. Dementsprechend bitte gnädig sein bei der Begutachtung des Codes ;-) Nichtsdestotrotz bin ich für jedes Feedback mehr als dankbar!
Mein Hauptproblem ist also, dass ich schlichtweg die Werte aus meinem Custom Indikator innerhalb meines EA's verwenden möchte, um Buy/Sell Signale zu erzeugen, dies aber derzeit nicht schaffe. Vielen Dank bereits im Voraus, für jeden Versuch mir zu helfen!
Hast Du schon mal den Debugger versucht?
Dafür sollte aber besser der Indikator nicht wo anders im Terminal laufen!
Setze mit DebugBreak() die Punkte, an denen
Du Dir die verschiedenen Werte anschauen willst!
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Hallo,
ich versteh die Funktion ja nicht, einmal geht sie, dann wieder nicht. Die initialisierung eines Indikators funktioniert nur zeitweise bei mir
ich verwende folgenden code im globalen
in der onInit
und dann in der onTick
wenn ich dann versuche
bekomme ich lauter 0 Werte,
ich hab auch schon die Buffer und die Array in die OnInit kopiert und da war keine Auswirkung.
Hab auch schon das Handle in die OnTick, genausowenig auswirkung.
interessanterweise, es funktioniert immer tageweise, dann wieder ein paar tage nicht
ist das bei euch auch so?
amando