Enlaces

lunes, 17 de enero de 2022

EL SISTEMA BLUEBAR

El primer vídeo que se subió en 2019 al canal YouTube de Onda4 muestra un sistema de trading completo, con su backtesting y con su algoritmo de ejecución automática de órdenes. El vídeo es el siguiente: https://youtu.be/2kZ6txO_gX4

A efectos didácticos, y como una pequeña muestra de lo que se puede hacer con Amibroker, he decidido compartir tanto el Backtester como el algoritmo IBcontroller que permite la ejecución automática de órdenes. El fichero rar con el código BLUEBAR se puede descargar aquí


CÓDIGO BLUEBAR BACKTESTER

//***********************************************************************
// SISTEMA DE TRADING "BLUEBAR" PARA EL FUTURO MICRO DEL NASDAQ100
// ESTA ES LA PARTE DEL BACKTESTER. PERMITE SIMULAR EN DATOS HISTÓRICOS
// OSCAR G. CAGIGAS. CREADO 12 AGO 2019. REVISADO 17 ENE 2022
// ESTE CÓDIGO SE PROPORCIONA "TAL CUAL" Y NO SE GARANTIZA QUE ESTÉ LIBRE DE ERRORES. 
// SE OFRECE CON PROPÓSITO DIDÁCTICO. EN NINGÚN CASO SE RECOMIENDA LA OPERATIVA EN DERIVADOS
// VÍDEO YOUTUBE CON EJEMPLO DE USO: https://youtu.be/2kZ6txO_gX4
// *SIMULAR EN GRÁFICOS DE 5min*  
//************************************************************************
//VARIABLES DE SIMULACIÓN   
ObjVolat = 200; //objetivo de volatilidad    
MaxVolat = 280; //Optimize("maxvolat",280,200,300,10); //Si se supera no abrimos posiciones
NStop = Optimize("NStop",2.5,2,3,0.5);
NTarget = Optimize("NTarget",4,4,14,0.5);  
LastBar = Optimize("LastBar", 5,4,12,1);
HoraPrevio = 152500;
HoraApertura = 153000;  //cuando operamos
//-----------------------MONEY MANAGEMENT--------------------------------   
//CAPITAL INICIAL Y COMISIONES//     
SetOption("WarningLevel", 1 ); 
SetOption( "initialequity", 10000 );   
SetOption("CommissionMode", 2); 
SetOption("commissionamount",10);     
PointValue = 2; MarginDeposit = 1;  //futuro micro del Nasdaq100
//Número de ctos para una volatilidad de $200
PositionSize = Ctos = Ref( round( Nz(ObjVolat/(ATR(20)*PointValue) ) ),-1); 
//-----------------------------------------------------------------------   

//+++++++++++++++++++++ SISTEMA DE TRADING +++++++++++++++++++++++  
//STOP Y TARGET EN PUNTOS
StopPtos = Nstop*ATR(10);
TargetPtos = NTarget*ATR(10); 
//DEFINICIONES
dn = DateNum(); 
tn = TimeNum();
newDay = dn != Ref( dn,-1);
Apertura = tn == HoraApertura;
Previo = tn == HoraPrevio;
TradeTime = tn >= HoraApertura AND BarsSince( Apertura ) <= LastBar; 
Volat = Ref(ATR(20)*PointValue,-1); 
Rango = ValueWhen( Previo, Max( ATR(10), HHV(H,3)-LLV(L,3) )  );  //Rango Barras Previas a la apertura
//CIERRE DE DOS DÍAS PREVIOS
C1 = TimeFrameGetPrice("C",inDaily,-1);
C2 = TimeFrameGetPrice("C",inDaily,-2);
//BUY EASY DAY (SI HUBO CAÍDAS) Y SELL EASY DAY (SI HUBO SUBIDAS)
BED = C1 <= C2;
SED = C1 > C2;
//BUYSTOP AND SHORTSTOP
BuyStop = IIf(BED, Open + 0.5*Rango, Open + Rango);
Shortstop = IIf(SED, Open - 0.5*Rango, Open - Rango);
//ENTRADAS LIMPIAS, TOCA BUYSTOP O SHORTSTOP PERO NO LOS DOS 
Buy1 =  TradeTime AND H > BuyStop AND NOT L < shortstop; 
Short1 = TradeTime AND L < ShortStop AND NOT H > Buystop; 
 
