Hello, how are you?
Based on the book "Trading with Automatic Systems" by Mr. Oscar G. Cagigas, I've tried to develop the "Fugax" system that he talks about on pages 91-94.
I've managed to get it to work more or less well, but the condition of selling at the first opening AFTER THE SECOND DAY is the one that I can't get to work.
Also, I don't see any operation in the backtest that indicates that the Stop Loss is triggered and that seems strange to me.
I'm attaching the AFL file in case someone can help me, and an image of some operation where you can see that it enters on one day and exits the next (not respecting the two-day thing).
/*Nombre sistema: Sistema Fugax FB
Autor: FB
Activos: Acciones Nasdaq 100
Temporalidad: Diaria
Largos/Cortos: Largos y Cortos
Resumen:
/*Sistema Reversal que mide la aceleración del precio mediante unas bandas de aceleración.
El precio suele estar casi siempre dentro de esas bandas pero si se sale de ellas,
nos prepararemos para tomar el sentido contrario.
La tendencia de la MA30 de los cierres del activo elegido y la pendiente de la Recta de Regresión lineal de 20 periodos del SP500
se utilizarán como filtros
Cagigas nos dá estos datos:
// Setup
// El mínimo de hoy queda por debajo de la banda inferior
// La media simple de 30 de los cierres está subiendo (Filtro de Tendencia)
// EL SP500 está subiendo (Pendiente de regresión lineal de los últimos 20 cierres > 0
//
// Buy
// Todas las condiciones del setup ocurrieron ayer
// Hoy se abre por debajo de la banda Lowerband
// Ponemos una orden de compra stop por encima del precio, justo en la banda Lowerband
//
// Sell
// Vendemos en la primera apertura con ganacias después del segundo día. Es decir, que si p.e. entramos un lunes, venderemos en la primera apertrua con ganacias a partri del miércoles inclusive
//
// Stop Loss
// El 5% por debajo del precio de entrada*/
_SECTION_BEGIN("Sistema ");
#include_once "Formulas\Norgate Data\Norgate Data Functions.afl"//Para usar funciones de NorgateData
// 1. TIPO DE SISTEMA [SIEMPRE]
SetBacktestMode( backtestRegular );
// 2. TEMPORALIDAD [SIEMPRE]
//Diaria
// 3. PARÁMETROS DE ENTRADA [OPCIONAL]
NumPos = Optimize("Num. Posiciones",1,1,12,1);
// 4. DETECTAR WATCHLIST (FILTER) [OPCIONAL]
//Nada
// 5. ANALYSIS SETTINGS [SIEMPRE]
SetOption( "InitialEquity", 100000 );
SetOption ("MaxOpenPositions", NumPos);
SetOption ("MaxOpenLong",0);
SetOption("MaxOpenShort",0);
SetOption("SeparateLongShortRank",False);
SetOption ("AllowPositionShrinking", True);
SetOption("CommissionMode", 2);
SetOption ("CommissionAmount", 3.00);
SetOption ("AllowSameBarExit", True);
SetOption ("HoldMinbars", 1);
SetOption ("ReverseSignalForcesExit", False);
SetTradeDelays(0,0,0,0);
SetOption("ActivateStopsImmediately", True);
// 6. REBALANCEO [OPCIONAL]
//Nada
//7. FILTRO DE MERCADO [OPCIONAL]
SP500 = Foreign("$SPX", "Close");
PendienteSP500 = LinRegSlope(SP500, 20);
// 8. TAMAÑO DE LA POSICIÓN [SIEMPRE]
SetPositionSize(100/NumPos, spsPercentOfEquity);
// 9. CÁLCULO INDICADORES [SIEMPRE]
//Bandas de aceleración
Lowerband = MA((L*(1-2*((((H-L)/((H+L)/2))*1000)*0.001))),20);
Higherband = MA((L*(1+2*((((H-L)/((H+L)/2))*1000)*0.001))),20);
//MA30 de los Cierres
MA30=MA(Close,30);
// 10. REGLAS DEL SISTEMA [SIEMPRE]
// Evitar Acciones Deslistadas
dt = DateTime();
bi = BarIndex();
delistedSecurity = Nz(DateTimeDiff(dt, GetFnData("DelistingDate")) >= 0);
barsBeforeDelisting = LastValue(ValueWhen(dt == GetFnData("DelistingDate"), bi, 1)) -bi;
//Que sean accciones constituyentes del índice
Constituyentes_Nasdaq100 = NorgateIndexConstituentTimeSeries("$NDX");
//Evitar Acciones que no quiero
Precio_Minimo = 5;
SharesOut = GetFnData("SharesOut");
Market_Cap = SharesOut*Close; //Nano<50M, Micro 50-300M, Small 200M-2.000M, Med 2.000-10.000M, Large 10.000-200.000M, Mega >200.000M
Vol_Promedio30d = MA(V,30);
Vol_Promedio90d = MA(V,90);
AccionesOK = Precio_Minimo AND Market_Cap >500000000 AND Vol_Promedio30d > 1000000;
//Las condiciones de Compra
C1 = Low < Lowerband;
C2 = MA30>Ref(MA30,-1);
C3 = PendienteSP500 >0;
Setup = C1 AND C2 AND C3;
C4 = Open < Ref(Lowerband,-1);
C5 = High >= Ref(Lowerband,-1);
BuySetup = Ref(Setup, -1) AND C4 AND C5 AND AccionesOK;
Buy = BuySetup;
BuyPrice = Ref(Lowerband,-1);
//Inicialización de variables
priceatbuy = 0; //Se inicializa como 0 para luego almacenar el precio de compra en la primera compra que ocurra
bi = BarIndex(); //Inicializa índice de barra, útil para saber en qué día fue la compra.
nstop = 0.05; //Porcentaje para el stop loss (del 5%) en el bucle
barsSinceEntry = 0; // Variable para contar barras desde la compra
stopprice =0;
//Bucle principal para pasar sobre todas las barras, desde la 0 a la última
for( i = 0; i < BarCount; i++ )
{
//Condición de Compra
if( priceatbuy == 0 && Buy[ i ] ) //Nueva Compra
{
priceatbuy = BuyPrice[ i ]; //Guardar el precio de compra
stopprice = priceatbuy*(1 - nstop); // Calcular el Stop Loss
EntryBar = bi[ i ]; //Guardar Barra de entrada
barsSinceEntry = 0; // Reiniciar contador de barras
}
//Condición de Venta
if( priceatbuy > 0) //Si estamos comprados
{
// Incrementar contador de barras desde la compra
barsSinceEntry++;
//Salida por Ganancias tras dos días como mínimo
if (barsSinceEntry > 3 && Open[ i ] > priceatbuy )
{
Sell[ i ] = 1; // Activar señal de venta
SellPrice[ i ] = Open[i]; // Precio de venta
priceatbuy = 0; // Resetear el precio de compra después de vender
barsSinceEntry = 0; // Resetear contador de barras
}
//Salida por Stop Loss
else if(Low[ i ] < stopprice )
{
Sell[ i ] = 1; // Activar señal de venta por stop loss
SellPrice[ i ] = stopprice; // Precio de venta por stop loss
priceatbuy = 0; // Resetear el precio de compra después de vender
barsSinceEntry = 0; // Resetear contador de barras
}
}
else
{
Sell[ i ] = 0; // Asegurar que Sell solo se activa en las condiciones específicas
}
}
//No hay Cortos
Short = Cover =0;
// 12. TAKEPROFIT [OPCIONAL]
//Nada
// 13. ELIMINAR SEÑALES EXTRAS [OPCIONAL]
Buy = ExRem( Buy, Sell );
Sell = ExRem( Sell, Buy );
// 14. EXPLORADOR [OPCIONAL]
//Nada
// 15. GUARDAR CURVA DE CAPITAL [OPCIONAL]
//Nada
// 16. DIBUJAR INDICADORES EN EL GRÁFICO [OPCIONAL]
// Nada
_SECTION_END();
Thank you very much