avatarAlex Roan

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>

How to Import External Smart Contracts and Libraries in Solidity

A step-by-step guide on how to import external code into your smart contracts

Image by WorldSpectrum from Pixabay

Where to Start

Getting started in the world of smart contract development can be overwhelming. There is often a lot of assumed knowledge that’s not particularly well explained anywhere. For example, importing external contracts and libraries into your smart contracts.

You might know exactly what a contract does, and that your contract would be better off using it, but the semantics of actually importing it is a roadblock.

In my early days, I remember copying and pasting library code into my .sol files as a workaround.

This article explains how to import any external contract or library into your smart contracts.

Moving On From Remix

The first steps you take in smart contract development most likely use the Remix online IDE. It’s a fantastic tool for quick and easy access to the Solidity compiler so you can learn the language as quickly as possible.

Once you’re confident using Solidity, you’ll naturally progress into wanting to develop in a local environment, in a desktop IDE. Having code in a project directory, running locally, allows for rapid development and enables the use of version control and open sourcing.

This is where Truffle Suite comes in.

“World class development environment for blockchain DApps (decentralized applications) and smart contracts.” — Trufflesuite.com

It keeps all your code in one place without much configuration, and the learning curve to get something basic working is very shallow.

The next time you come to create a new project containing smart contracts, start with Truffle. Let’s do it…

Getting Started

Node

Truffle runs on Node.js, so if you haven’t already got it installed, head over to their website and follow the installation instructions.

Truffle

Use Node Package Manager (npm) to install Truffle by running:

npm install -g truffle

Text editor

Ensure you have an up to date text editor installed. I’m using VS Code.

Once everything is installed, navigate to your preferred workspace and create a new directory in which our Truffle project will reside, then initialize a Truffle project:

mkdir my-project
cd my-project/
truffle init

Open up the new project directory in your text editor. Your folder structure should look like figure 1. There should be three subdirectories: contract/, migrations/, and test/; and a file: truffle-config.js.

Figure 1: folder structure
  • contract/ is where our Solidity smart contract code is stored. Truffle knows to look here for .sol files to compile and migrate to the blockchain.
  • migrations/ is where our migration logic resides. Here we can describe the steps needed when deploying our contracts so that they are correctly deployed.
  • test/ is where we will write for our smart contracts to ensure they function as expected.
  • truffle-config.js contains information about networks, compilers, file locations, and other custom configurations for the Truffle framework to know where our things are. Don’t worry about this file for now.

Installing and Importing

OpenZeppelin is the gold-standard reusable repository for Ethereum smart contracts. In this project, we’re going to install the contract repo as a dependency, then import the Ownable contract so we can restrict access to certain functions.

You may have seen or used a similar pattern before. When the contract is initialized, the msg.sender address is stored in a state variable indicating the owner of the contract. Using a custom modifier _onlyOwner, certain functions restrict access by requiring that the msg.sender is equal to the owner.

In the repository root, run:

npm install @openzeppelin/contracts --save

Once completed, you should see a new folder in your root named node_modules/ (if you’ve used Node or npm before you know all about this).

Inside node_modules, npm has downloaded the OpenZeppelin/contracts repo, in which live all the contracts and libraries that OpenZeppelin has to offer. Take a moment to have a browse at what is on offer.

We’re going to use the Ownable contract, which, from the project root, lies in @openzeppelin-solidity/contracts/access/Ownable.sol.

In the contracts/ folder, create a new Solidity file that will import the Ownable contract. I’m going to call mine TestContract.sol.

The first thing is to declare the Solidity compiler version, we’re using 0.6.0; then we need to import the Ownable contract using the path we found it; and finally, we need to declare the contract and that it extends from Ownable.

Figure 2 shows the skeleton contract once we’ve done all this.

Believe it or not, that’s pretty much it!

When writing new functions in this contract, we can add the onlyOwner modifier just after the public, private, internal, or external modifiers to declare that the function should only be run by the owner.

Here’s a simple example:

// This function has no restrictions on who can call it
function noRestrictions() public { ... }
// This function is restricted only to the owner. Anyone else
// who tries to call it will result in a reverted transaction
function restrictedFunction() public onlyOwner { ... }

To make sure the contract compiles when you’ve added your new restricted functions, run:

truffle compile

If all is well, you can start working on migrating your contracts to a local blockchain, writing tests, and deploying to a public testnet!

Further Reading

If you’re interested in blockchain development, I write tutorials, walkthroughs, hints, and tips on how to get started and build a portfolio. Check out some of these resources:

Programming
JavaScript
Blockchain
Ethereum
Solidity
Recommended from ReadMedium