Custom Machine Learning

Custom Machine Learnings describes how you can use environments like Python for machine learning and let it cooperate with the Haasonline TradeServer.

Procedure

In short, the procedure to make custom machine learning work is as follows;

  1. Create a dataset (using the Haasbot)

  2. Train a model on the dataset (using third party tooling)

  3. Run the model and make it respond to API inputs (using third party tooling)

  4. Connect HaasScript to the API of the model (using the Haasbot)

  5. Optional: Retrain the model

1. Creating a dataset

We are going to get started by creating a dataset. You can do this by creating a HaasScript which you set setup with the data you like to have.

Please open the Web-editor, create a new HaasScript, and copy-and-paste the following code in your editor.

local fileName = "Performance";

InitExportData(fileName, "Timestamp", "Price", "RSI", "Signal")

local rsi = RSI(ClosePrices(), 12)
local signal = SignalNone

if (rsi[1] > 80) then
  signal = SignalSell
end

if (rsi[1] < 20) then
  signal = SignalBuy
end

WriteExportData(fileName, Time(), ClosePrices(), rsi, signal)

The next thing you need to do is run a backtest. Once the backtest is done, open the Result tab on the backtest popup window. Over there you will see 2 buttons, one is to save your data as CSV and the other one is to save it as JSON. Please click on saving it as CSV.

2. Train a model

There are several ways to progress a dataset in machine learning. Each has his favorite tooling. We are going to show you how it's done in Python. We have chosen Python because it offers the fastest and best machine learning capabilities.

Before getting started with the coding in Python, we need to make sure we have the right modules installed. You can do this by executing the following command:

pip install pandas scikit-learn joblib

Once you have made sure the modules are installed, then create a new Python script and copy-and-paste the following code in it;

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
import joblib

# Step 1: Read data from CSV file
def read_data(file_path):
    return pd.read_csv(file_path)

# Step 2: Preprocess data and train a machine learning model
def train_model(data):
    # Assuming 'signal' is the target variable and the rest are features
    X = data[['Timestamp', 'Price', 'RSI']]
    y = data['Signal']

    # Split the data into training and testing sets
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

    # Create a decision tree classifier (you can replace this with any other model)
    model = DecisionTreeClassifier()

    # Train the model
    model.fit(X_train, y_train)

    # Make predictions on the test set
    y_pred = model.predict(X_test)

    # Evaluate model accuracy
    accuracy = accuracy_score(y_test, y_pred)
    print(f'Model Accuracy: {accuracy}')

    return model

# Step 3: Save the trained model
def save_model(model, model_filename='trained_model.joblib'):
    joblib.dump(model, model_filename)
    print(f'Model saved as {model_filename}')

# Main script
if __name__ == "__main__":
    # Replace 'your_data.csv' with the actual file path
    file_path = 'dataset.csv'

    # Step 1: Read data
    data = read_data(file_path)

    # Step 2: Train model
    trained_model = train_model(data)

    # Step 3: Save model
    save_model(trained_model)

If you make sure your dataset is copied in the same folder and this code is stored in, and the `file_path` points to your CSV file, then you can run it and a model will be created.

3. Run the model

Of course, running the model depends on what tooling you used earlier. In our case we used Python, so we keep using this. But before we can proceed we need to make sure a few modules are install again. To do this, please execute the following command.

pip install Flask

Once the modules are installed, create another new Python script and copy-and-paste the code listed below into it.

from flask import Flask, request, jsonify
import joblib

app = Flask(__name__)

# Load the trained model
model = joblib.load('trained_model.joblib')

# Define the API endpoint for making predictions
@app.route('/predict', methods=['GET'])
def predict():
    try:
        # Extract features from URL parameters
        timestamp = float(request.args.get('timestamp'))
        price = float(request.args.get('price'))
        rsi = float(request.args.get('rsi'))

        # Make a prediction using the loaded model
        prediction = model.predict([[timestamp, price, rsi]])

        # Convert the prediction to a string (assuming it's binary)
        prediction_str = str(prediction[0])

        return jsonify({'prediction': prediction_str})

    except Exception as e:
        return jsonify({'error': str(e)})

# Run the Flask application
if __name__ == '__main__':
    app.run(debug=True, port=5000)

If all goes well then the output is going to look like this;

4. Connect HaasScript

The next and last step is to connect HaasScript to your running model, so it can query the result. To do this, you can use the following HaasScript;

local myTime = Time()
local rsi = RSI(ClosePrices(), 12)[1]
local price = ClosePrices()[1]

local res = ParseJson('http://host.docker.internal:5000/predict?timestamp='..myTime..'&price='..price..'&rsi='..rsi)

if res["prediction"] == SignalNone then
  Log('Computer says: Do nothing')
elseif res["prediction"] == SignalBuy then
  Log('Computer says: Buy!')
elseif res["prediction"] == SignalSell then
  Log('Computer says: Sell')
end

NB: Notice that our Python script host to 127.0.0.1 and we do a webrequest from HaasScript to host.docker.internal This different URL tells the docker to look to the localhost on the main system.

You are done, you can now run this HaasScript and it will reach out to your Python model and read the outcome. This is all what it takes to get custom machine learning to work in the Haasonline TradeServer.

5. Retrain the model

In the given example, we have used just 1 dataset to train the model. You might want to update or perfect your model, and this can be done using retraining.

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
import joblib

# Step 1: Read data from CSV file
def read_data(file_path):
    return pd.read_csv(file_path)

# Step 2: Preprocess data and retrain the machine learning model
def retrain_model(data):
    # Assuming 'signal' is the target variable and the rest are features
    X = data[['Timestamp', 'Price', 'RSI']]
    y = data['Signal']

    # Split the data into training and testing sets
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

    # Create a decision tree classifier (you can replace this with any other model)
    model = DecisionTreeClassifier()

    # Retrain the model
    model.fit(X_train, y_train)

    # Make predictions on the test set
    y_pred = model.predict(X_test)

    # Evaluate model accuracy
    accuracy = accuracy_score(y_test, y_pred)
    print(f'Retrained Model Accuracy: {accuracy}')

    return model

# Step 3: Save the retrained model
def save_model(model, model_filename='retrained_model.joblib'):
    joblib.dump(model, model_filename)
    print(f'Retrained Model saved as {model_filename}')

# Main script
if __name__ == "__main__":
    # Replace 'your_updated_data.csv' with the path to the updated data file
    updated_file_path = 'dataset.csv'

    # Step 1: Read updated data
    updated_data = read_data(updated_file_path)

    # Step 2: Retrain model
    retrained_model = retrain_model(updated_data)

    # Step 3: Save retrained model
    save_model(retrained_model)

Reflection

In the examples which were given here, we have trained a ML-model to respond to an RSI output. This was of course designed to be a basic example of how to make it all work. But based on this example you can build a lot more advanced model in which you use more different indicators and maybe add historical values to teach it to respond to a trend or something like that.

Last updated