Sistemas basados en Sheldon Knight y William Brower Research

Nov 11, 2022 | EasyLanguage, TradeStation

Sistemas basados en Sheldon Knight y William Brower Research

En esta publicación sobre Easylanguage, vamos a dar nuestro punto de vista sobre el famoso estadístico y trader Sheldon Knight y su K-DATA. En esta línea de tiempo vamos a utilizar la siguiente nomenclatura:

  • El primer lunes de diciembre =1MonDec
  • El segundo viernes de abril = 2FriApr
  • Tercer miércoles de marzo= 3Wedmar

Esta enumeración o codificación se utilizó para determinar si una semana del mes y del día de la semana guardaban relación con la tendencia estacional. De igual manera, si conoces este tipo de índices es que alguna vez habrás trabajado con Witching Days.

Cuatro veces al año, los contratos de opciones sobre acciones, acerca de índices bursátiles y futuros sobre índices bursátiles vencen el mismo día, lo que da como resultado volúmenes y una volatilidad de precios más altos. Por esta razón, el mercado de valores puede parecer extraño y complicado para muchas personas y esto es lo que se conoce como «días triples de brujas».

La triple hora bruja, por lo general, ocurre el tercer viernes del último mes del trimestre. Eso significa el tercer viernes de marzo, junio, septiembre y diciembre. En 2022, la triple hora bruja son el 18 de marzo, el 17 de junio, el 16 de septiembre y el 16 de diciembre por las razones previamente expuestas.

Siguiendo esta misma línea, también hay otros días de algunos meses que tienen su significado. Como es el caso del primer viernes de cada mes (situación laboral), tienen aún más significado. En 1996, Bill Brower escribió un excelente artículo en Análisis técnico de acciones y materias primas. El título del artículo era The S&P 500 Seasonal Day Trade. En este artículo, Bill ideó 8 patrones comerciales diarios muy simples y luego los filtró con el día de la semana en el mes. Aquí están los ocho patrones tal como los expuso en el artículo:

  1. Patrón1: si la apertura de mañana es menos de 30 puntos del cierre de hoy, compra.
  2. Patrón 2: si es 30 puntos menos que el cierre de hoy, no compres.
  3. Patrón 3: si la apertura de mañana menos 30 puntos es mayor que el cierre de hoy, entonces vende en el mercado.
  4. Patrón 4: si es mayor de 30 puntos entonces debes vender en el mercado al descubierto.
  5. Patrón 5: si la apertura de mañana más 10 es menor que el mínimo de hoy, entonces compra en el mercado.
  6. Patrón 6: si la apertura es menor de 20 puntos, entonces vende al descubierto en el stop del cierre de hoy.
  7. Patrón 7: si la apertura de mañana es menor de 40 puntos del cierre de hoy, compra en el límite mínimo de hoy.
  8. Patrón 8: si la apertura es más de 70 puntos con respecto al cierre de hoy, entonces vende al descubierto en el límite alto hoy.

Este artículo fue escrito hace casi 27 años cuando 30 puntos significaban algo en el contrato de futuros S&P. Dicha empresa cotizaba alrededor de 600.000. Hoy por hoy, el e-mini cotiza alrededor de 4000.000 y ha sido más alto, por lo que hablar de 30,40 o70 puntos no tiene sentido.

Por esta razón, hemos decidido crear un porcentaje de ATR, lo que quiere decir que si el rango es igual a 112,00 mangos y usamos el 5%, entonces la base equivaldría a 11200 = 560 puntos. Usando la lógica, si utilizamos el 1% y el 5% de ATR, se podría reemplazar los valores de puntos de Bill.

Por ende, la sintaxis de Bill es diferente a cómo se han descrito los patrones y es fácil poder ver una brecha de más de 30 puntos, pero recuerda, hay más de una forma de programar una idea.

Sigamos con la sintaxis de Bill:

  • 10 puntos = 1 X(Mult) X ATR
  • 20 puntos = 2 X(Mult) X ATR
  • 30 puntos = 3 X(Mult) X ATR
  • 40 puntos = 4 X(Mult) X ATR
  • 50 puntos = 5 X(Mult) X ATR
  • 70 puntos =7 X(Mult) X ATR

 

A continuación, podemos jugar con Mult para ver si somos capaces de simular niveles similares de 1996.


// atrMult will be a small percentage like 0.01 or 0.05 atrVal = avgTrueRange(atrLen) * atrMult; //original patterns //use IFF function to either returne a 1 or a 0 //1 pattern is true or 0 it is false patt1 = iff(open of tomorrow - 3 * atrVal > c,1,0); patt2 = iff(open of tomorrow + 3 * atrVal < c,1,0); patt3 = iff(open of tomorrow - 3 * atrVal > c,1,0); patt4 = iff(open of tomorrow + 3 * atrVal < c,1,0); patt5 = iff(open of tomorrow + 1 * atrVal < l,1,0); patt6 = iff(open of tomorrow - 2 * atrVal > h,1,0); patt7 = iff(open of tomorrow - 4 * atrVal > c,1,0); patt8 = iff(open of tomorrow + 7 * atrVal < c,1,0);

 

