avatarPamela J. Nikodem, MSED

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

6469

Abstract

market dynamics. This is where feature engineering becomes invaluable. By transforming and synthesizing the raw data using established technical indicators, we can provide the model with enriched insights that could explain underlying market patterns and trends. Such enriched data can significantly improve the model’s ability to anticipate future price movements.</p><p id="07ea">For this forecast, we will utilize a couple of technical indicators for our feature engineering like RSI, MACD, Bollinger Bands, Parabolic SAR, and Stochastic Oscillator. Additionally, we introduce lag features to capture temporal dependencies, ensuring our model benefits from both current and historical contexts.</p><p id="f61d"><b>Let’s calculate the features we will utilize in this forecast</b></p><div id="d4ed"><pre><span class="hljs-comment"># Compute RSI</span> df[<span class="hljs-string">'momentum_rsi'</span>] = RSIIndicator(close=df[<span class="hljs-string">'Close'</span>]).rsi()

<span class="hljs-comment"># Compute MACD</span> macd = MACD(close=df[<span class="hljs-string">'Close'</span>]) df[<span class="hljs-string">'trend_macd'</span>] = macd.macd() df[<span class="hljs-string">'trend_macd_signal'</span>] = macd.macd_signal() df[<span class="hljs-string">'trend_macd_diff'</span>] = macd.macd_diff()

<span class="hljs-comment"># Compute Bollinger Bands</span> bollinger = BollingerBands(close=df[<span class="hljs-string">'Close'</span>]) df[<span class="hljs-string">'volatility_bbm'</span>] = bollinger.bollinger_mavg() df[<span class="hljs-string">'volatility_bbl'</span>] = bollinger.bollinger_lband() df[<span class="hljs-string">'volatility_bbh'</span>] = bollinger.bollinger_hband()

<span class="hljs-comment"># Compute Parabolic SAR</span> psar = PSARIndicator(high=df[<span class="hljs-string">'High'</span>], low=df[<span class="hljs-string">'Low'</span>], close=df[<span class="hljs-string">'Close'</span>]) <span class="hljs-comment"># Assuming you have 'High' and 'Low' columns in your df</span> df[<span class="hljs-string">'trend_psar'</span>] = psar.psar()

<span class="hljs-comment"># Compute Stochastic Oscillator</span> stochastic = StochasticOscillator(high=df[<span class="hljs-string">'High'</span>], low=df[<span class="hljs-string">'Low'</span>], close=df[<span class="hljs-string">'Close'</span>]) <span class="hljs-comment"># Assuming you have 'High' and 'Low' columns</span> df[<span class="hljs-string">'momentum_stoch'</span>] = stochastic.stoch() df[<span class="hljs-string">'momentum_stoch_signal'</span>] = stochastic.stoch_signal()

<span class="hljs-comment"># Create Lag Features</span> df[<span class="hljs-string">'Close_Lag1'</span>] = df[<span class="hljs-string">'Close'</span>].shift(<span class="hljs-number">1</span>)

<span class="hljs-comment"># Drop NaN values introduced due to lag features and indicators</span> df = df.dropna()

<span class="hljs-comment"># Define features and target</span> X = df[[<span class="hljs-string">'momentum_rsi'</span>, <span class="hljs-string">'trend_macd'</span>, <span class="hljs-string">'trend_macd_signal'</span>, <span class="hljs-string">'trend_macd_diff'</span>, <span class="hljs-string">'volatility_bbm'</span>, <span class="hljs-string">'volatility_bbl'</span>, <span class="hljs-string">'volatility_bbh'</span>, <span class="hljs-string">'trend_psar'</span>, <span class="hljs-string">'momentum_stoch'</span>, <span class="hljs-string">'momentum_stoch_signal'</span>, <span class="hljs-string">'Close_Lag1'</span>]] y = df[<span class="hljs-string">'Close'</span>]</pre></div><p id="712f">The above code is organizing the dataset <code>df</code> into input features and a target variable for our model. The input features, captured under <code>X</code>, consist of various the features we calculated on and previously defined. The target variable, denoted by <code>y</code>, is the <code>Close</code> column, representing the daily closing price of EUR/USD, which our model aims to predict based on the provided features.</p><p id="bdfb"><b>Model Initialization and Training</b></p><div id="a7d2"><pre><span class="hljs-comment"># Initialize the model</span> model = xgb.XGBRegressor( learning_rate=<span class="hljs-number">0.75</span>, n_estimators=<span class="hljs-number">200</span>, max_depth=<span class="hljs-number">5</span>, subsample=<span class="hljs-number">0.9</span>, colsample_bytree=<span class="hljs-number">0.8</span>, colsample_bylevel=<span class="hljs-number">0.8</span>, gamma=<span class="hljs-number">0</span>, min_child_weight=<span class="hljs-number">1</span> )