//ENTRADAS QUE REBASAN BUYSTOP Y SHORTSTOP A LA VEZ 
Buy2 = TradeTime AND H > BuyStop AND L < shortstop AND C < O;  //se asume que fue al máximo primero 
Short2 = TradeTime AND H > BuyStop AND L < shortstop AND C > O; //se asume que fue al mínimo primero 
//VOLATILIDAD OK
VolatOK = Volat < MaxVolat;  //barra anterior
//TODAS LAS ENTRADAS JUNTAS 
Buy = (Buy1 OR Buy2) AND VolatOK; 
Short = (Short1 OR Short2) AND VolatOK; 
BuyPrice = CoverPrice = BuyStop; 
ShortPrice = SellPrice = ShortStop; 
//PERMITIR SOLO UNA ENTRADA POR DÍA
Buy = Buy AND Sum( Buy, BarsSince( newDay) +1 ) <= 1;
Short = Short AND Sum( Short, BarsSince( newDay) +1 ) <= 1;
//SALIDA SOLO POR SL Y OBJETIVOS 
Sell = Cover = 0;
//STOP LOSS Y TARGET   
SetOption("ActivateStopsImmediately",False);   
ApplyStop(stopTypeProfit,stopModePoint, TargetPtos,1,0);  
ApplyStop(stopTypeLoss,stopModePoint, StopPtos,1,0); 
Equity(1,0);
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++   
   
//-------------------------PARTE VISUAL-------------------------------------   
   
//CHART CON INDICACIÓN DE COMPRA Y CORTOS   
color = IIf(Apertura, colorBlue, colorBlack);   
Plot(C,"PRICE",color,styleBar|styleThick,Null,Null,0,0,2);        
Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) )         
+"\n"+ FullName() +"\n"+ EncodeColor(colorBlue) + "Volat = $"    
+ WriteVal(ATR(20)*PointValue,1.0) +"; x"   + WriteVal(PointValue,1.0) + " (" + TickSize +")"   
+"\n" + EncodeColor(colorblack) + "----------------------------------"     
+"\n" + "BuyStop = " + WriteVal(BuyStop,1.2) 
+"\n" + "ShortStop = " + WriteVal(Shortstop,1.2)         
+"\n" + "Rango = " + Rango + " ($" + WriteVal(Rango*PointValue,1.0) + ")"
+"\n" + "Ctos = " + WriteVal(Ctos,1.0)     
+"\n"+ "----------------------------------"
+"\n"+ WriteIf(BED, "BUY EASY", "SELL EASY")
+"\n"+ "ATR10 = " + ATR(10)
+"\n"+ "Target = $" + WriteVal(TargetPtos*PointValue,1.0)
+"\n"+ "Stop = $" + WriteVal(StopPtos*PointValue,1.0)
+"\n" + "HoraApertura= " + HoraApertura;
   
//CIRCULOS EN LAS ENTRADAS Y SALIDAS   
PlotShapes(IIf(Buy,shapeUpArrow,shapeNone),colorGreen,0,L,-15);    
PlotShapes(IIf(Buy,shapeHollowCircle,shapeNone),colorGreen,0,BuyPrice,0);    
PlotShapes(IIf(Sell AND NOT Short,shapeDownArrow,shapeNone),colorRed,0,H,-15);    
PlotShapes(IIf(Sell AND NOT Short,shapeHollowCircle,shapeNone),colorRed,0,SellPrice,0);    
PlotShapes(IIf(Short,shapeDownArrow,shapeNone),colorBrown,0,H,-15);    
PlotShapes(IIf(Short,shapeHollowCircle,shapeNone),colorBrown,0,ShortPrice,0);    
PlotShapes(IIf(Cover AND NOT Buy,shapeUpArrow,shapeNone),colorDarkGreen,0,L,-15);    
PlotShapes(IIf(Cover AND NOT Buy,shapeHollowCircle,shapeNone),colorDarkGreen,0,CoverPrice,0);    
//NIVELES DE ENTRADA EN GRIS 
color2 = ColorBlend( colorBlue, colorWhite, 0.95 );
Plot(sup = IIf(TradeTime OR Previo, BuyStop, Null),"BuyStop",colorGrey50,styleLine);
Plot(inf = IIf(TradeTime OR Previo, ShortStop, Null),"ShortStop",colorGrey50,styleLine);
PlotOHLC(sup,sup,inf,inf,"",color2,styleCloud | styleNoRescale, Null, Null, Null, -1 );
   
