//+------------------------------------------------------------------+ //| SimpleEATemplatev1.2.mq5 coded on DELL-SP3| //| Copyright 2024, Singularity Partners Sarl. | //| https://www.SingularityPartners.ch | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Singularity Partners Sarl." #property link "https://www.SingularityPartners.ch" #property version "1.0" // based on A6.16.4 // Idea of this EA is (Describe the intention of this EA) //Versión 1.3 Intento garantizar sólo un corto o largo abierto y estrategia con algún beneficio 2019-2024 // Results from 1 Jan 2017 until 1 Jan 2024: UR:3 RDD:22% Sharpe Ratio:2.08 %Profit:33% or so. T=980 R7=36,529 //Con TLINE para largos y para cortos. #include #define CUANTASVELAS 4 int mitick=0; uint porrsi=0; uint posicionlinea; uint nuevomax=0; double sumadeproporciones=0.0; datetime cuando_fue; bool largoabierto=false; bool debesdibujar=true; double ultimopreciocompra,ultimomaximo,ultimominimo; //+------------------------------------------------------------------+ //| Input Variables | //+------------------------------------------------------------------+ //Input Variables input group "Copyright 2024, www.SingularityPartners.ch " input double IL = 2; // IL Initial Lot input double SL = 0.05; // SL Stop Loss as Percent of Balance //input double TP = 0.03; // TP Take Profit as Percent of Balance input double TPP = 2600; // TPP Take Profit in Points originalmente venia con 1000 input double SLP = 2600; // SLP Stop Loss in Points input group "Signal Inputs" input uint Period = 67; // Period iMA input uint Shift = 6; // Shift iMA input double Proporcion=0.00023 ;// Proporcion -> la media es 0.00005 input uint MULTIPLICADOR=50; input ENUM_MA_METHOD METHOD = MODE_LWMA; input ENUM_APPLIED_PRICE APPLIED_PRICE = PRICE_WEIGHTED; input uint CBA =9; // CBA CopyBufferAmount input uint EMAFirst = 2 ; input uint EMASecond = 4 ; /*input uint rsiPeriod = 60; // Período del RSI originalmente era 14 input uint overboughtLevel = 100; // Nivel de sobrecompra input uint oversoldLevel = 0; // Nivel de sobreventa*/ input double DESPLAZAMIENTO=15; //Include Files #include CTrade trade; //Trade Class // Variables Definitions //bool signal; int signal=-1; bool CS; // Close Shorts - en español ciérrame cortos bool CL; // Close Longs - en español ciérrame largos. int LT; // Counter of Long Trades int ST; // Counter of Short Trades int T; // Counter of Total Trades int L; // Code Line double EMAArray[]; bool quedaparcial=false; double DESPLAZAMIENTOVARIABLE; double OnTester() { double RDD = TesterStatistics ( STAT_EQUITY_DDREL_PERCENT ) ; double Numerator = (TesterStatistics (STAT_PROFIT) + TesterStatistics (STAT_INITIAL_DEPOSIT)); double Denominator = (TesterStatistics (STAT_INITIAL_DEPOSIT)*(5+5/12)*RDD*0.01); // 5+5/12 as Measured from Jan 2019 until May 2024 //string UR = TesterStatistics ((STAT_PROFIT+STAT_INITIAL_DEPOSIT)/STAT_INITIAL_DEPOSIT/7/STAT_EQUITY_DDREL_PERCENT*0.01); double UR = Numerator/Denominator; string concatenatedString = DoubleToString(UR,0)+ "." + DoubleToString(RDD,0) ; // UR.RDD UR cuanto más grande mejor, RDD cuanto más pequeño mejor return StringToDouble(concatenatedString); } void OnTick() { double raya=0; long micolor=0; mitick++; MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); //+------------------------------------------------------------------+ //| Price | //+------------------------------------------------------------------+ // Price double Ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); //+------------------------------------------------------------------+ //| Balance, Equity, Profit | //+------------------------------------------------------------------+ // Balance, Equity, Profit double Balance=NormalizeDouble(AccountInfoDouble(ACCOUNT_BALANCE),0); double Equity=NormalizeDouble(AccountInfoDouble(ACCOUNT_EQUITY),0); double Profit=NormalizeDouble(AccountInfoDouble(ACCOUNT_PROFIT),0); //+------------------------------------------------------------------+ //| Longs Shorts Counter | //+------------------------------------------------------------------+ LT=0; ST=0; T=0; //Print (" Las position total que me da en el preconteo de largos y cortos es ",PositionsTotal()); for(int i = 0; i < PositionsTotal(); i++) { ulong ticket = PositionGetTicket(i); PositionSelectByTicket(ticket); if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) // if it's a long' { LT ++; ultimopreciocompra = PositionGetDouble(POSITION_PRICE_OPEN); // obtener el precio de compra } else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) // if it's short { ST ++; ultimopreciocompra = PositionGetDouble(POSITION_PRICE_OPEN); // obtener el precio de compra } T=(LT+ST); } if (PositionsTotal()==0) ultimopreciocompra=0.00; //+------------------------------------------------------------------+ //| Sensing | //+------------------------------------------------------------------+ // esa media de cierres de x velas que me servirá para señal. Print ("Señal modulada : ",signalModulada(CUANTASVELAS)); if (T==0) { signal=-1; //Print ("Valor de la media de las 3 velas: " , mediacierres , " y el de la vela 0 me da : ",actualvela); if (signalModulada(CUANTASVELAS)<=0.4) { Print ("que la cosa parece que está pa compra "); signal=0; // largoabierto=true; } else if (signalModulada(CUANTASVELAS)>=0.6) { Print ("que la cosa parece que está pa ponerse de corto "); signal=1; largoabierto=true; } else signal=-1; } //Aquí se cierra el bloque que sirve para la primera . if (quedaparcial) DESPLAZAMIENTOVARIABLE=2*DESPLAZAMIENTO; if (LT==1) { Print ("¡escúchame!, hay largo abierto "); if (Ask=1)if(Equity=1)if(Equity=0; i--) { ulong ticket=PositionGetTicket(i); PositionSelectByTicket(ticket); if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { if (quedaparcial) { //si cumplió para cierre parcial, se cerrará parcialmente double volume = PositionGetDouble(POSITION_VOLUME); // Obtener el volumen de la posición double closeVolume =volume*2*(signalModulada(CUANTASVELAS)-0.5); // Calcular el volumen a cerrar (la mitad) trade.PositionClosePartial(ticket,closeVolume); quedaparcial=false; //se pone a false porque se inhabilita la señal. //abiertocompleto=false; // se pone a false para saber que "lo próximo" no podrá ser cierre parcial. Print ("Se ha hecho CORTO PARCIAL DE ",closeVolume," con señalM de",signalModulada(CUANTASVELAS)); signal=-1; MqlTradeRequest request; request.comment ="ultimo minuto"; } else { Print (" Por curiosidad cierro y el valor ticket es = ",ticket, " la position select por ticket es ",PositionSelectByTicket(ticket)); trade.PositionClose(ticket); ultimomaximo=0; ultimominimo=DBL_MAX; ultimopreciocompra=0; raya=0; signal=1; // largoabierto=false; // debesdibujar=false; } } } CL=0; L=__LINE__;Print("CL=1 CONFIRMED. L:",__LINE__); } //+------------------------------------------------------------------+ //| CLOSING SHORTS | //+------------------------------------------------------------------+ if(CS==1) { for(int i=PositionsTotal()-1;i>=0; i--) { ulong ticket2=PositionGetTicket(i); PositionSelectByTicket(ticket2); if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { if (quedaparcial) { double volume = PositionGetDouble(POSITION_VOLUME); // Obtener el volumen de la posición double closeVolume = (1-2*signalModulada(CUANTASVELAS))*volume; // Calcular el volumen a cerrar (la mitad) trade.PositionClosePartial(ticket2, closeVolume); quedaparcial=false; Print ("Se ha hecho LARGO PARCIAL DE ",closeVolume," con señalM de",signalModulada(CUANTASVELAS)); //abiertocompleto=false; signal=-1; } else { Print (" Por curiosidad cierro corteando y el valor ticket es = ",ticket2, " la position select por ticket es ",PositionSelectByTicket(ticket2)); trade.PositionClose(ticket2); ultimominimo=DBL_MAX; ultimomaximo=0; ultimopreciocompra=0; raya=0; signal=0; } } } CS=0; L=__LINE__;Print("CS=1 CONFIRMED. L:",__LINE__); } //+------------------------------------------------------------------+ //| Dashboard | //+------------------------------------------------------------------+ /*Comment("© Singularity Partners 2024","\n", "CODE LINE:",L,"\n", "Balance:",DoubleToString(Balance,0)," Equity:",DoubleToString(Equity,0)," Profit:",DoubleToString(Profit,0),"\n", "PRICE 0: ",ultimopreciocompra," LT = ",LT," ST = ",ST, " SeñalM :",signalModulada(CUANTASVELAS),"\n", " ultimominimo : ",ultimominimo," El TLINE es : ",raya , " ultimomaximo: ",ultimomaximo," Trailing EQ.: ",NormalizeDouble (Balance+(raya-ultimopreciocompra)*IL*(LT-ST),2),"\n" );*/ } void dibujaLinea (datetime time1, double price1,datetime time2, double price2,long colorcico) { string line_name = "TLine"; // Comprobar si el objeto ya existe y eliminarlo if(ObjectFind(0, line_name) >= 0) ObjectDelete(0, line_name); // Definir las coordenadas de la línea // datetime time1 = TimeCurrent(); // Fecha y hora del primer punto // double price1 = Ask; // Precio del primer punto //datetime time2 = TimeCurrent()-600; // Fecha y hora del segundo punto // double price2 = puntoderesistencia; // Precio del segundo punto // Crear la línea de tendencia ObjectCreate(0, line_name, OBJ_TREND, 0, time1, price1, time2, price2); // Configurar las propiedades de la línea ObjectSetInteger(0, line_name, OBJPROP_COLOR, colorcico); // Color de la línea ObjectSetInteger(0, line_name, OBJPROP_WIDTH, 2); // Ancho de la línea ObjectSetInteger(0, line_name, OBJPROP_STYLE, STYLE_SOLID); // Estilo de la línea } double signalModulada (int numerodevelas) { double total=0; for (int numvela=1;numvela<=numerodevelas;numvela++) { total = iClose(_Symbol, _Period, numvela) + total; } double mediacierres=total/numerodevelas; double actualvela=iClose(_Symbol, _Period, 0); Print ("Valor de la media de las 3 velas: " , mediacierres , " y el de la vela 0 me da : ",actualvela); double signalM=0.5-NormalizeDouble(MULTIPLICADOR*((actualvela-mediacierres)/mediacierres),1); //ese multiplicador, futuro input if (signalM<0) return 0; if (signalM>1) return 1; return signalM; }