Nov22Post1

 

Siguiendo esta misma línea, el día de la semana en un mes se representa con un número de dos dígitos. El primer dígito es el rango de la semana y el segundo número es el día de la semana. Pensé que esto era muy inteligente, así que decidí programarlo. Lo abordé desde un par de ángulos diferentes y, de hecho, codifiqué un método de codificación que incluía el rango de la semana, el día de la semana y el mes (1stWedJan) en mi edición de alta resolución. La versión de Bill no necesitaba ser tan sofisticada y como decidí usar las capacidades de optimización de TradeStation, no necesitaba crear una estructura de datos para almacenar ningún dato.

Por otro lado, NewMonth se establece en falso en cada barra. Si el día del mes de mañana es menor que el día del mes de hoy, entonces sabemos que tenemos un nuevo mes y newMonth se establece en verdadero. Si tenemos un nuevo mes, suceden varias cosas: reinicializar el código que cuenta el número lunes, martes, miércoles, jueves y viernes a 0 (no se usa para esta aplicación, pero se puede usar más adelante) y configurar el conteo de semanas weekCnt a 1. Si no es un mes nuevo y el día de la semana de mañana es menor que el día de la semana de hoy (lunes = 1 y viernes = 5, si mañana es menor que hoy (1 < 5)) entonces debemos tener una nueva semana en el bar de mañana. Codificar el día de la semana en un mes como un número de dos dígitos es bastante fácil: simplemente multiplique el rango de la semana (o cuente) por 10 y agregue el día de la semana (1-lunes, 2-martes,…) Entonces el tercer miércoles sería igual a 3X10+3 o 33.

Use la optimización para pasar por 8 patrones y 25 días de la semana en encuestas mensuales

Recorrer los 8 patrones es bastante sencillo. Sin embargo, pasar por los 25 posibles códigos o enumeraciones de DowInAMonth es más complejo. Muchas veces puedes usar una ecuación basada en el proceso iterativo de ir de 1 a 25. Este es un ejemplo perfecto de cómo reemplazar las matemáticas con código de ordenador.

newMonth = False;
newMonth = dayOfMonth(d of tomorrow) < dayOfMonth(d of today);
atrVal = avgTrueRange(atrLen) * atrMult;
if newMonth then
begin
	startTrading = True;
	monCnt = 0;
	tueCnt = 0;
	wedCnt = 0;
	thuCnt = 0;
	friCnt = 0;
	weekCnt = 1;
end;

if not(newMonth) and dayOfWeek(d of tomorrow) < dayOfWeek(d of today) then
	weekCnt +=1;

dayOfWeekInMonth = weekCnt * 10 + dayOfWeek(d of tomorrow);

De igual manera, aquí estamos activando la entrada (dowInMonthInc). Recordad que este valor irá de 1 a 25 en incrementos de 1. Lo que es realmente genial acerca de la implementación de Switch-Case de EasyLanguage es que pueden manejar rangos. Si dowInMonthInc resulta ser 4, caerá dentro del primer bloque de casos (caso 1 a 5). Aquí sabemos que si este valor es menor que 6, entonces estamos en la primera semana, así que configuré el primer número en la representación de dos dígitos dayOfWeekInMonth en 1. Esto se logra configurando value3 en 10. Ahora necesita extraer el día de la semana del bucle 1 al 25. Si dowInMonthInc es menor que 6, todo lo que necesitas hacer es usar la función de módulo y el valor 6.

  • mod(1,6) = 1
  • mod(2,6) = 2
  • mod(3,6) = 3

Esto funciona muy bien cuando el valor de incremento es inferior a 6. Recuerda:

  • 1 -> 11 (primer lunes)
  • 2 -> 12 (primer martes)
  • 3 -> 13 (primer miércoles)
  • 6 -> 21 (segundo lunes)
  • 7 -> 22 (segundo martes).

Entonces, tienes que ser un poco creativo con tu código. Supón que el valor iterativo es 8. Necesitamos que 8 sea igual a 23 (segundo miércoles). Este valor cae en el segundo caso, por lo que Value3 = 20 la segunda semana del mes. Eso es bastante fácil. Ahora necesitamos extraer el día de la semana. Recuerde que esta es solo una solución, le garantizo que hay muchas.

mod(dowInMonthInc – 5, 6) – ¿funciona?

valor2 = mod(8-5,6) = 3 -> valor3 = valor1 + valor2 -> valor3 = 23. Funcionó. ¿Ves el patrón de abajo?

  • caso 6 a 10 – mod(dowInMonthInc – 5, 6)
  • caso 11 a 15 – mod(dowInMonthInc – 10, 6)
  • caso 16 a 20- mod(dowInMonthInc – 15, 6)
  • caso 21 a 25 – mod(dowInMonthInc – 20, 6)