//PLOTTEXT//    
dist = 2*ATR(10);     
for( i = 0; i < BarCount; i++ )     
{     
if( Buy[i] ) PlotText( "Long "+NumToStr(ValueWhen(Buy[i],BuyPrice[i]),1.2), i, L[ i ]-dist[i], colorGreen );     
if( Sell[i] AND NOT Short[i]) PlotText( "Exit " + NumToStr(ValueWhen(Sell[i],SellPrice[i]),1.2), i, H[ i ]+dist[i], colorRed );     
if( Short[i] ) PlotText( "Short "+NumToStr(ValueWhen(Short[i],ShortPrice[i]),1.2), i, H[ i ]+dist[i], colorBrown );     
if( Cover[i] AND NOT Buy[i]) PlotText( "Cover " + NumToStr(ValueWhen(Cover[i],CoverPrice[i]),1.2), i, L[ i ]-dist[i], colorBlack );     
}     
     
//AVISAR SI LA VOLATILIDAD ES EXCESIVA
if( SelectedValue(VolatOK) == False)
{
GfxSetBkColor( colorGold); GfxSelectFont( "Tahoma", 15 );   
GfxSetBkMode( 2 ); GfxTextOut("VOLAT[1] = $" + WriteVal(Volat,1), 40, 900 ); 
}
//---------------------------------------------------------------------- 


CÓDIGO BLUEBAR AUTOTRADING

//*****************************************************************************
// ALGORITMO DE AUTOTRADING *BLUEBAR*
// OSCAR G. CAGIGAS 
// CREADO 21 AGOSTO 2019. REVISADO 17 ENERO 2022
// ESTE CÓDIGO SE PROPORCIONA "TAL CUAL" Y NO SE GARANTIZA QUE ESTÉ LIBRE DE ERRORES. 
// SE OFRECE SOLAMENTE CON PROPÓSITO DIDÁCTICO Y DESACTIVADO PARA QUE NO EJECUTE 
// ÓRDENES EN EL MERCADO (TRANSMIT = FALSE).
// EN NINGÚN CASO SE RECOMIENDA LA OPERATIVA EN DERIVADOS
// VÍDEO YOUTUBE CON EJEMPLO DE USO: https://youtu.be/2kZ6txO_gX4
//******************************************************************************
//VARIABLES
SegToMkt = 10; //Segundos para hacer la operación a mercado
transmit = false; //No activar
ObjVolat = 200; //Objetivo de volatilidad. 
MaxVolat = 280; //Máx Volat por Contrato
NStop = 2.5; //Veces del ATR(10) para el stop loss
NTarget = 4; //Veces del ATR(10) para el Target
LastBar = 5; //última barra donde se permite entrar
HoraPrevio = 152500; //Preapertura. Cuando miramos el rango  
HoraApertura = 153000;  //Apertura. Cuando operamos
ganancia = 0; //valor inicial (se crea dentro del IBcontroller)
//parámetros del futuro micro del Nasdaq
tib = "MNQH2-GLOBEX-FUT";  //ticker en formato IB
dec = 2; //dos decimales en el precio
PointValue = 2;
TickSize = 0.25;
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
//XXXXXXXXXXXXXXXXXXXXXXXX FUNCIONES XXXXXXXXXXXXXXXXXXXXXXXXXXXX
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
//MOSTRAR SOLO EN EL ÚLTIMO DÍA DESDE LA PREAPERTURA
function ShowLastDay( array )
{
    dn = datenum(); tn = TimeNum();
    lastDay = dn == LastValue( dn ) && tn >= 90000;
    return IIf( lastDay, array, Null );
}
//FUNCION REDONDEA AL TICK PARA FORMATO REAL DE TRADING
function Redondea( precio )
{
TickInv = 1 / TickSize;
return ( round( precio * TickInv ) / TickInv );

//Decir TEXTO Cada MINPERIOD Segundos
function DecirCada( text, Minperiod ) 
 { 
    elapsed=GetPerformanceCounter()/1000; 
    Lastelapsed = Nz( StaticVarGet("lastsaytime") ); 
   if( elapsed - Lastelapsed > Minperiod ) 
    { 
      StaticVarSet("lastsaytime", elapsed );       
      Say( text ); 
    }     
 } 
//RESETEAR VARIABLES
procedure ResetearVariables()
{
StaticVarSetText("EntryID"+Name(), "");
StaticVarSetText("StopID"+Name(), "");
StaticVarSetText("TargetID"+Name(), "");
StaticVarSet("PrecioEntry"+Name(), Null);
StaticVarSet("PrecioStop"+Name(), Null);
StaticVarSet("PrecioTarget"+Name(), Null);
StaticVarSet("Intento"+Name(), 0); 
StaticVarSet("MP"+Name(), 0); //Market Position
StaticVarSet("OrderTime"+Name(), 0);
}
//################################################################################
//############################## LÓGICA DE ENTRADA ###############################
//################################################################################
//DEFINICIONES
dn = DateNum(); 
tn = TimeNum();
newDay = dn != Ref( dn,-1);
Previo = tn == HoraPrevio;
Apertura = tn == HoraApertura;
TradeTime = tn >= HoraApertura AND BarsSince( Apertura ) <= LastBar; //solo se puede operar en este periodo
Rango = ValueWhen( Previo, Max( ATR(10), HHV(H,3)-LLV(L,3) )  );  //Rango Barras Previas a la apertura
Volat = Ref(ATR(20)*PointValue,-1); //Volat en dólares por contrato
VolatOK = Volat < MaxVolat;  //volatilidad adecuada
//BUYSTOP AND SELLSTOP WITH PATTERN RECOGNITION
C1 = TimeFrameGetPrice("C",inDaily,-1);
C2 = TimeFrameGetPrice("C",inDaily,-2);
BED = C1 <= C2; SED = C1 > C2; //Buy Easy Day, Sell Easy Day
BuyStop = IIf(BED, Open + 0.5*Rango, Open + Rango);
SellStop = IIf(SED, Open - 0.5*Rango, Open - Rango);
//LEEMOS LOS CONTRATOS DE LA VARIABLE ESTÁTICA
Ctos = Nz( StaticVarGet("Ctos"+Name()) ); 
//NÚMERO DE CONTRATOS POR VOLATILIDAD
CtosVolat = Ref( round( Nz(ObjVolat/(ATR(20)*PointValue) ) ),-1); 
//**************MARKET POSITION**************** 
// 1 primer largo,  2 girado al alza,  3 girado tras SL,  4 BreakEvenLargo
//-1 primer corto, -2 girado a corto, -3 girado tras SL, -4 BreakEvenCorto
//*********************************************
MP = Nz( StaticVarGet("MP"+Name()) );  //MP = 0 es sin posiciones

//ENTRADAS
Buy = TradeTime AND VolatOK AND C > BuyStop;
if( LastValue(Buy) && MP == 0)
{
Say("Compra");
StaticVarSet("MP"+Name(), 1, True);  //persistent = true   
StaticVarSet( "Ctos"+Name(), LastValue(CtosVolat), True );
}
Short = TradeTime AND VolatOK AND C < SellStop;
if( LastValue(Short) && MP == 0)
{
Say("Vende");
StaticVarSet("MP"+Name(), -1, True); 
StaticVarSet( "Ctos"+Name(), LastValue(CtosVolat), True );  
}
//--------------------------------PARTE VISUAL-------------------------------------
//CHART CON INDICACIONES
color = IIf(Apertura, colorBlue, colorBlack);
Plot(C,"PRICE",color,styleBar|styleThick,Null,Null,0,0,2);     
Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) )      
+"\n"+ FullName() +"; Mult x"   + WriteVal(PointValue,1.0) + " (" + TickSize +")" +"\n"+ EncodeColor(colorBlue) 
+ "ATR20 = " + WriteVal( ATR(20), 1.2 ) + "; CtosVolat = " + CtosVolat + "; Volat = $" + WriteVal(ATR(20)*PointValue*CtosVolat,1.0) 
+"\n" + "ATR10 = " + WriteVal(ATR(10),1.2) + "; SL = " + WriteVal(Nstop*ATR(10),1.2) + " Ptos"
+"\n"+ "----------------------------------";

