Una Lección de Trading con Fibonacci

Al menos que yo sepa, no existe en todas las publicaciones que hay en lengua española algo similar a lo que voy a explicar en esta entrada. He empezado enfocando el artículo hacia Fibonacci, pero podría tener cualquier otro enfoque para explicar lo mismo.

Cuando ofreces algo de forma gratuita siempre se desprecia. A las pocas personas a las que les he explicado gratis este asunto no les ha calado, pero supongo que eso también es porque el receptor de esa información no estaba listo para recibirla en ese momento. Luego miramos atrás y nos damos cuenta lo cerca que estuvimos y cómo no lo vimos.

El trading con fibonacci es parte del trading armónico o trading fractal. Yo suelo llamarle trading fractal porque engloba no solo la parte de la armónicos, sino también su propagación en múltiples escalas.

La mayoría de traders que yo conozco no saben hacer trading puramente técnico porque son incapaces de hacerlo en frecuencias temporales de pocos minutos. Existe un límite temporal, pero no está definido en sí por la escala de tiempo, sino por la liquidez instantánea de un mercado. No puedes comprar o vender más de lo que la oferta y la demanda en un momento dado te permiten, nada más.

Hablo, claro, sin tener en cuenta el precio de las operaciones que en mercados donde se negocia la volatilidad, como la bolsa o el mercado de divisas, es necesario operar una volatilidad que dé un rendimiento superior al coste de la operación más el diferencial que haya entre precio de venta y de compra.

El mercado que yo opero, Forex, empieza a ser rentable desde las gráficas de 1 minuto, aunque es mejor operar a partir de 5 minutos como mínimo para reducir la proporción coste-beneficio a un nivel más razonable. Cuando opero opciones binarias no me importa el margen temporal, pues la volatilidad ya no es un factor a tener en cuenta. No obstante, actualmente el mercado de binarias es demasiado complejo como para que sea atractivo, por lo que me voy a centrar exclusivamente en Forex.

Lo primero que vamos a hacer es localizar una vela que tenga un tamaño superior al de las velas próximas. Usaré cualquier par de Forex en cualquier marco temporal en tanto que la acción del precio sea favorable para operar. En general, cuando hay velas consecutivas del mismo tipo (bajistas o alcistas) se han de considerar como un solo movimiento, por lo que no se operarán de forma individual, sino en conjunto. Esto influye en el tiempo esperado para que la operación concluya. Por ejemplo, si operamos un grupo de 4 velas bajistas consecutivas de 5 minutos, estamos operando realmente en el marco temporal de 20 minutos. Si fueran 5 velas diarias, en el marco temporal de 1 semana. Si operamos la gráfica de 70 ticks pues lo mismo, ya que estas técnicas son universales en cuanto a tipo de gráficas y marcos temporales. Es pues crucial determinar bien el setup o estructura de precios que vamos a negociar para estimar el tiempo aproximado de finalización y la volatilidad que vamos a soportar.

Operar Fibonacci por niveles es una lotería. Así que vamos a buscar algo más. Nos vamos a centrar en los niveles 62,8 y 50. Y vamos a mirar al pasado reciente para comprobar si en alguno de esos niveles, el precio reaccionó de forma notable.

Si el precio, en general, iba como Pepe por su casa en un nivel determinado, entonces lo vamos a ignorar, pero si vemos que el precio era rechazado y obligado a volver en dirección contraria habitualmente, entonces lo consideraremos un punto de entrada de alta probabilidad. Ésa es la diferencia entre operar como si jugáramos a la ruleta rusa o como si fuéramos traders de verdad.

Es importante no operar durante la emisión de noticias macroeconómicas porque esta técnica no funciona entre los minutos previos y posteriores a las mismas. También es recomendable usar niveles de stop loss para salir de las operaciones si hemos calculado mal la entrada, pues no hacerlo puede producir un nivel de pérdida importante o incluso la bancarrota en una sola operación.

A continuación voy a lanzar mi plataforma de trading y a capturar una o dos operaciones como ejemplo. Invito a quien lea este artículo a que realice este ejercicio con datos históricos y revise muchas gráficas hasta que dé con las mejores condiciones para aplicarlo. El uso de niveles de Fibonacci, así como del de Ichimuko son realmente muletas temporales hasta que uno empieza a entender el mercado, momento en el cual ya no son necesarios nunca más.

En la imagen siguiente, he marcado algunos niveles donde existe una notable resistencia a que el precio traspase dichas líneas.

Estos niveles son buenos candidatos para operar Fibonacci al haber sido puntos de inflexión en el pasado.

