No estoy seguro del subforo en el que debería abrir este hilo de consulta, de modo que pido disculpas por adelantado si no es este. Ruego ayuda de algún programado presente aquí que fuera tan amable de crear un fragmento que necsito añadir a un proyecto que tengo en marcha. Se trata de lo siguiente.
Dispongo de los siguientes parámetros de entrada para el usuario: a) distancia de SL y TP para todas las operaciones en pips, y b) cantidad de dinero (sea cual sea la divisa que sea la cuenta) que quiero conseguir si se alcanza dicho TP. Por ejemplo, se selecciona una distancia de 20 pips de SL, 40 pips de TP y se quiere conseguir 50 euros de beneficio con ello.
Pues bien, qué fórmula debería usar para que:
1. El bot calcule los lotes necesarios para conseguir esa cantidad de dinero especificada para dicha distancia de TP.
2. El cálculo anterior sea automático para toda divisa y todo par/cruce.
Esto escapa a mis capacidades y cualquier ayuda será con creces agradecida.
Duda Programación Robot
Duda Programación Robot
Enseño a crear bots de forex sin necesidad de aprender lenguaje mql4/5.
¿Interesado? Visita my web https://www.theandorraninvestor.eu/es
Re: Duda Programación Robot
Entiendo que es para Metatrader 4, lo muevo aquí.
Saludos,
X-Trader
Saludos,
X-Trader
"Los sistemas de trading pueden funcionar en ciertas condiciones de mercado todo el tiempo, en todas las condiciones de mercado en algún momento del tiempo, pero nunca en todas las condiciones de mercado todo el tiempo."
Re: Duda Programación Robot
Si es así, es 50, que son los euros que querés ganar, dividido 40 de TP... si lo querés más ajustado súmale al TP el Spread que perdió, la comisión y el Swap aprox pasados a pips, y el resultado te da el lotaje que debería usar para ganar 50 euros por operación.
Re: Duda Programación Robot
El siguiente paso es más fácil todavía, haces una variable externa para poner la divisa de la próxima operación.
Re: Duda Programación Robot
Gracias por tu respuesta. No, lo que necesito es que me calcule los valores de lotes en función de la distancia variable de TP. Ya sé que en EURUSD puedo dividir dinero entre pips para conseguir lotes, pero no sé cómo trasladar eso a índices o cruces, por ejemplo. Además, la distancia de TP puede ser diferente de una operación a la siguiente.
Enseño a crear bots de forex sin necesidad de aprender lenguaje mql4/5.
¿Interesado? Visita my web https://www.theandorraninvestor.eu/es
Re: Duda Programación Robot
Hola landorra, bueno en ese caso lo único que cambia son los dígitos... en el EURUSD tenés 5 y en el SP500 2. Sí querés hacemos un zoom el lunes a las 9hs (-3GMT) y lo resolvemos.landorra escribió: ↑29 Ago 2021 13:45 Gracias por tu respuesta. No, lo que necesito es que me calcule los valores de lotes en función de la distancia variable de TP. Ya sé que en EURUSD puedo dividir dinero entre pips para conseguir lotes, pero no sé cómo trasladar eso a índices o cruces, por ejemplo. Además, la distancia de TP puede ser diferente de una operación a la siguiente.
Sino, tenés que usar en tus cálculos NormaliceDouble(variable,_Digits); Saludos.
Re: Duda Programación Robot
Lamento el retraso en la respuesta. Gracias por tu información. De todas formas, me temo que no funciona como explicas. Te pongo un ejemplo. Quiero probar la fórmula en el índice del NASDAQ. En mi broker ese instrumento tiene dos decimales. Quiero que la fórmula me calcules los lotes para conseguir 500 € con un recorrido de 40 pips (no 40 puntos). Si divido 500 € entre 40 pips, el resultado es de ¡¡12.5 lotes estándar!! :O.
Como puedes ver, no es correcto. Está claro que para el instrumento del EURUSD pueda ser correcto, pero no para el resto de instrumentos.
Como puedes ver, no es correcto. Está claro que para el instrumento del EURUSD pueda ser correcto, pero no para el resto de instrumentos.
Enseño a crear bots de forex sin necesidad de aprender lenguaje mql4/5.
¿Interesado? Visita my web https://www.theandorraninvestor.eu/es
Re: Duda Programación Robot
ValorDelTick = MarketInfo (Symbol(), Mode_TickValue);
Teniendo el valor del tick y el valor en euros a arriesgar y la distancia, puedes deducir el numero de lotes.
Lotes = NormalizeDouble(Valor a arriesgar en euros/Distancia Stop/ ValorDelTick,numDecimales);
A ver si te sirve
Saludos
El fin NO justifica los medios.
Re: Duda Programación Robot
Gracias por la sugerencia, pero no funciona. Me salen unos lotes disparados. He probado esta otra opción que he encontrado en otro foro:Síntesis escribió: ↑09 Sep 2021 18:54
ValorDelTick = MarketInfo (Symbol(), Mode_TickValue);
Teniendo el valor del tick y el valor en euros a arriesgar y la distancia, puedes deducir el numero de lotes.
Lotes = NormalizeDouble(Valor a arriesgar en euros/Distancia Stop/ ValorDelTick,numDecimales);
A ver si te sirve
Saludos
double LotSize = SymbolInfoDouble(NULL,SYMBOL_TRADE_CONTRACT_SIZE);
double TickValue = SymbolInfoDouble(NULL,SYMBOL_TRADE_TICK_VALUE);
double TickSize = SymbolInfoDouble(NULL,SYMBOL_TRADE_TICK_SIZE);
double PointSize = SymbolInfoDouble(NULL,SYMBOL_POINT);
double lot_size = 0
double StopsInMoney = 50
double TakeProfit = 100
lot_size = StopsInMoney/(TakeProfit*LotSize*(TickValue/TickSize)*PointSize);
Pero tampoco funciona. en este caso los lots no pasan del mínimo. Como se puede ver en el ejemplo, quiero conseguir 50 euros si el precio alcanza un TP de 100 pips.
¿Alguna otra sugerencia?
Enseño a crear bots de forex sin necesidad de aprender lenguaje mql4/5.
¿Interesado? Visita my web https://www.theandorraninvestor.eu/es
Re: Duda Programación Robot
Te puedo pasar mi script pero te calcula sobre un porcentaje del balance. Lo puedes modificar si quieres para que te calcule sobre una cantidad.
Tiene otras opciones como el calculo automatico de la distancia del stop según el atr. También tengo los script para buy y sell con los parametros calculados aquí. Si te interesa me lo dices.
Tiene otras opciones como el calculo automatico de la distancia del stop según el atr. También tengo los script para buy y sell con los parametros calculados aquí. Si te interesa me lo dices.
Código: Seleccionar todo
//+------------------------------------------------------------------+
//| ParametrosSet.mq4 |
//| Copyright 2020, Sintesis |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, Sintesis"
#property version "4.00"
//--- strict compilation mode
#property strict
//--- show input parameters
#property show_inputs
//--- input parameters
extern double PorcRiesgo = 2; // Porcentaje Riesgo. "Si es cero, nº de lotes mínimo."
extern double Lotes = 0; // Nº Lotes. "Si Lotes== 0.0, entonces cálculo de lotes automatico."
extern bool distSL_Auto = true; // distSL_Auto. "Calcula la distancia SL automaticamente."
extern int distSL = 0; // Distancia SL. "Manual cuando distSL_Auto==false."
extern int distTP = 0; // Distancia TP.
extern double RatioTP = 1; // Si RatioTP =0 se toma Distancia TP.
extern double Balance = 0; // Balance. "Si Balance==0, Balance= Balance real de la cuenta."
extern double multiplicador_atr = 3; // Multiplicador ATR."Para calcular distancia del stop."
extern int n_atr = 10; // Numero velas ATR.
extern ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT;// TimeFrame para el calculo del riesgo.
extern int GV_Deslizamiento = 10; // Maximo deslizaminto;
extern int maximo_numero_lotes = 10; // Maximo nº de lotes;
double pipMultiplier,GV_DistSL,GV_DistTP,GV_Lotes,GV_ValorDelTick;
double StopRiesgo,ValorATR;
int nDecimales;
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart(){
//if (MuestraAlerta)Alert("");
nDecimales=1;
double x=MarketInfo(Symbol(),MODE_LOTSTEP)*10;
while(x<1)
{
x*=10; nDecimales+=1;
}
double digit = MarketInfo(Symbol(),MODE_DIGITS);
//digit=_Digits;
if(digit==2 || digit==4 || digit==1) pipMultiplier = 1;
if(digit==3 || digit==5) pipMultiplier = 10;
if(digit==6) pipMultiplier = 100;
ValorATR=MathFloor (iATR(NULL,TimeFrame,n_atr,1)/Point);
StopRiesgo=NormalizeDouble(multiplicador_atr*ValorATR,0);
if (distSL_Auto) GV_DistSL=StopRiesgo;else GV_DistSL=distSL;
GV_DistTP=distTP;
if (RatioTP!=0 && GV_DistSL!=0)GV_DistTP=GV_DistSL*RatioTP;
CalculoNumeroLotes();
//--- Asignar a Variables Globales
GlobalVariableSet("Ordenes_Lotes",GV_Lotes);
GlobalVariableSet("Ordenes_DistanciaSL",GV_DistSL);
GlobalVariableSet("Ordenes_DistanciaTP",GV_DistTP);
GlobalVariableSet("Ordenes_Deslizamiento",GV_Deslizamiento);
GlobalVariableSet("Valor_Tick",GV_ValorDelTick);
//GlobalVariableSet("Ordenes_PorcRiego",GV_PorcRiesgo);
//GlobalVariableSet("Ordenes_Balance",GV_Balance);
}
//+------------------------------------------------------------------+
void CalculoNumeroLotes()
{
Balance=MathRound(Balance);
if (Balance==0.0)Balance=MathRound(AccountBalance());
//if (Equidad=0.0)Equidad= MathRound(AccountEquity());
// Calculo con Fraccion Fija
GV_ValorDelTick =MarketInfo(Symbol(),MODE_TICKVALUE);
if (Lotes==0.0)GV_Lotes=NormalizeDouble(Balance*PorcRiesgo/100/StopRiesgo/ GV_ValorDelTick,nDecimales);
else GV_Lotes= Lotes;
GV_Lotes= MathRound (GV_Lotes/MarketInfo(Symbol(),MODE_LOTSTEP));
GV_Lotes= GV_Lotes*MarketInfo(Symbol(),MODE_LOTSTEP);
if (GV_Lotes<MarketInfo(Symbol(),MODE_MINLOT)) // Mínimo Nº de Lotes
{
//Alert(Symbol(),"-"+TFtoString(_Period),", Lotes= Mínimo nº de lotes= ",MarketInfo(Symbol(),MODE_MINLOT));
MessageBox("Lotes= "+MarketInfo(Symbol(),MODE_MINLOT)+" (mínimo nº de lotes) \r\r"+ "Dist SL= "+GV_DistSL+
" pips. Dist TP= "+GV_DistTP+" pips.",Symbol()+"-"+TFtoString(_Period) );
GV_Lotes=MarketInfo(Symbol(),MODE_MINLOT);return;
}
if(GV_Lotes>maximo_numero_lotes) // Máximo Nº de Lotes
{
//Alert(Symbol(),"-"+TFtoString(_Period), " Lotes= Máximo nº de lotes= ", maximo_numero_lotes);
MessageBox("Lotes= "+maximo_numero_lotes+" (máximo nº de lotes)\r\r Dist SL= "+GV_DistSL+
" pips. Dist TP= "+GV_DistTP+" pips.",Symbol()+"-"+TFtoString(_Period) );
GV_Lotes=maximo_numero_lotes;return;
}
if (Lotes==0.0) MessageBox("Lotes= "+ GV_Lotes+", Riesgo="+PorcRiesgo+"% sobre "+Balance+" €."+"\r\r"+
"Dist SL= "+GV_DistSL+ " pips. Dist TP= "+GV_DistTP+" pips.",Symbol()+"-"+TFtoString(_Period) );
else MessageBox(Symbol()+"-"+TFtoString(_Period)+": Nº Lotes discrecional="+ GV_Lotes);
}
//+------------------------------------------------------------------+
string TFtoString (int TF) {
string TFS = "";
switch(TF) {
case 1: TFS = "M1"; break;
case 5: TFS = "M5"; break;
case 15: TFS = "M15"; break;
case 30: TFS = "M30"; break;
case 60: TFS = "H1"; break;
case 240: TFS = "H4"; break;
case 1440: TFS = "D1"; break;
case 10080: TFS = "W1"; break;
case 43200: TFS = "MN1"; break;
}
return(TFS);
}
El fin NO justifica los medios.
Re: Duda Programación Robot
Gracias por compartir el código. Lo probaré.
Síntesis escribió: ↑12 Sep 2021 23:43 Te puedo pasar mi script pero te calcula sobre un porcentaje del balance. Lo puedes modificar si quieres para que te calcule sobre una cantidad.
Tiene otras opciones como el calculo automatico de la distancia del stop según el atr. También tengo los script para buy y sell con los parametros calculados aquí. Si te interesa me lo dices.
Código: Seleccionar todo
//+------------------------------------------------------------------+ //| ParametrosSet.mq4 | //| Copyright 2020, Sintesis | //| | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, Sintesis" #property version "4.00" //--- strict compilation mode #property strict //--- show input parameters #property show_inputs //--- input parameters extern double PorcRiesgo = 2; // Porcentaje Riesgo. "Si es cero, nº de lotes mínimo." extern double Lotes = 0; // Nº Lotes. "Si Lotes== 0.0, entonces cálculo de lotes automatico." extern bool distSL_Auto = true; // distSL_Auto. "Calcula la distancia SL automaticamente." extern int distSL = 0; // Distancia SL. "Manual cuando distSL_Auto==false." extern int distTP = 0; // Distancia TP. extern double RatioTP = 1; // Si RatioTP =0 se toma Distancia TP. extern double Balance = 0; // Balance. "Si Balance==0, Balance= Balance real de la cuenta." extern double multiplicador_atr = 3; // Multiplicador ATR."Para calcular distancia del stop." extern int n_atr = 10; // Numero velas ATR. extern ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT;// TimeFrame para el calculo del riesgo. extern int GV_Deslizamiento = 10; // Maximo deslizaminto; extern int maximo_numero_lotes = 10; // Maximo nº de lotes; double pipMultiplier,GV_DistSL,GV_DistTP,GV_Lotes,GV_ValorDelTick; double StopRiesgo,ValorATR; int nDecimales; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart(){ //if (MuestraAlerta)Alert(""); nDecimales=1; double x=MarketInfo(Symbol(),MODE_LOTSTEP)*10; while(x<1) { x*=10; nDecimales+=1; } double digit = MarketInfo(Symbol(),MODE_DIGITS); //digit=_Digits; if(digit==2 || digit==4 || digit==1) pipMultiplier = 1; if(digit==3 || digit==5) pipMultiplier = 10; if(digit==6) pipMultiplier = 100; ValorATR=MathFloor (iATR(NULL,TimeFrame,n_atr,1)/Point); StopRiesgo=NormalizeDouble(multiplicador_atr*ValorATR,0); if (distSL_Auto) GV_DistSL=StopRiesgo;else GV_DistSL=distSL; GV_DistTP=distTP; if (RatioTP!=0 && GV_DistSL!=0)GV_DistTP=GV_DistSL*RatioTP; CalculoNumeroLotes(); //--- Asignar a Variables Globales GlobalVariableSet("Ordenes_Lotes",GV_Lotes); GlobalVariableSet("Ordenes_DistanciaSL",GV_DistSL); GlobalVariableSet("Ordenes_DistanciaTP",GV_DistTP); GlobalVariableSet("Ordenes_Deslizamiento",GV_Deslizamiento); GlobalVariableSet("Valor_Tick",GV_ValorDelTick); //GlobalVariableSet("Ordenes_PorcRiego",GV_PorcRiesgo); //GlobalVariableSet("Ordenes_Balance",GV_Balance); } //+------------------------------------------------------------------+ void CalculoNumeroLotes() { Balance=MathRound(Balance); if (Balance==0.0)Balance=MathRound(AccountBalance()); //if (Equidad=0.0)Equidad= MathRound(AccountEquity()); // Calculo con Fraccion Fija GV_ValorDelTick =MarketInfo(Symbol(),MODE_TICKVALUE); if (Lotes==0.0)GV_Lotes=NormalizeDouble(Balance*PorcRiesgo/100/StopRiesgo/ GV_ValorDelTick,nDecimales); else GV_Lotes= Lotes; GV_Lotes= MathRound (GV_Lotes/MarketInfo(Symbol(),MODE_LOTSTEP)); GV_Lotes= GV_Lotes*MarketInfo(Symbol(),MODE_LOTSTEP); if (GV_Lotes<MarketInfo(Symbol(),MODE_MINLOT)) // Mínimo Nº de Lotes { //Alert(Symbol(),"-"+TFtoString(_Period),", Lotes= Mínimo nº de lotes= ",MarketInfo(Symbol(),MODE_MINLOT)); MessageBox("Lotes= "+MarketInfo(Symbol(),MODE_MINLOT)+" (mínimo nº de lotes) \r\r"+ "Dist SL= "+GV_DistSL+ " pips. Dist TP= "+GV_DistTP+" pips.",Symbol()+"-"+TFtoString(_Period) ); GV_Lotes=MarketInfo(Symbol(),MODE_MINLOT);return; } if(GV_Lotes>maximo_numero_lotes) // Máximo Nº de Lotes { //Alert(Symbol(),"-"+TFtoString(_Period), " Lotes= Máximo nº de lotes= ", maximo_numero_lotes); MessageBox("Lotes= "+maximo_numero_lotes+" (máximo nº de lotes)\r\r Dist SL= "+GV_DistSL+ " pips. Dist TP= "+GV_DistTP+" pips.",Symbol()+"-"+TFtoString(_Period) ); GV_Lotes=maximo_numero_lotes;return; } if (Lotes==0.0) MessageBox("Lotes= "+ GV_Lotes+", Riesgo="+PorcRiesgo+"% sobre "+Balance+" €."+"\r\r"+ "Dist SL= "+GV_DistSL+ " pips. Dist TP= "+GV_DistTP+" pips.",Symbol()+"-"+TFtoString(_Period) ); else MessageBox(Symbol()+"-"+TFtoString(_Period)+": Nº Lotes discrecional="+ GV_Lotes); } //+------------------------------------------------------------------+ string TFtoString (int TF) { string TFS = ""; switch(TF) { case 1: TFS = "M1"; break; case 5: TFS = "M5"; break; case 15: TFS = "M15"; break; case 30: TFS = "M30"; break; case 60: TFS = "H1"; break; case 240: TFS = "H4"; break; case 1440: TFS = "D1"; break; case 10080: TFS = "W1"; break; case 43200: TFS = "MN1"; break; } return(TFS); }
Enseño a crear bots de forex sin necesidad de aprender lenguaje mql4/5.
¿Interesado? Visita my web https://www.theandorraninvestor.eu/es
Si te ha gustado este hilo del Foro, ¡compártelo en redes!