KimIV'ten faydalı özellikler - sayfa 91

 

CrossPointOfSections() işlevi.

Bu fonksiyon, iki doğru parçasının kesişme noktasının koordinatlarını hesaplar. Her segment, noktalarının bir çift koordinatıyla tanımlanır. İşleve parametre olarak üç dizi iletilir:

  • x - Bir dizi apsis. Dört öğe içermelidir: x[0] , x[1] - ilk bölümün apsisi, x[2] , x[3] - ikinci bölümün apsisi.
  • y - Bir dizi koordinat. Dört öğe içermelidir: y[0] , y[1] - ilk bölümün koordinatları, y[0] , y[1] - ikinci bölümün koordinatları.
  • t - İstenen kesişme noktası için bir dizi koordinat. İşlevin normal yürütülmesinden sonra, bu dizi iki öğe içerecektir: t[0] - iki çizginin istenen kesişme noktasının apsisi ve t[1] - aynı noktanın ordinatı.
  • segmentler kesişiyorsa sonuç doğru , aksi takdirde yanlıştır . Segmentler tamamen veya kısmen eşleşirse, işlev false değerini döndürür.
 //+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    x - массив абсцисс              x[0], x[1] - первый отрезок             |
//|                                    x[2], x[3] - второй отрезок             |
//|    y - массив ординат              y[0], y[1] - первый отрезок             |
//|                                    y[0], y[1] - второй отрезок             |
//|    t - массив искомых координат    t[0]       - абсцисса точки пересечения |
//|                                    t[1]       - ордината точки пересечения |
//|    результат                       true если отрезки пересекаются          |
//|                                    false если нет                          |
//|    примечание                      если отрезки не пересекаются, то в мас- |
//|                                    сив t[] передается точка пересечения    |
//|                                    прямых, на которых лежат отрезки        |
//+----------------------------------------------------------------------------+

bool CrossPointOfSections ( double & x [ ] , double & y [ ] , double & t [ ] ) 
{
   double z = ( y [ 3 ] - y [ 2 ] ) * ( x [ 1 ] - x [ 0 ] ) - ( y [ 1 ] - y [ 0 ] ) * ( x [ 3 ] - x [ 2 ] ) ;
   ArrayResize ( t , 2 ) ;
   ArrayInitialize ( t , 0.0 ) ;

   if ( z = = 0 ) 
   {
       Print ( "CrossPointOfSections(): Не удалось найти точку пересечения!" ) ;
       return ( false ) ;
   }

   double xy1 = x [ 1 ] * y [ 0 ] - x [ 0 ] * y [ 1 ] ;
   double xy2 = x [ 3 ] * y [ 2 ] - x [ 2 ] * y [ 3 ] ;
   t [ 0 ] = NormalizeDouble ( ( xy1 * ( x [ 3 ] - x [ 2 ] ) - xy2 * ( x [ 1 ] - x [ 0 ] ) ) / z , 0 ) ;
   t [ 1 ] = ( xy1 * ( y [ 3 ] - y [ 2 ] ) - xy2 * ( y [ 1 ] - y [ 0 ] ) ) / z ;
   
   if ( ( t [ 0 ] - x [ 0 ] ) * ( t [ 0 ] - x [ 1 ] ) > 0 | | ( t [ 1 ] - y [ 0 ] ) * ( t [ 1 ] - y [ 1 ] ) > 0 ) return ( false ) ;
   if ( ( t [ 0 ] - x [ 2 ] ) * ( t [ 0 ] - x [ 3 ] ) > 0 | | ( t [ 1 ] - y [ 2 ] ) * ( t [ 1 ] - y [ 3 ] ) > 0 ) return ( false ) ;

   return ( true ) ;
}

Test için komut dosyası.

Dosyalar:
 
Teşekkür ederim.
 

Tünaydın. Kaybı al veya durdur ile son pozisyonu kapatmak için bayrağı döndüren işlevler hakkında soru.

'KimIV'ten Faydalı Özellikler'

isCloseLastPosByTake() işlevi.
Bu fonksiyon, son pozisyonu alma ile kapatmak için bayrağı döndürür. Bayrak kaldırıldı - Doğru - TakeProfit çalıştı. İşaret atlandı - Yanlış - pozisyon başka bir nedenle kapatıldı

//------------------------------------------------ ---------------

Zaten dün genel forumda bir soru gündeme getirdi. Ama cevap henüz bulunamadı.

MY EA'nın 3 adımlı martingali vardır. Her adımın (pozisyonun) bir büyüsü vardır (1,2,3).