Vamos a centrar ahora mismo la operación a una vela solo. Para ello tenemos que trazar el nivel de Fibonacci adecuado. Si miramos la gráfica, la última vela cerrada es verde, pero tiene una mecha bastante larga arriba, por lo que el precio podemos decir que ha sido rechazado desde ese nivel.

Pues bien, voy a trazar los niveles tomando como referencia la vela que considere que es la que está proporcionando el momento al precio actual. En este caso, considero que el precio está reaccionando a una resistencia, por lo que el momento es bajista, así que voy a buscar el rango bajista en el que debería de operar.

Al estar reaccionando el precio de arria hacia abajo, la acción es sobre una resistencia, por lo que tenemos que reflejar el momento bajista y sus niveles.

Ante la típica pregunta de cómo definir los niveles de Fibonacci, cualquier rango es válido, así que marco uno que considero que puede resolverse en una magnitud de tiempo del orden de la unidad de vela, es decir por debajo de 10 veces ese orden por decir algo.

Veamos desde más cerca la situación:

La acción del precio muestra cómo la vela ha rebotado en el nivel 38.2 hasta por debajo del 23.6. La resistencia más cercana es el nivel 23.6 y el soporte más cercano el 0%.

Dado que el precio ya ha testeado el nivel 38.2 de Fibonacci, es de esperar a que, si estamos operando a la baja, el siguiente máximo sea más bajo que el anterior y el siguiente mínimo también lo sea. Así que vamos a entrar cerca del nivel 23.6 y salir cerca del siguiente nivel inferior de Fibonacci, el 0%.

Aunque es probable que se vuelva a testear el nivel 23.6, ya que este tutorial es estático, voy a introducir una orden de venta en el sistema y ver qué sucede. Ahora mismo ignoro qué sucederá, por lo que es posible que tenga que ampliar el artículo si el precio rompe el SL.

Como el precio sigue en resistencia, vendemos a pesar de que puede subir un poco aún antes de bajar hasta el siguiente soporte.

La venta está ya abierta, el SL está situado por encima del nivel máximo que debería de servir de resistencia actual. Si el precio sobrepasa dicho nivel es que la estructura sobre la que operamos no se estaba desarrollando en este momento y debemos salir inmediatamente.

La reacción del precio parece favorable, al estar formándose una resistencia en el nivel de Fibonacci.

Observamos cómo el precio, en efecto sube hasta el nivel 23.6 y empieza a completar el momento bajista. No hay que esperar hasta justo el nivel exacto de salida, es mejor salir unos pips por arriba para asegurarse la operación. Esperaremos a que baje un poco más para salir. En este caso, dado que estoy escribiendo un tutorial, salgo cuando el precio ha recorrido más del 80%-90% del rango. Es muy posible que complete en una o dos velas máximo el nivel, pero no quiero arriesgarme y tener que alargar innecesariamente el artículo; pues es mucho más claro explicar cómo operar en una vela que interpretar subsiguientes reacciones del precio.

Ya casi en el nivel 0 de Fibonacci, cerramos la venta tras haber el precio recorrido un nivel casi por completo.

Siempre es bueno asegurar beneficios conforme se opera, pues el tiempo necesario que puede suponer no cerrar un poco antes puede ser mucho mayor que el porcentaje de beneficio a recibir a cambio de dicha espera. En este caso, la vela finalmente cerró en contra de la operación, por lo que al haber cerrado un poco antes nos salvó de una situación bastante comprometida.

La vela cerró con un patrón alcista, por lo que el momento ha cambiado de repente y ahora es incierto cuándo el momento bajista se retomará.

Como conclusión, decir que el trading no es tan obvio como a veces se explica, pero que siempre es lógico y sus principios son claros y sencillos de entender.

En este ejercicio se detalla con bastante precisión la motivación detrás de cada paso dado para definir una estructura de negociación, el retroceso de Fibonacci, y cómo se opera para asegurar siempre la negociación dentro de los máximos niveles de probabilidad posibles mediante la búsqueda de una serie de convergencias técnicas.

El autor de este artículo ofrece a quien lo desee tutoriales de trading privados en primera persona bajo presupuesto o por horas sueltas. El coste aproximado para cubrir la materia y entender los puntos básicos rondaría los 12,000€ (doce mil) dadas dos semanas de sesiones de unas 5 horas cada día para una persona ya iniciada en el análisis técnico.

Si tienes interés por aprender más sobre el mismo, puedes enviar un mensaje mediante el formulario de contacto o dejar un comentario. Como el trading no es adecuado para la mayoría de personas, solo se atiende a solicitantes que tengan un nivel de conocimientos o experiencia equivalentes a un grado en Administración de Empresas, Medicina, Filosofía o Magisterio y excelente gramática. No se requiere titulación, solo es un nivel cultural y capacidades de aprendizaje y comprensión de referencia. Si tienes un nivel equivalente pero con muy buen expediente en Psicología, Ingeniería Superior, Matemáticas, Física, Estadística o similar tienes más bastantes posibilidades que el resto.

