Amibroker is a powerful technical analysis and trading system development platform, used extensively by traders and analysts for developing and deploying trading strategies. Python, on the other hand, is a versatile programming language that offers a rich ecosystem of libraries for machine learning and data analysis. By using AmiPy, a plugin that acts as a bridge between Amibroker and Python, we can combine the strengths of both platforms to create powerful machine learning-based trading strategies.
In this article, we will discuss how to perform machine learning to predict the next day stock price using Amibroker and Python with AmiPy. We will use a linear regression model to predict stock prices and evaluate its performance using various metrics.
Prerequisites
Before we begin, ensure that you have the following installed:
- Amibroker 6.3 or higher (64-bit) and AmiPy Plugin
- Python 3.8 (64-bit) or higher – Standalone, not Conda or Anaconda install
- Numpy Library, Pandas, Scikit and joblib Library
To install the required libraries using pip, open your command prompt or terminal and run the following commands:
pip install numpy
pip install pandas
pip install scikit-learn
pip install joblib
These commands will install the Numpy, Pandas, Scikit-learn, and Joblib libraries in your Python environment.
Note: Ensure that both the Amibroker AFL and Python files are created in the same directory. In this example, both the files are created in the same path C:\ML\Projects\linreg as shown below
Amibroker AFL Code
First, create an Amibroker AFL code that sends the features and targets in realtime to Python. Below is the sample code for this purpose. This code defines the features and targets for the machine learning model, as well as parameters for training and resetting the model. The Amibroker AFL code Plots the predicted value over the candlestick data and also brings the metrics of linear regression in the title section. By Default 10 features and 1 Target is sent by Amibroker. Users can customize the features and target section in the Amibroker AFL to suit their requirements.
In the above chart, the thick yellow line shows the predicted value and the pink dashed line shows the next day/ next bar predicted value and metrics is shown in the title section
Amibroker Controls
When the chart is dragged to the Amibroker Workspace it trains the model for the first time and plot the predicted values. However one has to reset the model by pressing the Reset Training Button “Yes” and retrain the model by pressing “Yes” in the Parameter section
Linear Regression – Prediction Amibroker AFL Code
_SECTION_BEGIN("Linear Regression - Prediction");
//turnoff quick afl
SetBarsRequired(sbrAll,sbrAll);
EnableTextOutput(False);
pyFilePath = "C:\\ML\\Projects\\linreg\\linreg_prediction.py";
metricsFilePath = "C:\\ML\\Projects\\linreg\\linreg_metrics.txt";
//python code will be executed
PyLoadFromFile("linreg_py",pyFilePath);
prediction = Null;
//Call Python Function inside the file
testdata = Param("Test Data %",0.2,0.05,1,0.05);
trainmodel = ParamTrigger("Train the Model", "Yes");
reset = ParamTrigger("Reset Training", "Yes");
feature1 = Close;
feature2 = open;
feature3 = high;
feature4 = low;
feature5 = Ref(Close,-1);
feature6 = EMA(Close,5);
feature7 = HMA(Close,5);
feature8 = linearreg(Close,5);
feature9 = WMA(Close,5);
feature10 = DEMA(Close,5);
close_forecast = Ref(C,1);
target = close_forecast;
static_var = Name() + Interval() + GetChartID() + "MLStrategy";
if( Nz( StaticVarGet(static_var+"MachineLearning") ) == 0 )
{
StaticVarSet(static_var+"MachineLearning", 1);
resp = PyEvalFunction("linreg_py","linreg_train", testdata, feature1,feature2,feature3,feature4,feature5
,feature6,feature7,feature8,feature9,feature10,target);
_TRACE("Static Variable Set for the symbol"+Name());
}
if(reset)
{
StaticVarRemove(static_var+"*");
_TRACE("Static Variable Removed for the symbol"+Name());
}
Prediction = PyEvalFunction("linreg_py","linreg_predict", feature1,feature2,feature3,feature4,feature5
,feature6,feature7,feature8,feature9,feature10,target);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Title = "Linear Regression - Machine Learning (Actual Vs Prediction) -" + Title ;
fh = fopen(metricsFilePath,"r");
_TRACE("File Opened");
if(fh)
{
//feof - end of the file -> True if the file ends else it returns false
while(!feof(fh)) //as long as the condition of while loop is true the loop continues
{
line = fgets(fh);
Title = Title + Line;
_TRACE("Read from the file");
}
}
fclose(fh);
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
Plot(prediction[BarCount-1],"Next Day Prediction",colorPink,styleDashed | styleThick );
Plot(Ref(prediction,-1),"Prediction",colorYellow,styleThick );
_SECTION_END();
Python File for Linear Regression Algorithm for Training, Prediction and Metrics
Next, create a Python file that performs linear regression algorithm training, prediction, and computation of metrics. The file should also store the models and prediction metrics. Below is the sample Python code that accomplishes these tasks:
Linear Regression – Python (linreg_prediction.py)
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, r2_score, explained_variance_score
import numpy as np
import AmiPy
import joblib
import os
#Get the Current Working directory of python script
script_directory = os.path.dirname(os.path.abspath(__file__))
model_path = os.path.join(script_directory, 'linear_regression_model.pkl')
scaler_path = os.path.join(script_directory, 'scaler.pkl')
metrix_path = os.path.join(script_directory, 'linreg_metrics.txt')
#Function to calculate MAPE
def mean_absolute_percentage_error(y_true, y_pred):
y_true, y_pred = np.array(y_true), np.array(y_pred)
return np.mean(np.abs((y_true - y_pred) / y_true)) * 100
def linreg_train(testdata, feature1, feature2, feature3, feature4, feature5, feature6, feature7, feature8, feature9, feature10, target):
result = 0
# Prepare the dataframe
df = pd.DataFrame.from_records({'feature1': feature1,
'feature2': feature2,
'feature3': feature3,
'feature4': feature4,
'feature5': feature5,
'feature6': feature6,
'feature7': feature7,
'feature8': feature8,
'feature9': feature9,
'feature10': feature10,
'target': target})
AmiPy.Print("Python Dataframe Prepared\n")
# Remove nan values from the dataframe
df.dropna(inplace=True)
# Prepare the data
y = df['target']
X = df.drop(columns=['target'], axis=1)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=testdata, random_state=42)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
AmiPy.Print("Training the Model!\n")
# Train the model
model = LinearRegression()
model.fit(X_train_scaled, y_train)
# Save the model and scaler
joblib.dump(model, model_path)
joblib.dump(scaler, scaler_path)
result = 1
return result
def linreg_predict(feature1, feature2, feature3, feature4, feature5, feature6, feature7, feature8, feature9, feature10, target):
# Load the model and scaler
model = joblib.load(model_path)
scaler = joblib.load(scaler_path)
# Prepare the dataframe
df = pd.DataFrame.from_records({'feature1': feature1,
'feature2': feature2,
'feature3': feature3,
'feature4': feature4,
'feature5': feature5,
'feature6': feature6,
'feature7': feature7,
'feature8': feature8,
'feature9': feature9,
'feature10': feature10,
'target': target})
# Remove nan values from the dataframe
df.dropna(inplace=True)
# Predict the target values
X_scaled = scaler.transform(df.drop(columns=['target'], axis=1))
y_true = df['target']
y_pred = model.predict(X_scaled)
# Calculate the metrics
mse = mean_squared_error(y_true, y_pred)
rmse = np.sqrt(mse)
mape = mean_absolute_percentage_error(y_true, y_pred)
r2 = r2_score(y_true, y_pred)
explained_var = explained_variance_score(y_true, y_pred)
# Write the metrics to a txt file
with open(metrix_path, 'w') as f:
f.write(f'MSE: {mse}\n')
f.write(f'RMSE: {rmse}\n')
f.write(f'MAPE: {mape}\n')
f.write(f'R2 Score: {r2}\n')
f.write(f'Explained Variance: {explained_var}\n')
return y_pred
In this Python file, we have defined two main functions: linreg_train
and linreg_predict
. The linreg_train
function prepares the data, trains the linear regression model, and saves the model and scaler to files. The linreg_predict
function, on the other hand, loads the model and scaler, prepares the data, predicts the target values, and calculates the evaluation metrics.
By combining Amibroker and Python using AmiPy, we can leverage the power of machine learning to develop advanced trading strategies. In this example, we have demonstrated how to use a linear regression model for predicting stock prices. You can explore other machine learning models and techniques to further enhance your trading strategies. The seamless integration of Amibroker and Python using AmiPy opens up a world of possibilities for creating sophisticated and data-driven trading systems.
Wow.
WOW.
can’t believe i’m the first to comment on this absolute piece of treasure!
thanks for explaining Rajandran!
Much appreciated.
very informative data Rajendran! Thanks for sharing it/
Thanks Rahul