Pozisyonlar sinyaller ve/veya stoplarla kapatılır.

Aşağıdaki kapatma da sağlanır:

 if ( isCloseLastPosByStop ( NULL , OP_BUY , Magic_3 ) ) //если посл. позиция 
//закрылась по тейкпрофиту, - то закрываем все позиции
 ClosePosFirstProfit ( NULL , OP_BUY , - 1 ) ;   

Görünüşe göre danışmanım dövüşün son (en büyük pozisyon) aşaması kar al ile kapanana kadar iyi çalışıyor !

Bundan sonra, bir sonraki ilk pozisyon (Magic-1) açıldığında hemen kapanır, çünkü isCloseLastPosByTake() İşlevinin işlev bayrağı bir (1)'e eşit kaldı!

Ve böylece sonsuza kadar. Açılır ve kapanır.

Üstelik! Terminal bu bayrağı hatırlar ve danışmanın yeni kaldırılması / kurulması bile yardımcı olmaz (siz sihri değiştirene kadar).

Tüm pozisyonları kapattıktan sonra isCloseLastPosByTake() fonksiyonunu bir şekilde resetlemek gerekiyor.

Beynimi çoktan tersine çevirdim. İşe yaramıyor!

Igor! veya herhangi biri (kim yapabilir), pl. bana nasıl yapacağımı söyle ve bunu yapmak mümkün mü?

 

Soruma bir cevap varmış gibi görünüyor. Merak edenler için burada

'Uzmanlara soru'

 
KimIV >> :

ModifyOrder() işlevini kullanma örnekleri.

İlk önce, bana defalarca sorulan örnekler vermeye karar verdim. Bu, Piyasa İzleme ticaret emirlerinin piyasa yürütme koşullarında pozisyonların açılmasıdır. Bu, aynı anda piyasa fiyatından bir pozisyon açmak için emir vermek ve ona bekleyen bir emir eklemek imkansız olduğunda. Piyasa İzleme koşullarında böyle bir açılış iki aşamada gerçekleştirilmelidir: önce bir pozisyon açın ve ardından ona bekleyen emirleri ekleyin, yani StopLoss ve TakeProfit fiyat seviyelerini ayarlayın.

1. Mevcut enstrümandan 0.1 lot satın alın ve 30 puanlık bir stop loss ayarlayın

2. Mevcut enstrümanın 0.15 lotunu sat ve SL=45, TP=99 olarak ayarla

 int ti = OpenPosition ( NULL , OP_SELL , 0.15 ) ;
if ( OrderSelect ( ti , SELECT_BY_TICKET ) )
  ModifyOrder ( - 1 , Bid + 45 * Point , Bid - 99 * Point , clModifySell ) ;

Fragmanda, örneklerle çalışan bir komut dosyası.





Günaydın Igor ve orada bulunan herkes! Bu işlevleri Uzman Danışmanımda uyguladım. Her şey iyi değişir.

EA'ma sihir ekleyene kadar!

Tüm pozisyonlar normal olarak değiştirilir. Yine de -

Nedeni belli değil, ancak OpenPosition() işlevi - sanki sihirbazı görmüyor ve her çubukta birbiri ardına durmadan pozisyonlar açmaya devam ediyor. Gereksiz her şeyi zaten kaldırdım (kodda benim hatam olduğunu düşündüm).

Ve yoruma pozisyon sayısını ekledim. Faydasız. Konumların bariz varlığıyla, yorum sıfır gösterir:


İşlevin neden sihri görmediğini anlayamıyorum! İşte kod:
 extern int        Magic           = 7771 ;
extern int        StopLoss        = 200 ;
extern int        TakeProfit_Sell = 200 ;
extern double     Lots_1          = 0.01 ; //размер лота
//--------------------------------------------------------------------+
extern string _P_Performance = "- Параметры открытия  позиций " ;
extern bool       UseSound      = True ;        //Использовать звуковой сигнал
extern string     NameFileSound = "expert.wav" ; //Наименование зву. файла откр.
color  clOpenBuy     = Blue ;      // Цвет значка открытия покупки
color  clOpenSell    = Red ;       // Цвет значка открытия продажи
color  clModifyBuy   = Aqua ;      // Цвет значка модификации покупки
color  clModifySell  = Tomato ;    // Цвет значка модификации продажи
 int    Slippage      = 10 ;       // Проскальзывание цены
 int    NumberOfTry   = 10 ;       // Количество попыток
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
//-- Подключаемые модули --

