Funciones útiles de KimIV - página 91

 

La función CrossPointOfSections().

Esta función calcula las coordenadas del punto de intersección de dos segmentos. Cada segmento está definido por un par de sus coordenadas puntuales. Se pasan tres matrices a la función como parámetros:

  • x - Matriz de abscisas. Debe contener cuatro elementos: x[0], x[1] - abscisas del primer segmento, x[2], x[3] - abscisas del segundo segmento.
  • y - Una matriz de ordenadas. Debe contener cuatro elementos: y[0], y[1] - ordenadas del primer segmento, y[0], y[1] - ordenadas del segundo segmento.
  • t - Matriz de coordenadas del punto de intersección que se busca. Tras la ejecución normal de la función, este array contendrá dos elementos: t[0] es la abscisa del punto de cruce de las dos líneas y t[1] es la ordenada del mismo punto.
  • El resultado es verdadero si los segmentos se cruzan, falso si no lo hacen. Si los segmentos son congruentes, total o parcialmente, la función devolverá falso.
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    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);
}

El script es para probarlo.

Archivos adjuntos:
 
Gracias.
 

Buenas tardes. Pregunta sobre las funciones que devuelven una bandera para cerrar la última posición en una toma o stop loss.

'Funciones útiles de KimIV'.

Función isCloseLastPosByTake().
Esta función devuelve la bandera para cerrar la última posición de la toma. La bandera está levantada - Verdadero - El TakeProfit se ha activado. Bandera bajada - Falso - la posición se cerró debido a otra razón

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

Ayer hice esta pregunta en el foro general. Pero hasta ahora no hay respuesta.

Mi Asesor Experto tiene una martingala de 3 pasos. Cada paso (posición) tiene su propio magik (1,2,3).

Las posiciones se cierran mediante señales y/o stops.

Este tipo de cierre también se aplica:

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

¡Resulta que mi Asesor Experto funciona bien hasta que la última posición (la más grande) de un marginal se cierra en el Take Profit!

¡Entonces, cuando se abre la siguiente primera posición (mágica 1), se cierra inmediatamente, porque la bandera de la función isCloseLastPosByTake() se queda en uno (1) !

Y así hasta el infinito. Se abre y se cierra.

Además. El terminal recuerda esta bandera e incluso una nueva eliminación/instalación del EA no ayuda (hasta que se cambie de magiks).

Necesito alguna forma de restablecer la función isCloseLastPosByTake() después de que se hayan cerrado todas las posiciones.

Ya me he retorcido el cerebro al revés. No funcionará.

Igor !, O quien sea (que pueda), por favor dígame como hacerlo y si puede hacerlo del todo ?




 

Parece que se ha encontrado la respuesta a mi pregunta. Si te interesa, está aquí.

Una pregunta para los entendidos".

 
KimIV >> :

Ejemplos de cómo utilizar la función ModifyOrder().

Decidí dar los primeros ejemplos que me han preguntado muchas veces. Se trata de la apertura de posiciones en términos de ejecución de órdenes de mercado Market Watch. Es cuando no podemos dar simultáneamente una orden de apertura de posición a precio de mercado y adjuntarle una orden pendiente. Dicha apertura en Market Watch debe realizarse en dos etapas: primero, abrimos una posición, y luego le adjuntamos una orden pendiente, es decir, establecemos los niveles de precio StopLoss y TakeProfit.

1. Compre 0,1 lotes del símbolo actual y fije un stop de 30 puntos

2. Vender 0.15 lotes del símbolo actual y establecer 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);

En el tráiler se incluye un guión de trabajo con ejemplos.





¡Buenos días a Igor y a todos vosotros! He aplicado estas funciones en mi EA. Todo se está modificando bien.

¡Mientras no ponga en mi EA un magik !

Todas las posiciones se modifican normalmente. Sin embargo...

No entiendo por qué pero la función OpenPosition() no ve al mago y sigue abriendo posiciones una a una en cada barra. Ya he eliminado todo lo innecesario (pensé que era un error mío en el código).

Y pon el número de puestos en el comentario. Es inútil. Cuando hay posiciones obvias - el comentario imprime cero:


¡No puedo entender por qué la función no puede ver al mago! Aquí está el código:
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)//флаг сущ.

Se adjunta el archivo fuente de este código. ¿Puedes decirme dónde me he equivocado y por qué EA no ve el magik?

Archivos adjuntos:
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);
 
¿Sabe que en su versión sólo comprueba las órdenes de venta?
Lo he encontrado, sólo envías cuatro parámetros a la función de apertura de posición, mientras que necesitas 6.
 

Sí, ¡gracias a todos(tmp.0 y Roger)! Lo he arreglado y todo funciona como debería.

La culpa la tiene mi falta de atención. No la función OpenPosition() en absoluto.

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

Jugador, ¡una pista!

Cuando se utiliza OrderCloseBuy - OrderCloseSell, el lenguaje MKueL incorporado y el compilador requieren dos parámetros de función(entradas de orden - compra y venta). Tenemos un billete para un pedido abierto, pero ¿cómo podemos fijar el segundo? O tal vez no entendí algo - el auto-estudio del lenguaje no ha escrito nada sobre esta función y no tiene ningún ejemplo.

Gracias de antemano.

 

Y aquí hay otra pregunta para Igor.

¿Ha creado una función personalizada separada (u otra) para invertir la posición de compra-venta y viceversa, sin el habitual OrderClose-OrderSend?