<span class="hljs-comment"># Train the model</span> model.fit(X_train, y_train)</pre></div><p id="7ce9">Continuing from the previously discussed data preparation, this section of code dives into the model initialization and training phases using XGBoost. The <code>xgb.XGBRegressor()</code> initializes a regression model with specified hyperparameters to optimize the forecast. Key parameters include a learning rate of <code>0.75</code>, which determines the step size at each iteration while optimizing, <code>200</code> estimators or trees, and a maximum depth of <code>5</code> for each tree, among others. These hyperparameters play a role in controlling the model’s complexity and fit to the data.</p><p id="4e91">After initializing, the model is trained on the <code>X_train</code> and <code>y_train</code> datasets using the <code>fit</code> method. This step allows the model to learn the underlying patterns from the training data, preparing it to make future predictions on unseen data.</p><p id="95cf"><b>Performance Evaluation and Testing</b></p><div id="a823"><pre><span class="hljs-comment"># Predict on the test set</span> y_pred = model.predict(X_test)

<span class="hljs-comment"># Calculate performance metrics</span> mae = mean_absolute_error(y_test, y_pred) mse = mean_squared_error(y_test, y_pred) rmse = np.sqrt(mse)

<span class="hljs-built_in">print</span>(<span class="hljs-string">f"Mean Absolute Error: <span class="hljs-subst">{mae}</span>"</span>) <span class="hljs-built_in">print</span>(<span class="hljs-string">f"Mean Squared Error: <span class="hljs-subst">{mse}</span>"</span>) <span class="hljs-built_in">print</span>(<span class="hljs-string">f"Root Mean Squared Error: <span class="hljs-subst">{rmse}</span>"</span>)

y_train_pred = model.predict(X_train)</pre></div><p id="8c56">After training the

Options

model on the historical data we evaluate its performance on unseen or test data. Using the <code>predict</code> method of the trained model, predictions (<code>y_pred</code>) are generated for the test dataset <code>X_test</code>. Subsequently, to assess the accuracy and reliability of these predictions, various performance metrics are computed:</p><ul><li><b>The Mean Absolute Error (MAE)</b> provides an average magnitude of errors between predicted and actual values.</li><li><b>The Mean Squared Error (MSE) </b>squares these errors to emphasize larger discrepancies.</li><li><b>Root Mean Squared Error (RMSE) </b>is the square root of MSE, providing error in the same units as the original data.</li></ul><p id="c92b">These metrics are then printed for clear visibility. We concludes by also predicting on the training set (<code>X_train</code>) with <code>y_train_pred</code>, to further analyze and compare the model’s performance on both training and test datasets.</p><p id="44c0">The following output displays the performance metricswhich assess the accuracy of our model’s predictions:</p><div id="6743"><pre><span class="hljs-attribute">Mean</span> Absolute Error: <span class="hljs-number">0</span>.<span class="hljs-number">009141215039947168</span> <span class="hljs-attribute">Mean</span> Squared Error: <span class="hljs-number">0</span>.<span class="hljs-number">000303615460154008</span> <span class="hljs-attribute">Root</span> Mean Squared Error: <span class="hljs-number">0</span>.<span class="hljs-number">017424564848340058</span></pre></div><ul><li><b>Mean Absolute Error (MAE): </b>At 0.0091, it shows the model’s average absolute deviation from the actual values.</li><li><b>Mean Squared Error (MSE):</b> With a value of 0.0003036, it indicates the average squared error, emphasizing larger mistakes.</li><li><b>Root Mean Squared Error (RMSE):</b> At 0.0174, it provides the average error in the original unit, illustrating the typical magnitude of error.</li></ul><p id="7500">The relatively low values across these metrics suggest that the model has a good degree of accuracy in its predictions. The model appears to be reliably forecasting the target variable, depicted with minimal deviations in the forecasted data when compared to the actual data.</p><p id="be3b"><b>Data Visualization</b></p><div id="2b49"><pre><span class="hljs-comment"># Create a new DataFrame for visualization</span> viz_df = pd.DataFrame({<span class="hljs-string">'True'</span>: y_test, <span class="hljs-string">'Predicted'</span>: y_pred})

