Useful features from KimIV - page 91

 

The CrossPointOfSections() function.

This function calculates the coordinates of the intersection point of two segments. Each segment is defined by a pair of its point coordinates. Three arrays are passed to the function as parameters:

  • x - Abscissa array. Must contain four elements: x[0], x[1] - abscissae of the first segment, x[2], x[3] - abscissae of the second segment.
  • y - An array of ordinates. Should contain four elements: y[0], y[1] - ordinates of the first segment, y[0], y[1] - ordinates of the second segment.
  • t - Array of coordinates of the intersection point you are looking for. After the normal execution of the function, this array will contain two elements: t[0] is the abscissa of the crossing point of the two lines and t[1] is the ordinate of the same point.
  • The result is true if the segments intersect, false if they don't. If the segments are congruent, totally or partially, the function will return false.
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    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);
}

The script is for testing.

Files:
 
Thank you.
 

Good afternoon. Question about functions that return a flag to close the last position at a take or stop loss.

'Useful functions from KimIV'.

Function isCloseLastPosByTake().
This function returns the flag to close the last position on the take. Flag is up - True - TakeProfit has triggered. Flag lowered - False - position was closed due to other reason

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

Yesterday I asked this question on general forum. But so far no answer.

My Expert Advisor has a 3-step martingale. Each step (position) has its own magik (1,2,3).

Positions are closed by signals and/or stops.

This type of closing is also implemented:

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

It turns out that my Expert Advisor works fine as long as the last (largest position) of a martigail step is not closed at Take Profit!

Then when the next first position (magic 1) is opened, it is closed immediately, because the isCloseLastPosByTake() function flag stays set to one (1) !

And so to infinity. Opens and closes.

Moreover! The terminal remembers this flag and even new removal/installation of the EA does not help (until you change magiks).

I need some way to reset isCloseLastPosByTake() function after all positions are closed.

I've already twisted my brain inside out. It won't work!

Igor !, Or whoever (who can), please tell me how to do it and if you can do it at all ?




 

The answer to my question seems to have been found. If you're interested, it's right here.

'A question for connoisseurs'.

 
KimIV >> :

Examples of how to use the ModifyOrder() function.

I decided to give the very first examples that I've been asked many times before. This is opening of positions in terms of market order execution Market Watch. It is when we cannot simultaneously give an order to open a position at the market price and attach a pending order to it. Such an opening at Market Watch should be performed in two stages: first, we open a position, and then we attach a pending order to it, i.e. we set StopLoss and TakeProfit price levels.

1. Buy 0.1 lot of the current symbol and set a stop of 30 points

2. Sell 0.15 lot of current symbol and set SL=45, TP=99

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

A working script with examples is included in the trailer.





Good morning to Igor and all of you! I have applied these functions in my EA. Everything is modifying normally.

As long as I didn't put in my EA a magik !

All positions modify normally. However -

I do not understand why but OpenPosition() function does not see the magician and keeps opening positions one by one on every bar. I have already removed all unnecessary things (I thought it was my error in the code).

And put the number of positions in the comment. It is useless. When there are obvious positions - comment prints zero:


I can't figure out why the function can't see the magician! Here's the code:
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)//флаг сущ.

Attached is the source file of this code. Can you please tell me where I made a mistake and why EA does not see magik?

Files:
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);
 
Are you aware that in your version it only checks for sell orders?
I found it, you only send four parameters to the position opening function, while you need 6.
 

Yes, thank you all(tmp.0 & Roger)! Fixed it and everything is working as it should.

My inattention is to blame. Not the OpenPosition() function at all.

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);
 

Player, a hint!

When using OrderCloseBuy - OrderCloseSell, the built-in MKueL language and compiler requires two function parameters(order tickets - buy and sell). We have one ticket for an open order, but how can we set the second one? Or maybe I did not understand something - the language self-study has not written anything about this function and has no example.

Thank you in advance!

 

And here's another question for Igor.

Have you created a separate custom (or other) function to flip the buy-sell position and vice versa, without the usual OrderClose-OrderSend?