//NIVELES EN EL GRÁFICO
color2 = ColorBlend( colorBlue, colorWhite, 0.95 );
Plot(sup =  IIf(TradeTime OR Previo, BuyStop, Null), "BuyStop",colorGrey50,styleLine);
Plot(inf =  IIf(TradeTime OR Previo, SellStop, Null),"SellStop",colorGrey50,styleLine);
PlotOHLC(sup,sup,inf,inf,"",color2,styleCloud | styleNoRescale, Null, Null, Null, -1 );

//OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
//OOOOOOOOOOOOOOOOOOOOOOOOOOOO   IBCONTROLLER  OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
//OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
//PREVIO. AVISAR CON MENSAJE
if( LastValue(Previo) )
{
DecirCada("Preapertura",400);
}
//HORA DE ENTRAR. AVISAR CON MENSAJE
if( LastValue(Apertura) )
{
DecirCada("Apertura",150);
}
//AUTOTRADING arranca el IBController
autotrading = ParamToggle("IBController","No|Yes",0);
//Si falla una entrada hay que resetear los EntryID o no entrará de nuevo
reset = ParamTrigger("RESET","RESETEAR VARIABLES");  
if(reset) ResetearVariables();
if (autotrading)
{
ibc = GetTradingInterface("IB"); //arranca el IBCONTROLLER
RequestTimedRefresh( 1 );  //refresca el gráfico VISIBLE cada 1 seg

//PRECISIÓN EN IBCONTROLLER
tickIB = 1;

//LEE LAS VARIABLES ESTÁTICAS (CERO LA PRIMERA VEZ)
Ctos = Nz( StaticVarGet("Ctos"+Name()) ); 
EntryID = StaticVarGetText("EntryID"+Name()); 
StopID = StaticVarGetText("StopID"+Name());
TargetID = StaticVarGetText("TargetID"+Name());
PrecioEntry = StaticVarGet("PrecioEntry"+Name());
PrecioStop = StaticVarGet("PrecioStop"+Name());
PrecioTarget = StaticVarGet("PrecioTarget"+Name());
Intento = Nz( StaticVarGet("Intento"+Name()) ); //intentos de abrir o cerrar la posición (3)
OrderTime = StaticVarGet("OrderTime"+Name());

//PINTAMOS NIVELES DE STOP Y TARGET
Plot( ShowLastDay( PrecioStop ), "PrecioStop", colorRed, styleThick  );
Plot( ShowLastDay( PrecioTarget), "PrecioTarget", colorGreen, styleThick  );
//CONTAR SEGUNDOS DESDE SITUAR LA POSICIÓN
Contador = DateTimeDiff( Now(5), OrderTime );  
Contador = IIf( Contador > SegToMkt, 0, Contador);  //SI AGOTADO PONEMOS A CERO

//ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
//ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ  GIROS  ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
//ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

//GIRO A LA BAJA
if( LastValue(TradeTime) && MP == 1 && LastValue(C < SellStop) ) //Giro a la baja
{
ibc.CancelOrder( StopID ); //Cancelar el stop anterior (cancela también el Target al ser OCA)
ResetearVariables(); //para que pueda volver a entrar
StaticVarSet("Ctos"+Name(), 2*Ctos, True);  
StaticVarSet("MP"+Name(), -2, True); //MP = -2 es girado a la Baja
Say("Giro");
}
//GIRO AL ALZA
if( LastValue(TradeTime) && MP == -1 && LastValue(C > BuyStop) ) //Giro al alza
{
ibc.CancelOrder( StopID ); //cancelar el stop anterior
ResetearVariables(); //para que pueda volver a entrar
StaticVarSet("Ctos"+Name(), 2*Ctos, True);  
StaticVarSet("MP"+Name(), 2, True);
Say("Giro");
}

//SI ESTÁ CONECTADO OPERA
if ( ibc.IsConnected() )
{

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ALCISTA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if( MP > 0  )  //ALCISTA NORMAL O GIRADO
{
//---------------------ABRIR LARGOS-----------------------------------

//AL PRINCIPIO INTENTAMOS ENTRAR CON DESCUENTO DE UN TICK
if( intento == 0 AND LastValue(Buy) AND EntryID == "") //primer intento
{
//ENTRADA Y STOP LOSS (BRACKET)
Say("Situada Orden");
Precio = Prec( C - TickSize, dec ); //precio es array. Dec son los decimales (del include)
EntryID = ibc.PlaceOrder( tib, "BUY", Ctos, "LMT", LastValue( Precio ), 0, "DAY", transmit, tickIB); //COMPRA A LMT
StaticVarSetText("EntryID"+Name(), EntryID, True); //almacenamos el ID de la orden (existe solo con situar la orden)

//PRIMER INTENTO. REGISTRAR HORA ENTRADA
StaticVarSet("Intento"+Name(), 1, True); //PRIMER INTENTO
StaticVarSet("OrderTime"+Name(), Now(5), True); //REGISTRAMOS HORA DE LA ORDEN
PlaySound("C:\\Windows\\Media\\ding.wav"); //Si suena es que está la Orden metida. A esperar que se haga
}

//CONTADOR A MITAD DE SegToMkt INTENTAMOS ENTRAR AL ÚLTIMO PRECIO DISPONIBLE (LAST)
if( intento == 1 AND Contador == int(SegToMkt/2) AND EntryID != "") 
{
//ENTRADA Y STOP LOSS
ibc.ModifyOrder( EntryID, tib, "BUY", Ctos, "LMT", LastValue(C), 0, "DAY", Transmit, tickIB); //COMPRA A LMT
StaticVarSet("Intento"+Name(), 2, True); //SEGUNDO INTENTO
Say("Uy!");
}
//CONTADOR A SegToMkt ENTRAMOS A MERCADO
if(  Intento == 2 AND Contador == SegToMkt AND EntryID != "") 
{
//ENTRADA Y STOP LOSS
ibc.ModifyOrder( EntryID, tib, "BUY", Ctos, "MKT", 0, 0, "DAY", transmit); //COMPRA A MERCADO
StaticVarSet("Intento"+Name(), 3, True); //TERCER INTENTO
}

//SI SE HIZO LA ENTRADA Y YA TENEMOS EL PRECIO ENTONCES RESETEAMOS INTENTOS, PONEMOS STOPS, ETC
PrecioEntry = Nz(ibc.GetPositionInfo( tib, "Avg. cost") / PointValue); //mayor que cero cuando lea del Ibc
if ( ibc.GetStatus( EntryID, True ) == "Filled" AND StopID == "" AND PrecioEntry  > 0)  
{
//RESETEAMOS INTENTOS
StaticVarSet("Intento"+Name(), 0, True); 

//SI GIRADO CON DOBLE DE CONTRATOS ENTONCES VOLVEMOS A NORMALIDAD
if( MP == 2 ) StaticVarSet("Ctos"+Name(), Ctos/2, True);

//PONEMOS STOP Y TARGET
PopupWindow(NumToStr(ATR(10)),"ATR10",60);
Ctos = StaticVarGet("Ctos"+Name()); 
Stop = Redondea( LastValue(PrecioEntry - NStop*ATR(10)) );
Objetivo = Redondea( LastValue(PrecioEntry + NTarget*ATR(10)) );
StopID = ibc.PlaceOrder( tib, "SELL", Ctos, "STP", 0, Stop, "GTC", transmit, tickIB, "outsideRTH","","123"); //stop loss
TargetID = ibc.PlaceOrder( tib, "SELL", Ctos, "LMT", Objetivo, 0, "GTC", transmit, tickIB, "","","123"); //target
StaticVarSetText("StopID"+Name(), StopID, True); //almacenamos el ID del stop loss
StaticVarSetText("TargetID"+Name(), TargetID, True); //almacenamos el ID del Target
StaticVarSet("PrecioEntry"+Name(), PrecioEntry, True); //almacenamos el precio de entrada
StaticVarSet("PrecioStop"+Name(), Stop, True); //almacenamos el precio de SL
StaticVarSet("PrecioTarget"+Name(), Objetivo, True); //almacenamos el precio de Target
Say("Comprado");
}

//PINTAMOS EL PRECIO DE ENTRADA COMO UNA LÍNEA GRIS
Plot( IIf(PrecioEntry > 0, ShowLastDay( PrecioEntry ), Null), "PrecioEntry", colorLightGrey, styleThick  );

//BREAKEVEN CUANDO GANE EL DOBLE DEL STOP
ActivarBElong = LastValue(C) > PrecioEntry + 2*(PrecioEntry - PrecioStop);
if ( !StopID == "" AND ActivarBElong AND MP < 4 ) //MP = 4 es activado BreakEven largo
{
ibc.ModifyOrder( StopID, tib, "SELL", Ctos, "STP", 0, Redondea( PrecioEntry ), 
"GTC", transmit, tickIB, "outsideRTH"); //stop loss
StaticVarSet("PrecioStop"+Name(), Redondea( PrecioEntry ), True); //almacenamos el stop
StaticVarSet("MP"+Name(), 4,True);
Say("He subido el stop al precio de compra");
}

//SI SE HIZO EL STOP EN LA 1A ENTRADA PUEDE VOLVER A ENTRAR PERO EN SENTIDO CONTRARIO
HechoStop = ibc.GetStatus( StopID, True ) == "Filled";
if ( !EntryID == "" AND HechoStop AND MP == 1 )  
{
ResetearVariables(); //para que pueda volver a entrar
StaticVarSet("MP"+Name(), -3, True); //MP = -3 es girado a bajista después de un stop loss
}

} //if alcista

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ BAJISTA @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

if( MP < 0 ) //BAJISTA NORMAL O GIRADO
{
//---------------------ABRIR CORTOS-----------------------------------

//AL PRINCIPIO INTENTAMOS ENTRAR CON DESCUENTO DE UN TICK
if( intento == 0 AND LastValue(Short) AND EntryID == "") //primer intento
{
//ENTRADA Y STOP LOSS (BRACKET)
Say("Situada Orden");
Precio = Prec( C + TickSize, dec ); //array
EntryID = ibc.PlaceOrder( tib, "SELL", Ctos, "LMT", LastValue(Precio), 0, "DAY", transmit, tickIB); //CORTO A LMT
StaticVarSetText("EntryID"+Name(), EntryID, True); //almacenamos el ID de la orden (existe solo con situar la orden)

//PRIMER INTENTO. REGISTRAR HORA ENTRADA
StaticVarSet("Intento"+Name(), 1, True); //PRIMER INTENTO
StaticVarSet("OrderTime"+Name(), Now(5), True);
PlaySound("C:\\Windows\\Media\\ding.wav"); //Si suena es que está la Orden metida. A esperar que se haga
}

//CONTADOR A MITAD DE SegToMkt INTENTAMOS ENTRAR AL ÚLTIMO PRECIO DISPONIBLE (LAST)
if( intento == 1 AND Contador == int(SegToMkt/2) AND EntryID != "") 
{
//ENTRADA Y STOP LOSS
ibc.ModifyOrder( EntryID, tib, "SELL", Ctos, "LMT", LastValue(C), 0, "DAY", Transmit, tickIB); //COMPRA A LMT
StaticVarSet("Intento"+Name(), 2, True); //SEGUNDO INTENTO
Say("Uy!");
}
//CONTADOR A SegToMkt ENTRAMOS A MERCADO
if(  Intento == 2 AND Contador == SegToMkt AND EntryID != "") 
{
//ENTRADA Y STOP LOSS
ibc.ModifyOrder( EntryID, tib, "SELL", Ctos, "MKT", 0, 0, "DAY", transmit); //CORTO A MERCADO
StaticVarSet("Intento"+Name(), 3, True); //TERCER INTENTO
}

//SI SE HIZO LA ENTRADA Y YA TENEMOS EL PRECIO ENTONCES RESETEAMOS INTENTOS, PONEMOS STOPS, ETC
PrecioEntry = Nz(ibc.GetPositionInfo( tib, "Avg. cost") / PointValue); //mayor que cero cuando lea del Ibc
if ( ibc.GetStatus( EntryID, True ) == "Filled" AND StopID == "" AND PrecioEntry > 0)  
{
//RESETEAMOS INTENTOS
StaticVarSet("Intento"+Name(), 0, True); 

//SI GIRADO CON DOBLE DE CONTRATOS ENTONCES VOLVEMOS A NORMALIDAD
if( MP == -2 ) StaticVarSet("Ctos"+Name(), Ctos/2, True);

//PONEMOS STOP Y TARGET
PopupWindow(NumToStr(ATR(10)),"ATR10",60);
Ctos = StaticVarGet("Ctos"+Name()); 
Stop = Redondea( LastValue(PrecioEntry + NStop*ATR(10)) );
Objetivo = Redondea( LastValue(PrecioEntry - NTarget*ATR(10)) );
StopID = ibc.PlaceOrder( tib, "BUY", Ctos, "STP", 0, Stop, "GTC", transmit, tickIB, "outsideRTH","","456"); //stop loss
TargetID = ibc.PlaceOrder( tib, "BUY", Ctos, "LMT", Objetivo, 0, "GTC", transmit, tickIB, "","","456"); //target
StaticVarSetText("StopID"+Name(), StopID, True); //almacenamos el ID del stop loss
StaticVarSetText("TargetID"+Name(), TargetID, True); //almacenamos el ID del Target
StaticVarSet("PrecioEntry"+Name(), PrecioEntry, True); //almacenamos el precio de entrada
StaticVarSet("PrecioStop"+Name(), Stop, True); //almacenamos el precio de SL
StaticVarSet("PrecioTarget"+Name(), Objetivo, True); //almacenamos el precio de Target
Say("Vendido");
}

//PINTAMOS EL PRECIO DE ENTRADA COMO UNA LÍNEA GRIS
Plot( IIf(PrecioEntry > 0,  ShowLastDay( PrecioEntry ), Null), "PrecioEntry", colorLightGrey, styleThick  );

//BREAKEVEN CUANDO GANE EL DOBLE DEL STOP
ActivarBEshort = LastValue(C) < PrecioEntry + 2*(PrecioEntry - PrecioStop);
if ( !StopID == "" AND ActivarBEshort AND MP > -4 )
{
ibc.ModifyOrder( StopID, tib, "BUY", Ctos, "STP", 0, Redondea( PrecioEntry ), 
"GTC", transmit, tickIB, "outsideRTH"); //stop loss
StaticVarSet("PrecioStop"+Name(), Redondea( PrecioEntry ), True); //almacenamos el stop
StaticVarSet("MP"+Name(), -4, True);
Say("He bajado el stop al precio del corto");
}

//SI SE HIZO EL STOP EN LA 1A ENTRADA PUEDE VOLVER A ENTRAR PERO EN SENTIDO CONTRARIO
HechoStop = ibc.GetStatus( StopID, True ) == "Filled";
if ( !EntryID == "" AND HechoStop AND MP == -1 )  
{
ResetearVariables(); //para que pueda volver a entrar
StaticVarSet("MP"+Name(), 3, True); //MP = 3 es girado a alcista después de un stop loss
}

} //if bajista

} //is connected

//SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
//SSSSSSSSSSSSSSSSSSSSSSSS  VARIABLES EN PANTALLA SSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
//SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

//LEER Net Account Value
NAV = StrToNum(ibc.GetAccountValue( "NetLiquidationByCurrency"));

//GANANCIA EN TIEMPO REAL
Ganancia = IIf(PrecioEntry > 0, sign(MP)*( LastValue(C) - PrecioEntry )*Ctos*PointValue, 0);

//GANANCIAS Y PÉRDIDAS DIARIAS
dailyPnL = StrToNum(ibc.GetAccountValue("UnrealizedPNL")) + StrToNum(ibc.GetAccountValue( "RealizedPnL"));

//GANANCIAS EN VERDE Y PÉRDIDAS EN ROJO
color1 = IIf(ganancia >= 0, colorGreen, colorRed);
color2 = IIf(dailyPnL >= 0, colorGreen, colorRed);

//TENDENCIA CON COLOR
color3 = IIf( MP > 0, colorGreen, IIf(MP < 0, colorRed, colorBlue));

//CONTADOR EN MINUTOS Y SEGUNDOS
minutos = int(Contador/60);
segundos = Contador % 60;

//si aún no hay entrada indicamos el último precio en el visor
UltPrecio = IIf( PrecioEntry > 0, PrecioEntry, C);

//PRECIO AL QUE ENTRA EL BREAKEVEN (GANANCIA DOBLE DEL STOP)
PrecioBE = PrecioEntry + 2*(PrecioEntry-PrecioStop);

//PINTAMOS EL BREAKEVEN
Plot( IIf(PrecioEntry > 0, ShowLastDay( PrecioBE ), Null), "PrecioBE", colorBrown, styleLine  );

//visualizamos las variables en el chart
decim = 1 + dec/10; //decimales formato WriteVal
Title = Title + "\n" + EncodeColor(colorBlue) + tib
+ "\n" + EncodeColor(colorGrey50) + "Rango = " + WriteVal(Rango, decim) + " ($" + WriteVal(rango*PointValue, 1.0) + ")"
+ "\n" + EncodeColor(colorGrey50) + "SL = $" + WriteVal(abs(UltPrecio - PrecioStop)*Ctos*PointValue,1)
+ " ;" + EncodeColor(colorGrey50) + "Target = $" + WriteVal(abs(UltPrecio - PrecioTarget)*Ctos*PointValue,1)
+ "\n" + EncodeColor(colorGrey50) + "BuyStop = " + BuyStop
+ "\n" + "SellStop = " + SellStop
+ "\n" + WriteIf(BED,"BUY EASY","SELL EASY")
+ "\n" + EncodeColor(colorGrey40) + "----------------------------"
+ "\n" + EncodeColor(colorBlack) + "PrecioEntry = " + UltPrecio + "; Ctos = " + WriteVal(Ctos,1)
+ "\n" + "HoraEntrada = " + DateTimeToStr(OrderTime,5)
+ "\n" + EncodeColor(color1) + "Position P&L = " +  WriteVal(ganancia, 1.0)
+ "\n" + EncodeColor(colorGreen) + "----------------------------------"
+ "\n" + "Intento = " + StaticVarGet("Intento"+Name()) + "; ( " + minutos + ":" + segundos + " )"
+ "\n" + EncodeColor(colorBlue) + "--------------------------------------"
//+ "\n" + "NAV = " + WriteVal( NAV, 1.0) + "; DailyPNL = " + EncodeColor(color2) + WriteVal( dailyPnL, 1.0)
+ "\n" + EncodeColor(colorBlue) + "EntryID = " + EntryID + "; StopID = " + StopID  + "; TargetID = " + TargetID  
+ "\n" + "PrecioStop = " + WriteVal(PrecioStop, decim)
+ "\n" + "PrecioBE = " + WriteVal(PrecioBE, decim)
+ "\n" + "PrecioTarget = " + WriteVal(PrecioTarget, decim)
+ "\n" + EncodeColor(Color3) + "MarketPos  = "  + WriteVal(MP,1)
+ "\n" + EncodeColor(colorGrey40) + "----------------------------"
+ "\n" + StrExtract( ibc.GetPositionList(), 0 );
} // si autotrading
//AVISAR SI LA VOLATILIDAD ES EXCESIVA
if( SelectedValue(VolatOK) == False )
{
GfxSetBkColor( colorGold); GfxSelectFont( "Tahoma", 15 );   
GfxSetBkMode( 2 ); GfxTextOut("VOLAT[1] = $" + WriteVal(Volat,1), 40, 900 ); 
}




No hay comentarios:

Publicar un comentario