<span class="hljs-comment"># Concatenate the training data for a complete view</span> viz_df_train = pd.DataFrame({<span class="hljs-string">'True'</span>: y_train, <span class="hljs-string">'Predicted'</span>: y_train_pred}) viz_df = pd.concat([viz_df_train, viz_df])

<span class="hljs-comment"># Plot the results</span> plt.figure(figsize=(<span class="hljs-number">14</span>, <span class="hljs-number">7</span>)) plt.plot(viz_df[<span class="hljs-string">'True'</span>], label=<span class="hljs-string">'True'</span>, color=<span class="hljs-string">'blue'</span>) plt.plot(viz_df[<span class="hljs-string">'Predicted'</span>], label=<span class="hljs-string">'Predicted'</span>, color=<span class="hljs-string">'red'</span>, alpha=<span class="hljs-number">0.7</span>) plt.title(<span class="hljs-string">'EUR/USD Forecast: True vs Predicted'</span>) plt.legend() plt.grid(<span class="hljs-literal">True</span>) plt.show()</pre></div><figure id="ce5c"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*cLlTTCFRMZqUBQIUBeya0g.png"><figcaption></figcaption></figure><p id="62e5">The visual representation of the EUR/USD currency pair’s forecasted versus actual values offers an insightful glimpse into the model’s capabilities. The close alignment between the blue <code>True</code> line and the red <code>Predicted</code> line for most of the chart affirms the model’s strong predictive proficiency, especially given the low Mean Absolute Error (MAE) of 0.0091. The few areas where deviations occur resonate with the Root Mean Squared Error (RMSE) of 0.0174, indicating the average magnitude of error.</p><p id="ba85">Notably, the small segment towards the right end, where predictions seem to diverge slightly, underscores the challenges of exact currency forecasting. Nevertheless, the model, as depicted in the graph and corroborated by the performance metrics, has shown remarkable accuracy in capturing the nuances of the EUR/USD exchange rate’s movements.</p><h1 id="fe27">Conclusion</h1><p id="3036">In conclusion, this exploration into Forex forecasting has underscored the critical interplay between data preprocessing, feature engineering, and model selection. Through this model we found that XGBoost in predicting the EUR/USD currency pair stands out, demonstrating the algorithm’s robustness and adaptability. Finally, the precision showcased by our model reinforces XGBoost’s reputation as an efficient tool to forecast financial data.</p><p id="0141">Read more of my stories here:</p><div id="c60c" class="link-block"> <a href="https://algocraft.xyz/eur-usd-forecasting-simplified-an-lstm-users-guide-337ccdda6158"> <div> <div> <h2>EUR/USD Forecasting Simplified: an LSTM User’s Guide</h2> <div><h3>LSTM, or Long Short-Term Memory, is a specialized type of Recurrent Neural Network (RNN) designed to recognize patterns…</h3></div> <div><p>algocraft.xyz</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/1*EUIE-cUkt3x2AqBX5nUotA.jpeg)"></div> </div> </div> </a> </div><div id="a6a6" class="link-block"> <a href="https://algocraft.xyz/how-to-get-131-return-with-mean-reversion-trading-strategy-from-stock-selection-to-backtesting-c623870adf31"> <div> <div> <h2>How to Get a 131% Return with Mean Reversion Trading Strategy: From Stock Selection to Backtesting</h2> <div><h3>undefined</h3></div> <div><p>undefined</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*o95y-D4ETf1Geqx3)"></div> </div> </div> </a> </div></article></body>