En cualquier caso, las probabilidades de aprender con éxito trading son inferiores al 10%-20% en promedio, conllevan del orden de un año de preparación casi en solitario y suponen una inversión de tiempo y dinero notables. Los resultados dependen en gran medida del individuo y de su buena gestión monetaria y psicológica.

Predicting Stock Exchange Prices with Machine Learning

This article will describe how to get an average 75% prediction accuracy in next day’s average price change. The target magnitude is the 2-day simple moving average. The reason is that if we do not apply smoothing to daily prices, the forecasts are much harder to get. The minimum possible smoothing is two days, and that will be the target: altering actual prices as little as possible.

I have selected randomly a company from the New York Stock Exchange, it was «CNH Industrial NV». No reason for that, it has been a completely random choice among a couple thousand files I have generated extracted from either Yahoo! or Google finance, I do not remember the source. The files are uploaded here: https://drive.google.com/open?id=18DkJeCqpibKdR8ezwk9hGjdHYSGwovWH.

The method is valid for any financial data as long as it has the same structure. I have also tested it with Forex data getting similar accuracy levels with currencies such as EURUSD, GBPUSD or USDJPY. The interesting point of forecasting those quotes is that by examining where it fails, I think you will improve your price action trading skills and your understanding of the market and what matters.

Data Collection and Variable Configuration

There are millions of possible variable candidates that may seem valid to be analyzed. And which will be the target value we will try to aim? I like thinking that price is like any other object subject to physical laws. It reacts to market forces, it has an inertia, velocity, acceleration, etc.

The forces may be volume, it may have a potential energy depending if it is very high or very low, the rate of change may be important and so on. There are other many factors we could analyze such as gaps, breakouts, technical patterns, candlestick analysis or price distribution within space just to mention a few. For this example we will only be focused on price action and volume.

I have the files saved in csv format to be used with Excel, so let’s start loading the csv file into a DataFrame object using Python.

# Importing all the libraries that we will use.
 
import pandas as pd
import matplotlib.pyplot as plt
import xgboost as xgb
from sklearn.metrics import accuracy_score
 
#Load the data from a csv file.
CNHI = {"stock_name":"CNH Industrial NV", "data": pd.read_csv("./data/CNHI_excel.csv",sep="\t",header=0,decimal=',')}
 
CNHI["data"]=CNHI["data"].drop("Adj Close",1).set_index("Date")

The previous code will, after extracting, remove a column that won’t be used («Adj Close») and creating an index using the «Date» column. The date is not a variable we may use for forecasting, so there is no need to keep it as a column of the dataset.

The data now has the typical structure of the financial data: Date, Open, High, Low and Close. The first three rows are shown in the next table:

Date Open High Low Close Volume
2013-09-30 2.75 13.08 12.5 12.5 352800
2013-10-01 12.76 13.16 12.75 12.92 1477900
2013-10-02 13.02 13.08 12.87 12.9 1631900

Predictors

We are going to omit High, Low and Open, using only Open and Volume for the study. Let’s start preparing the data for the analysis. The predictors (X variables) to be used to predict the target magnitued (y variable) will be the following ones:

  • Two day simple moving average (SMA2). The formula is (Ct – Ct-1)/2, being Ct equal to current day’s open price and Ct-1 to previous day’s open price. This formula is applied to each row of the data set.
Predictors = pd.DataFrame({"sma2":CNHI["data"].Open.rolling(window=2).mean()})
  • 1 day window SMA2. The previous day’s SMA2 value.
Predictors["sma2_1"] = Predictors.sma2.shift(1)

And the other predictors will be:

  • Current day SMA2 increment. (SMA2t – SMA2t-1).
  • 1 day window SMA2 increment. (SMA2t-1 – SMA2t-2).
  • Current day volume increment. (Volt – Volt-1).
  • Current day volume rate of change. (Volt – Volt-1)/Volt
  • 1 day window open price. (Ct-1)
  • Current day open price increment. Ct – Ct-1
  • Current day open price. Ct.
Predictors["sma2_increment"] = Predictors.sma2.diff()  
 
Predictors["sma2_1_increment"] = Predictors.sma2_1.diff()  
 
Predictors["vol_increment"] = CNHI["data"].Volume.diff()
 
Predictors["vol_rel_increment"] = CNHI["data"].Volume.diff() / CNHI["data"].Volume
 
