wskaźnik średniej wartości różnicy

O jezykach programowania w platformach i nie tylko.
Awatar użytkownika
personov
Pasjonat
Pasjonat
Posty: 1525
Rejestracja: 09 sie 2009, 21:27

wskaźnik średniej wartości różnicy

Nieprzeczytany post autor: personov »

Próbuje zrobić wskaźnik, którego linia będzie wartością średniej arytmetycznej różnic sześciu ostatnich MA.
To znaczy :
różnica to wartość bezwzględna MA1 i MA2.
Wskaźnik ma być średnią wartością sześciu ostatnich takich różnic.
Nic nie jest wyświetlane.
Co robię nie tak ?

Kod: Zaznacz cały

#property indicator_separate_window
#property indicator_buffers 1 
#property indicator_color1 Navy
double MA1[];
double MA2[];
double osc[];
double as[];   
///////////////////////////////////////////////////////////////////////////////////////////////////
void init()
{
SetIndexBuffer(0,as);
SetIndexStyle (0,DRAW_LINE);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void deinit()
{}
///////////////////////////////////////////////////////////////////////////////////////////////////
void start()
{  
   
   for(int i=1000;i>=0;i--){
   MA1[i] = iMA(Symbol(),Period(),4,0,0,0,i);
   MA2[i] = iMA(Symbol(),Period(),9,0,0,0,i);
   osc[i]=MathAbs(MA1[i]-MA2[i]);
   as[i]=(osc[i]+osc[i+1]+osc[i+2]+osc[i+3]+osc[i+4]+osc[i+5])/6;
   }
}

 
Solą życia jest kasa.

dulf
Pasjonat
Pasjonat
Posty: 399
Rejestracja: 24 kwie 2010, 15:13

Nieprzeczytany post autor: dulf »

Kod: Zaznacz cały

#property indicator_separate_window 
 #property indicator_buffers 1 
 #property indicator_color1 Navy 
 double MA1[]; 
 double MA2[]; 
 double osc[]; 
 double as[];    
 /////////////////////////////////////////////////////////////////////////////////////////////////// 
 void init() 
 { 
 IndicatorBuffers(4);
 
 SetIndexBuffer(0,as); 
 SetIndexStyle (0,DRAW_LINE);
 
 SetIndexBuffer(1,osc); 
 SetIndexStyle (1,DRAW_NONE); 
 
 SetIndexBuffer(2,MA1); 
 SetIndexStyle (2,DRAW_NONE); 
 
 SetIndexBuffer(3,MA2); 
 SetIndexStyle (3,DRAW_NONE);  
 
 } 
 /////////////////////////////////////////////////////////////////////////////////////////////////// 
 void deinit() 
 {} 
 /////////////////////////////////////////////////////////////////////////////////////////////////// 
 void start() 
 {  
    int i ; 
    for(i=1000;i>=0;i--){ 
    MA1[i] = iMA(Symbol(),Period(),4,0,0,0,i); 
    MA2[i] = iMA(Symbol(),Period(),9,0,0,0,i); 
    osc[i]=MathAbs(MA1[i]-MA2[i]); 
    as[i]=(osc[i]+osc[i+1]+osc[i+2]+osc[i+3]+osc[i+4]+osc[i+5])/6; 
    } 
    

 }
Nie przydzieliłeś pamięci dla :

Kod: Zaznacz cały

 double MA1[]; 
 double MA2[]; 
 double osc[]; 
Mozna to zrobić przez :

Kod: Zaznacz cały

 SetIndexBuffer(indeks,nazwa_tablicy);

Albo przez
int ArrayResize( void array[], int new_size);

Stosujesz mało wydajną metodę operacji na danych , jeśli wartości buforów nie muszą być wyliczane za każdym tickiem ,należy ustalić ilość iteracji pętli
np :

Kod: Zaznacz cały

 
int Max_bar = 1000 ;
int      i, cbars = IndicatorCounted();

//----
   if(cbars > 0) cbars--;
//----
   //...
   i = Bars - cbars-1 ;
   if(i > Max_bar) i = Max_bar ;
   for( ; i >= 0 ; i--)
     {

    }
///-----
W ten sposób przekraczasz rozmiar tablicy i operujesz na danych które mają losową wartość :

Kod: Zaznacz cały

 for(i=1000;i>=0;i--){ 

    // maksymalny dostępny index dla tablicy nie może być większy od 1000 
    // bo do tego zakresu masz wyliczone poprzednie dane 
   as[i]=(osc[i]+osc[i+1]+osc[i+2]+osc[i+3]+osc[i+4]+osc[i+5])/6; 
  
  // !!!!!!!!!!!!!!(osc[1000]+osc[1000+1]+osc[1000+2]+osc[1000+3] .. itd; !!!!!!!!!!!!
Nie będzie widać tego na wykresie ,ale to błąd .
Jeśli zastosujesz optymalizację pętli , to ten kod będzie działać źle .
Raczej powinno to wyglądac :

Kod: Zaznacz cały

  void start() 
  {  
int Max_bar = 1000 ;  

 int      i,j, cbars = IndicatorCounted(); 

 //---- 
    if(cbars > 0) cbars--; 
 //---- 
    //... 
    i = Bars - cbars-1 ; 
    
    if(i > Max_bar) i = Max_bar ;
    
    j = i ;
    
    i+= 5 ; // Dodatkowe indeksy
    
   Comment(i); 
         
     for(;i>=0;i--){ 
     MA1[i] = iMA(Symbol(),Period(),4,0,0,0,i); 
     MA2[i] = iMA(Symbol(),Period(),9,0,0,0,i); 
     osc[i]=MathAbs(MA1[i]-MA2[i]);
           
     } 
     
     
     for(;j>=0;j--){
     
          as[j]=(osc[j]+osc[j+1]+osc[j+2]+osc[j+3]+osc[j+4]+osc[j+5])/6;
     }
  }
Przykładowo , przy takim rozwiązaniu po każdym ticku jest przeliczane tylko 6 ostatnich elementów ,a nie jak w przypadku pierwszym 1000 (!).
Nie spiesz się , zawsze zdążysz stracić .

Awatar użytkownika
personov
Pasjonat
Pasjonat
Posty: 1525
Rejestracja: 09 sie 2009, 21:27

Nieprzeczytany post autor: personov »

Dzięki dulf za cenną poradę i rozwiązanie problemu. Przy okazji zapytam :
czy istnieje jakieś skrócenie zapisu

Kod: Zaznacz cały

osc[j]+osc[j+1]+osc[j+2]+osc[j+3]+osc[j+4]+osc[j+5]
Jeśli byloby to mnożenie to mozna pokombinować coś z :

Kod: Zaznacz cały

(wartość1*MathPow(wartość2,3))
A czy istnieje coś takiego do sumowania ?
Jeśli przypadkiem chciałbym określić np. średnią z 67 ostatich wartości wskaźnika.
Solą życia jest kasa.

dulf
Pasjonat
Pasjonat
Posty: 399
Rejestracja: 24 kwie 2010, 15:13

Nieprzeczytany post autor: dulf »

A dodatkowa pętla ?

Kod: Zaznacz cały

   double tmp ;   
   int len = 6 ;
     
   for(;j>=0;j--)
   {
     
       tmp = 0.0 ;
       
         for(int k = 0 ; k < len ;k++)
         {
            tmp += osc[j+k];
         }      
             
          as[j]=tmp/len;
    }
Albo wrzucić w oddzielną fun:

Kod: Zaznacz cały

   for(;j>=0;j--)
   {
         
             
          as[j]= Sum(osc,j,6);
    }  
//-------------------------------------------------
double Sum(double t[],int start,int len)
{
       double tmp = 0 ;
       for(int i = 0 ; i < len ;i++)
       {
             
           tmp += t[start+i];
       }
       
           return(tmp/len);
}
Nie spiesz się , zawsze zdążysz stracić .

Awatar użytkownika
Pierz Andrzej
Przyjaciel Forum
Przyjaciel Forum
Posty: 1200
Rejestracja: 02 lip 2006, 14:17

Nieprzeczytany post autor: Pierz Andrzej »

macie panowie do dyspozycji tez funkcje wbudowana
iMaOnArray()

pozdrawiam
Andrzej Pierz
z poważaniem
Andrzej Pierz
FOREX-SERVICE

ODPOWIEDZ