In FOREX, both the EURCHF and USDCHF series have outliers that can be a problem when applying Machine Learning techniques to them. So, in this post, the performance of an autoencoder detecting these anomalies is going to be studied.
Analyzing the EURCHF and USDCHF returns, it can be seen that there are days in which there was a very abrupt change in the price. The reasons for this are as follows:
- September 6th, 2011: the Swiss National Bank (SNB) established a minimum exchange rate of 1.20 francs to euro. This was because the value of the franc was considered a threat to the economy.
- January 15th, 2015: the Swiss National Bank said that the minimum exchanged rate that was established in 2011 stopped making sense. Furthermore, the SNB reduced the interest rates from -0.25% to -0.75%.

Working with time series can be a problem in the presence of outliers. As T.Fuertes explains in her post titled “Outliers detection with autoencoder, a neural network”, when using Machine Learning techniques, outliers can make the results be misunderstood. Furthermore, in that post, she explains how to use autoencoders as outliers’ detectors.
Therefore, using quantitative analysis tools on the EURCHF and USDCHF could be a problem. For that reason, this post is going to study the results obtained when using an autoencoder with the purpose of detecting outliers in those series.
Autoencoder
The autoencoder’s aim is to reproduce the input, after reducing its dimension, in the output with a certain error. For that purpose, the neural network has to be trained with normal data (which has not outliers) and then, tested with anomaly data (with outliers). In consequence, the reconstruction error will be higher for anomalous data.
The data that has been chosen for training are the returns of the EURUSD. This implies that the EURUSD is supposed to have no outliers, which is a dangerous assumption, but for this experiment, it can be useful. This is because the outliers of EURUSD are insignificant compared to those in EURCHF and USDCHF.

Implementation
Moreover, the autoencoder that has been used is written in Keras and it is quite simple as can be seen in the following code:
model = Sequential()
model.add(Conv1D(filters=8, kernel_size=5, padding='same', activation='tanh', input_shape=(time_window_size, 1)))
model.add(GlobalMaxPool1D())
model.add(Dense(units=time_window_size, activation='tanh'))
model.compile(optimizer='adam', loss='mean_squared_error')
The input dimension of the autoencoder is defined in the input_shape argument, which is set to time_window_size which is one month. Thus, the neural network will be fed with the returns series using a one-month rolling window. The advantages of using a rolling window will be explained when analyzing the results.
The hidden layer (GlobalMaxPool1D) is in charge of reducing the dimensions, while the output layer has the same dimensions as the input. In this way, the autoencoder is implemented using the adam optimizer, tanh as activation function and the mean squared error as the loss to minimize.
Therefore, before introducing the data into the neural network, they have to be pre-processed. This pre-processing consists of creating the rolling window and scaling the data. The scaler used is the MinMaxScaler of scikit-learn since in this way the outliers are not eliminated.
Once the neural network has been trained, the training reconstruction error is calculated which is the root mean squared error. Moreover, it is calculated using the following formula, where \(\hat{x}_{i}\) is the output and \(x_{i}\) the input.
$$
RMSE =
\sqrt{ \frac{1}{n} \sum_{i=0}^{n} (\hat{x}_{i} – x_{i})^2}$$
After training, the test data (returns of EURCHF and USDCHF) are introduced into the autoencoder. Therefore, in those windows where the test reconstruction error is much higher than the training reconstruction error, an outlier exists. In order to make a comparison between the training and test errors, the following formula is applied.
$$
e_{n} = \frac{e_{test}}{e_{train}}$$
Results
The following graphs show the results. As can be seen, on days when there are outliers in the returns, the reconstruction error is much higher. Therefore, by applying a threshold, the outliers can be detected automatically.

If we zoom-in to the peak of 2015, it can be seen that its duration is one month. This makes sense because that is just the size of the window. Due to this, it is important to use a rolling window. In this way, we are able to detect which specific day the outlier has taken place.

The reconstruction error increases as soon as the outlier enters the rolling window. In addition, after one month, the reconstruction error recovers its normal value. This is just when the outlier leaves the window. Therefore, the outlier can be detected the first time that the reconstruction error is higher.
Conclusion
We have identified outliers using autoencoders in FOREX series. It is very interesting to note that by training the network with the EURUSD, outliers of EURCHF and USDCHF can be detected. However, one question comes to my mind, if there were two outliers in the same window, how would this affect the reconstruction error?