Nov22Post3

Guarde el informe de optimización como texto y ábralo con Excel

Nov22Post2

Estas son las configuraciones que usé para crear el siguiente informe. Si haces los cálculos, es un total de 200 interacciones.

inputs: atrLen(10),atrMult(.05),patternNum(1),dowInMonthInc(1);

vars: patt1(0),patt2(0),patt3(0),patt4(0),
patt5(0),patt6(0),patt7(0),patt8(0);

vars: atrVal(0),dayOfWeekInMonth(0),startTrading(false),newMonth(False);;

vars: monCnt(0),tueCnt(0),wedCnt(0),thuCnt(0),friCnt(0),weekCnt(0);


newMonth = False;
newMonth = dayOfMonth(d of tomorrow) < dayOfMonth(d of today);
atrVal = avgTrueRange(atrLen) * atrMult;
if newMonth then
begin
	startTrading = True;
	monCnt = 0;
	tueCnt = 0;
	wedCnt = 0;
	thuCnt = 0;
	friCnt = 0;
	weekCnt = 1;
end;

if not(newMonth) and dayOfWeek(d of tomorrow) < dayOfWeek(d of today) then
	weekCnt +=1;

dayOfWeekInMonth = weekCnt * 10 + dayOfWeek(d of tomorrow);	


//print(date," ", dayOfMonth(d)," " ,dayOfWeek(d)," ",weekCnt," ",monCnt," ",dayOfWeekInMonth);


//original patterns

patt1 = iff(open of tomorrow - 3 * atrVal > c,1,0);
patt2 = iff(open of tomorrow + 3 * atrVal < c,1,0);
patt3 = iff(open of tomorrow - 3 * atrVal > c,1,0);
patt4 = iff(open of tomorrow + 3 * atrVal < c,1,0);
patt5 = iff(open of tomorrow + 1 * atrVal < l,1,0);
patt6 = iff(open of tomorrow - 2 * atrVal > h,1,0);
patt7 = iff(open of tomorrow - 4 * atrVal > c,1,0);
patt8 = iff(open of tomorrow + 7 * atrVal < c,1,0);


switch(dowInMonthInc)
begin
	case 1 to 5:
		value2 =  mod(dowInMonthInc,6);
		value3 = 10;
	case 6 to 10:
		value2 = mod(dowInMonthInc-5,6);
		value3 = 20;
	case 11 to 15:
		value2 = mod(dowInMonthInc-10,6);
		value3 = 30;
	case 16 to 20:
		value2 = mod(dowInMonthInc-15,6);
		value3 = 40;
	case 21 to 25:
		value2 = mod(dowInMonthInc-20,6);
		value3 = 50;
end;

value1 = value3 + value2 ;

//print(d," ",dowInMonthInc," ",dayOfWeekInMonth," ",value1," ",value2," ",value3," ",mod(dowInMonthInc,value2));

if value1 = dayOfWeekInMonth then
begin
	if patternNum = 1 and patt1 = 1 then buy("Patt1") next bar at open;
	if patternNum = 2 and patt2 = 1 then buy("Patt2") next bar at open;
	if patternNum = 3 and patt3 = 1 then sellShort("Patt3") next bar at open;
	if patternNum = 4 and patt4 = 1 then sellShort("Patt4") next bar at open;
	if patternNum = 5 and patt5 = 1 then buy("Patt5") next bar at low limit;
	if patternNum = 6 and patt6 = 1 then sellShort("Patt6") next bar at close stop;
	if patternNum = 7 and patt7 = 1 then buy("Patt7") next bar at low limit;
	if patternNum = 8 and patt8 = 1 then sellShort("Patt8") next bar at high stop;
end;

setExitOnClose;

Para finalizar, me gustaría destacar que este tema podría discurrir en un análisis mucho más profundo, no obstante quiero agradecer a William Brower su excelente artículo The S&P Seasonal Day Trade in Stocks and Commodities, edición de agosto de 1996, V.14:7 (333-337).

Esperemos haya disfrutado y saque provecho a este artículo sobre los istemas basados en Sheldon Knight y William Brower Research.

 

Artículo escrito por George Pruitt

Easylanguage | Sistema de trading: Tortugas

Easylanguage | Sistema de trading: Tortugas

He visto una plétora de publicaciones sobre las estrategias de comercio de tortugas donde se proporcionan las reglas y el código. Los códigos van desde una mera ruptura de Donchian hasta una representación bastante cercana. Sin retroalimentación de...

leer más

Subscribe to our Newsletter

Join our mailing list to receive the latest news and updates from Quantified Models team.

Subscribe to our Newsletter

You have Successfully Subscribed!

Ir al contenido