Photo by Prateek Katyal on Unsplash

Creates Space With Simplicity

When less is more becomes your motto, the mind feels clearer, and often, oppressive thoughts, lift.

External spaces conflict with the internal condition of the body. Crowded spaces tend to produce an uptight condition inside. Reducing the rubbish, or extras in our life creates space where we can begin to think without the brain getting sidetracked.

The power of reduction of ‘stuff’ in the home, office, car, or any closet opens the door to freedom. The places we occupy develop into a sanctuary of serenity the more we simplify and reduce the extras. What are the extras?

They are the little things, which stack up like mail, sometimes junk mail we think we might look at later, but don’t. Things such as books stacked near chairs, because you read and need them, they keep reproducing (you are the helper of this plan).

Little steps make big changes.

Some strategies to help you overcome procrastination in tidying up spaces helped me think of ways I can reduce. Hopefully, during the time of confinement, you can embrace a few tactics so you can accomplish more over the span of time.

Five different strategies to simplify your sanctuaries:

  • Take some time to evaluate what life was like over the past year. Think of one small change you can do to improve this next year. As you do your thinking, consider what worked and what didn’t. Think of areas of your sanctuary (home, car, office) that seemed to pile up and you neglect. Is there some behavior you can change, which will help reduce the pile?
  • Our cars are a place where we hang out often. Travel to work (now to just get out of the house in a contained environment), travel to the store, and to family and friends, we leave stuff in our vehicles. Reduce catch-all containers, bags, and boxes. Keep the car stuff to the essential items: pen, paper towels, wet wipes, spare blanket, and some water.

My experience: I had three different places I drove too each week. Each job had a specific bag. I would bring the bags in at night, and then put them back in the morning as I left the house. Pretty soon, I stopped taking them out of my truck. When COVID-19 took place, I brought them all in my house, plus a couple more large bags (fabric material) which contained more files, books, and ideas). I didn’t realize how much I had kept in the bags until I cleaned them. To be honest, I did not need all of the stuff. They became a catch-all. Finally, I cleaned out all of the bags. Freedom felt good!

  • Clean out the closet for Spring! Take five minutes everyday to go through your closet and choose items you want for fall or winter and put them away. At the same time, choose three items to toss to Goodwill or throw away.
  • Write down a morning routine and stick the list on the bathroom mirror. As you build a routine, you’ll start to feel like you are accomplishing goals. Little clean ups, little self-care tactics helps us to clean up our life on the inside of us, and then the positive responsibility helps us on the outside. Little steps make big changes.
  • Tackle one room over the weekend. Step back and look at the whole room. What is too much? What can be eliminated? Is there anything you don’t need in the room? Take the time to focus on removing things you do not need. Then, take a dust cloth and wipe things down. Even do some deeper cleaning if you have some extra germ cleansers.
Image by Gordon Johnson from Pixabay

As you seek to simplify, you’ll move beyond keeping everything to feeling freedom in reduction. Life feels free when you look in areas where clutter lived, and notice the space seems less mind-crowded.

Often we make things so complex. The more we demand things to go our way the more we struggle with letting go.

Simplification is a step toward kindness and freedom. As you move toward a simple life, you’ll find the world opens up wider to you. The enclosed, trapped feeling dissipates. In time, the temptation to fill up the cleaned areas diminishes. You’ll no longer keep bringing things in if you consistently reduce the stuff and the stuff’s storage spots and containers in your life.

~Just a thought by Pamela

Personal Development
Life
Self Improvement
Change
Life Lessons
Recommended from ReadMedium