#include <stderror.mqh>
#include <stdlib.mqh>
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
bool   gbDisabled    = False ;    // Флаг блокировки советника
double SL , TP ;
int ti ;
static int prevtime = 0 ; 

//------------------------------------------------------------
int start ( ) {
Comment ( "Количество откр. позиций = " , NumberOfPositions ( NULL , OP_SELL , Magic ) ) ;
if ( Time [ 0 ] = = prevtime )   return ( 0 ) ; //ждём появления нового бара
   prevtime = Time [ 0 ] ; //если появился новый бар , включаемся

//XXXXXXXXXXXXXXXXXXX ОТКРЫТИЕ ПОЗИЦИЙ ХХХХХХХХХХХХХХ

if ( NumberOfPositions ( NULL , OP_SELL , Magic ) < 1 ) { //если нет открытых селл-
// позиций
SL = 0 ; TP = 0 ; // задаем стопы
if ( StopLoss > 0 )   SL = Bid + Point * StopLoss ;
if ( TakeProfit_Sell > 0 ) TP = Bid - Point * TakeProfit_Sell ; 
//Открываем позицию селл  
 ti = OpenPosition ( NULL , OP_SELL , Lots_1 , Magic ) ;
if ( OrderSelect ( ti , SELECT_BY_TICKET ) )
  ModifyOrder ( - 1 , SL , TP , clModifySell ) ;
 } 
 return ( 0 ) ;
 //-----------------Конец функции int start()-------------------------
}
// Пользовательские функции жжжжжжжжжжжжжжжжжжжжжжжжж
//Здесь только названия. Полный код ф-й - ниже в аттаче
void Message ( string m ) //вывод сообщ в коммент и принт
int NumberOfPositions ( string sy = "" , int op = - 1 , int mn = - 1 ) //кол-во позиций
string GetNameOP ( int op ) //торг. операция
int OpenPosition ( string sy , int op , double ll , double sl = 0 , double tp = 0 , int mn = 0 )
void ModifyOrder ( double pp = - 1 , double sl = 0 , double tp = 0 , color cl = CLR_NONE )
string GetNameTF ( int TimeFrame = 0 ) //таймфрейм
bool ExistPositions ( string sy = "" , int op = - 1 , int mn = - 1 , datetime ot = 0 ) //флаг сущ.

Bu kodun kaynak dosyası ektedir. Lütfen. nerede hata yaptığımı söyle ve danışman neden sihri göremiyor?

Dosyalar:
exp.sell.rar  4 kb
 
if(StopLoss>0)   SL=Bid+Point*StopLoss;
if(TakeProfit_Sell>0) TP=Bid-Point*TakeProfit_Sell; 
//Открываем позицию селл  
 //ti=OpenPosition(NULL, OP_SELL, Lots_1,Magic);  Ваш маджик шел в качестве стоп-лосса
 ti=OpenPosition(NULL, OP_SELL, Lots_1,SL,TP,Magic);
 
Versiyonunuzda sadece satış emirlerini kontrol ettiğinin farkında mısınız?
Konum açma işlevine yalnızca dört parametre gönderdiğinizi buldum, ancak 6'ya ihtiyacınız var.
 

Evet, hepinize teşekkürler ( tmp.0 ve Roger )! Düzelttim ve her şey olması gerektiği gibi çalıştı.

Benim dikkatsizliğim suçlu. Ve hiç bir işlev değil - OpenPosition ()

SL = 0 ; TP = 0 ;
if ( StopLoss > 0 )   SL = Bid + Point * StopLoss ;
if ( TakeProfit > 0 ) TP = Bid - Point * TakeProfit ;   
ti = OpenPosition ( NULL , OP_SELL , Lots , 0 , 0 , Magic ) ;
if ( OrderSelect ( ti , SELECT_BY_TICKET ) )
  ModifyOrder ( - 1 , SL , TP , clModifySell ) ;
 

Oyun, söyle bana!

OrderCloseBuy - OrderCloseSell'i kullanırken, yerleşik MCule dili ve derleyici iki işlev parametresi gerektirir ( bilet sipariş et - satın al ve sat). Bir açık sipariş bileti var, ancak ikincisi nasıl ayarlanır? Ya da bir şey anlamadım - dil eğitiminde bu işlev hakkında hiçbir şey yazılmamış ve hiçbir örnek yok.

Şimdiden teşekkürler!

 

Ve işte Igor için başka bir soru.

Alış-satış pozisyonunu tersine çevirmek için ayrı bir özel (veya başka) bir işlev yarattınız mı ve bunun tersi de normal OrderClose - OrderSend olmadan mı?