KimIV'ten faydalı özellikler - sayfa 110

 
Açıklama için teşekkürler, şimdi devam edeceğim)))))
 

WritingLineInFile() işlevi.

Geçen gün bu işlevi biraz değiştirdim, dosyanın geri kalan satırlarından, örneğin tablo başlığından farklı olan ilk satırını yazma yeteneğinden sorumlu olan fs parametresini ekledim. İlk satır, yalnızca iki koşulun aynı anda karşılanması durumunda dosyaya yazılacaktır: satırın uzunluğu sıfırdan büyük ve dosya boyutu sıfır. Ve önceki sürümle uyumluluğu korumak için yeni parametre isteğe bağlı hale getirildi.

WritingLineInFile() işlevinin parametreleri:

  • fn - dosya adı
  • st - dosyaya yazılan dize
  • fs - ilk satır (tablo başlığı)

 //+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,   http://www.kimiv.ru                    |
//+----------------------------------------------------------------------------+
//|  Версия   : 28.04.2012                                                     |
//+----------------------------------------------------------------------------+
//|  Описание : Запись строки в файл                                           |
//|  Параметры:                                                                |
//|    fn - имя файла                                                          |
//|    st - строка                                                             |
//|    fs - первая строка (шапка таблицы)                                      |
//+----------------------------------------------------------------------------+
void WritingLineInFile( string fn, string st, string fs= "" ) {
   int fh= FileOpen (fn, FILE_READ | FILE_WRITE , " " );

   if (fh> 0 ) {
     if ( FileSize (fh)== 0 && StringLen (fs)> 0 ) FileWrite (fh, fs);
     FileSeek (fh, 0 , SEEK_END );
     FileWrite (fh, st);
     FileClose (fh);
  }
}

not. Ekli, işlevi test etmek için bir komut dosyasıdır.

Dosyalar:
 
İyi akşamlar, Igor! Bir işleve karar verildi
 DateBeginQuarter

Her şeyden önce satırları anlamaya çalışıyorum:

 int ye = Year () - MathFloor ( nq / 4 ) ;
   nq = MathMod ( nq , 4 ) ;

varsayılan olarak nq = 0, bu yüzden MathMod (nq/4) ifadesinden ne elde ettiğimiz net değil, çünkü sonuç her zaman 0 olacaktır. İkinci satır da net değil, çünkü 0/4'te kalan yok, lütfen açıklayın.

 

Sorunuz için teşekkür ederim Natasha. Sayenizde işlevi tekrar kontrol ettim ve bir hata buldum. Çizgide

 int ye= Year ()- MathFloor (nq/ 4 );

eksi işaretini artı ile değiştirmeniz gerekir

 int ye= Year ()+ MathFloor (nq/ 4 );

Ve şimdi sorunuzun noktasına. nq her zaman sıfıra eşit değildir. Negatif olanlar da dahil olmak üzere herhangi bir tamsayı değeri olabilir. Belirttiğiniz satırlar, nq'nin 4'ün katı olduğu, yani 4 çeyrek (yıllık) eklemeniz veya çıkarmanız gerektiğinde çalışır.

 
KimIV :

Sorunuz için teşekkür ederim Natasha. Sayenizde işlevi tekrar kontrol ettim ve bir hata buldum. Çizgide

eksi işaretini artı ile değiştirmeniz gerekir

Ve şimdi sorunuzun noktasına. nq her zaman sıfıra eşit değildir. Negatif olanlar da dahil olmak üzere herhangi bir tamsayı değeri olabilir. Belirttiğiniz satırlar, nq'nin 4'ün katı olduğu, yani 4 çeyrek (yıllık) eklemeniz veya çıkarmanız gerektiğinde çalışır.