Predictors["open_1"] = CNHI["data"].Open.shift(1)
 
Predictors["open_incr"] = CNHI["data"].Open - CNHI["data"].Open.shift(1)
 
Predictors["open"] = CNHI["data"].Open
 
# The rows with nulls generated by rolling values will be removed.
Predictors = Predictors.dropna()

A sample of the first 5 rows:

Date sma2 sma2_1 sma2_increment sma2_1_increment vol_increment vol_rel_increment open_1 open_incr open
2013-10-03 12.895 12.89 0.005 0.135 -495500 -0.436026047 13.02 -0.25 12.77
2013-10-04 12.765 12.895 -0.13 0.005 -21800 -0.019558586 12.77 -0.01 12.76
2013-10-07 12.59 12.765 -0.175 -0.13 -400 -0.000359002 12.76 -0.34 12.42
2013-10-08 12.42 12.59 -0.17 -0.175 104600 0.08582212 12.42 0 12.42
2013-10-09 12.5 12.42 0.08 -0.17 -232400 -0.235604217 12.42 0.16 12.58

 

Target Variable

This will be a classification variable, if the average price will go either up or down the next day.  The target will be forecasting the difference between today’s price and tomorrow’s price (which is unkonwn).

target = pd.DataFrame({"value":Predictors.sma2.shift(-1) - Predictors.sma2}).dropna()

After calculating the data to predict, the three first rows look like this:

Date value
2013-10-03 -0.13
2013-10-04 -0.175
2013-10-07 -0.17

Finally we will match predictors and target values by date and remove those rows without counterpart in the other table.

X = pd.merge(Predictors, target,left_index=True,right_index=True)[Predictors.columns]
y = pd.merge(Predictors, target,left_index=True,right_index=True)[target.columns]

X now contains the predictors and y the target values. The table contains 1,059 records at this moment.

Extreme Gradient Boosting prediction

The extreme gradient boosting is an exceptional machine learning technique for many reasons. It is based on decision trees and it has nice features such as residuals analysis, non-linear regression, feature selection tools, overfitting avoidance and many other more. Other machine learning alternative techniques commonly used for this type of analysis are Support Vector Machines, Neural Networks and Random Forest. I have used all of those for predicting market prices and the Extreme Gradient Boosting is always my first choice.

We will setup the regression model using the 65% of the data and with that model, the next 35% of the data will be used to predict future values. This simulates the actual scenario in which we have past data to train our model and we want to predict how a future datum will be with the data we currently have on hand. The data will be split in two sets: the training set to preconfigure the model and the testing set that won’t be used to build the model, but only to test if it works as expected with new data.

train_samples = int(X.shape[0] * 0.65)
 
X_train = X.iloc[:train_samples]
X_test = X.iloc[train_samples:]
 
y_train = y.iloc[:train_samples]
y_test = y.iloc[train_samples:]

After applying the data splitting, the test data set contains:

  • Train records: 688.
  • Test records: 371.

The target variables will be transformed for binary classification. A positive change in the value of prices will be classified as 1 and a non-positive change as 0.

def getBinary(val):
    if val>0:
        return 1
    else:
        return 0
 
# and the transformation is applied on the test data for later use.
# The train data will be transformed while it is being fit.
y_test_binary = pd.DataFrame(y_test["value"].apply(getBinary)

And next, the model is trained and the test data predicted to verify the accuracy of the system:

regressor = xgb.XGBRegressor(gamma=0.0,n_estimators=150,base_score=0.7,colsample_bytree=1,learning_rate=0.01)
 
xgbModel = regressor.fit(X_train,y_train.value.apply(getBinary))
 
y_predicted = xgbModel.predict(X_test)
y_predicted_binary = [1 if yp >=0.5 else 0 for yp in y_predicted]
 
print (accuracy_score(y_test_binary,y_predicted_binary))
 
 
Out: 0.76010781671159033

So, the initial accuracy without optimizing the model is 76% predicting the daily average price change for each of the the next 371 trading days.

The model can be optimized, I have just used a few parameters to avoid overfitting with the training data and adjusting the learning rate.

The features used should also be analyzed to avoid using redundant variables and to discard those with no correlation. New features should be added to try improved approaches and, to sum up, there is a lot of work that could be done around this basic model.

XGBOOST has also ways to study features. Let’s take a look at their importance:

fig = plt.figure(figsize=(8,8))
plt.xticks(rotation='vertical')
plt.bar([i for i in range(len(xgbModel.feature_importances_))], xgbModel.feature_importances_.tolist(), tick_label=X_test.columns, color="chocolate")
plt.show()

It is obvious that the field extension is huge and especially interesting.