Cevabınız için teşekkürler, Igor .... İşlevi normalden daha uzun buldum, ancak yine de anladım))))))) aynı işlevde, bana göre yılı azaltmanın gerekli olmadığı anlaşılıyor. ifade:

  if ( mo < 1 ) {
     mo += 12 ;
     ye --;

o zaman her şey yoluna girecek.

 
Lisi4ka330 :

...aynı işlevde, bana öyle geliyor ki, ifadede yılı azaltmaya gerek yok...

Haklısın Natasha, neden olmasın? Tam tersine aylık çemberin kapanmasından sonraki yılı tam tersi yönde azaltmak bana mantıklı geliyor. Belirttiğiniz ifadede yılı küçültmek, dakika tam bir daire geri sarıldıktan sonra akrebi bir saat geriye almakla aynı şeydir. İşlevin kendi versiyonunu getir, tartışalım ... belki senin versiyonun benimkinden daha başarılı olur.
 

GetDrawdownOpenPosInPoint() işlevi

Görünüşe göre bu işlevin kapsamlı testini bitirdim. Gerektiğinde yayılmayı hesaba kattım, optimize etmeye çalıştım... Fonksiyon, mevcut açık pozisyonların maksimum düşüşünü puan olarak döndürür. Geleneksel olarak, fonksiyona parametreler iletebilir ve böylece analiz için ihtiyaç duyduğunuz pozisyonları filtreleyebilirsiniz:

  • sy - Araç adı. Bu parametreyi ayarlarsanız, fonksiyon sadece belirtilen enstrümanın pozisyonlarını kontrol edecektir. NULL , geçerli araç anlamına gelir ve "" (varsayılan) herhangi bir araç anlamına gelir.
  • op - Ticaret işlemi, pozisyon türü. Geçerli değerler: OP_BUY , OP_SELL veya -1 . Varsayılan değer -1 , herhangi bir konum anlamına gelir.
  • mn - Konum Kimliği (MagicNumber). Varsayılan değer -1 - herhangi bir büyü.
  • tf - Çubukların Yüksek ve Düşük değerlerine bakılacağı zaman çizelgesi. Varsayılan değer 0 - mevcut zaman dilimi.
 //+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,   http://www.kimiv.ru                    |
//+----------------------------------------------------------------------------+
//|  Версия   : 01.05.2012                                                     |
//|  Описание : Возвращает максимальную просадку в пунктах текущих открытых    |
//|             позиций.                                                       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любая позиция)                  |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//|    tf - таймфрейм                  ( 0   - текущий таймфрейм)              |
//+----------------------------------------------------------------------------+
int GetDrawdownOpenPosInPoint( string sy= "" , int op=- 1 , int mn=- 1 , int tf= 0 ) {
   if (sy== "0" ) sy= Symbol ();
   if (tf== 0 ) tf= Period ();

   datetime to=TimeOpenFirstPos(sy, op, mn); // Время открытия первой позиции
   datetime tb=GetTimeOpenBar(sy, tf, to);
   int       dd, md= 0 ;                         // Просадка
   double    po, sp;                           // Пункт, спрэд
   int       i, k= OrdersTotal ();               // Номера позиций
   int       nb;                               // Номер бара

   if (tb> 0 ) {
     while (tb< TimeCurrent ()) {
      dd= 0 ;
       for (i= 0 ; i<k; i++) {
         if ( OrderSelect (i, SELECT_BY_POS, MODE_TRADES)) {
           if (( OrderSymbol ()==sy || sy== "" ) && (mn< 0 || OrderMagicNumber ()==mn)) {
             if ((op< 0 || OrderType ()==op) && ( OrderType ()==OP_BUY || OrderType ()==OP_SELL)) {
               if (tb> OrderOpenTime ()) {
                nb= iBarShift ( OrderSymbol (), tf, tb, True);
                 if (nb>= 0 ) {
                  po= MarketInfo ( OrderSymbol (), MODE_POINT);
                   if (po== 0 ) Message( "В обзоре рынка отсутствует символ " + OrderSymbol ()+ ". Точность расчётов не гарантируется!" );
                   else {
                     if ( OrderType ()==OP_BUY) {
                      dd+=( OrderOpenPrice ()- iLow ( OrderSymbol (), tf, nb)+po)/po;
                    }
                     if ( OrderType ()==OP_SELL) {
                      sp=po* MarketInfo ( OrderSymbol (), MODE_SPREAD);
                      dd+=( iHigh ( OrderSymbol (), tf, nb)- OrderOpenPrice ()+sp)/po;
                    }
                  }
                }
              }
            }
          }
        }
      }
       if (md<dd) md=dd;
      tb+= 60 *tf;
    }
  }
   return (md);
}

not. GetDrawdownOpenPosInPoint() işlevini test etmek için bir komut dosyası ektedir.

 
KimIV :
Haklısın Natasha, neden olmasın? Tam tersine aylık çemberin kapanmasından sonraki yılı tam tersi yönde azaltmak bana mantıklı geliyor. Belirttiğiniz ifadede yılı küçültmek, dakikayı tam bir daire olarak geri sardıktan sonra akrebi bir saat geriye almakla aynı şeydir. İşlevin kendi versiyonunu getir, tartışalım ... belki senin versiyonun benimkinden daha başarılı olur.

Şöyle akıl yürüttüm: diyelim ki 7. çeyreğin başlangıcını geçmişte ve gelecekte belirlememiz gerekiyor, sonra sırasıyla nq= -7 ve nq=7. Mathfloor geçmiş için -2 ve gelecek için +1 döndürür (fonksiyonun dokümantasyondaki açıklamasına göre), bu nedenle geçmişteki durum için gelecekte eklediğimizden bir yıl daha çıkaracağız .... .Geçmiş için daha fazla hesaplamaya devam edersek, o zaman yılı tekrar küçültmek zorunda kalacağız ve kendimizi 2009'da bulacağız .....

Ne yazık ki vakit darlığından (site sayfasını okuyacak vaktim çok az) şu an doğru kodu veremiyorum kanımca ama gerekirse düzeltmenin de zor olmayacağını düşünüyorum.

 
Lisi4ka330 :

Şöyle akıl yürüttüm: diyelim ki 7. çeyreğin başlangıcını geçmişte ve gelecekte belirlememiz gerekiyor, sonra sırasıyla nq= -7 ve nq=7. Mathfloor geçmiş için -2 ve gelecek için +1 döndürür (fonksiyonun dokümantasyondaki açıklamasına göre), bu nedenle geçmişteki durum için gelecekte eklediğimizden bir yıl daha çıkaracağız .... .Geçmiş için daha fazla hesaplamaya devam edersek, yılı tekrar küçültmek zorunda kalacağız ve kendimizi 2009'da bulacağız...

Mantığınıza katılıyorum, ancak işlemlerde yer alan veri türlerini unutuyorsunuz. MathFloor() işlevi tamamen atlanabilir. Ekteki betiğin çıktısına bakın.

Dosyalar:
test.mq4  1 kb
 
İyi günler, Igor)))) Dürüst olmak gerekirse, cevabınızı tam olarak anlamadım ve ekli komut dosyası bile netleşmedi, tam tersi ...)))) ama sanırım zamanla anlayacağım )))) Lütfen neden dönüş satırında ( StrToTime ( ye + " . " + mo + " .01 " )) artılar olduğunu söyleyin.