Create a Price Forecast Model

This tutorial will walk you through how to create a price forecast model

πŸ“˜

Tutorial Overview

In this tutorial we will explain how to create and deploy a Network of Time Series (NoTS) that generates 48-hour DA LMP forecasts for ERCOT North Hub. The resulting forecast will be generated every hour on an ongoing basis.

Create your NoTS

For this tutorial you will leverage the client library to create your NoTS. The NoTS that you'll create will use an XGBoost model with time-based and weather-based features to forecast the DA LMP for ERCOT North Hub. We will be using the Yes Energy DataSignals API to access historical price data.

🚧

Model Performance

Note that the model we are using in this tutorial is not optimized to generate DA LMP forecasts for ERCOT North Hub. The goal of this tutorial is merely to show users how to create and deploy a simple price forecasting model. We do not recommend using this model in production.

Client Library

To create the NoTS in the client library, you can use the following code.

import myst
from myst.connectors.model_connectors import xgboost
from myst.connectors.source_connectors import time_trends
from myst.connectors.source_connectors import yes_energy
from myst.recipes.time_series_recipes import the_weather_company

myst.authenticate()

# Create a new project.
project = myst.Project.create(title="DA LMP ERCOT North Hub")

# Create an hour of day, day of week, and month of year time series from a time trends source.
time_trends_source = project.create_source(
    title="Time Trends",
    connector=time_trends.TimeTrends(
        sample_period=myst.TimeDelta("PT1H"),
        time_zone="UTC",
        fields=[
            time_trends.Field.HOUR_OF_DAY,
            time_trends.Field.DAY_OF_WEEK,
            time_trends.Field.DAY_OF_YEAR,
        ],
    ),
)
hour_of_day_time_series = time_trends_source.create_time_series(
    title="Hour of Day",
    sample_period=myst.TimeDelta("PT1H"),
    label_indexer=time_trends.Field.HOUR_OF_DAY,
)
day_of_week_time_series = time_trends_source.create_time_series(
    title="Day of Week",
    sample_period=myst.TimeDelta("PT1H"),
    label_indexer=time_trends.Field.DAY_OF_WEEK,
)
day_of_year_time_series = time_trends_source.create_time_series(
    title="Day of Year",
    sample_period=myst.TimeDelta("PT1H"),
    label_indexer=time_trends.Field.DAY_OF_YEAR,
)

# Create a temperature time series using a The Weather Company recipe.
temperature_time_series = project.create_time_series_from_recipe(
    recipe=the_weather_company.TheWeatherCompany(
        metar_station=the_weather_company.MetarStation.KDFW,
        field=the_weather_company.Field.TEMPERATURE,
    )
)

# Create a DA LMP time series using a Yes Energy source.
yes_energy_source = project.create_source(
    title="Yes Energy",
    connector=yes_energy.YesEnergy(
        items=[yes_energy.YesEnergyItem(datatype="DALMP", object_id=10000697078)],
        stat=yes_energy.YesEnergyAggregation.AVG,
    ),
)
da_lmp_ts = yes_energy_source.create_time_series(
    title="Historical DA LMP",
    sample_period=myst.TimeDelta("PT1H"),
    label_indexer="DALMP_10000697078",
)

# Create an XGBoost model.
model = project.create_model(
    title="DA LMP Model",
    connector=xgboost.XGBoost(num_boost_round=100, max_depth=3, learning_rate=0.1),
)

# Add the time series as inputs to the model.
for time_series in [
    hour_of_day_time_series,
    day_of_week_time_series,
    day_of_year_time_series,
    temperature_time_series,
]:
    model.create_input(time_series, group_name=xgboost.GroupName.FEATURES)
model.create_input(da_lmp_ts, group_name=xgboost.GroupName.TARGETS)

# Add a fit policy to the model.
model.create_fit_policy(
    start_timing=myst.TimeDelta("-P3M"), 
    end_timing=myst.TimeDelta("PT1H"),
    schedule_timing=myst.TimeDelta("PT24H"),
)

# Create a time series with the model predictions.
forecast_time_series = model.create_time_series(
    title="DA LMP Forecast", sample_period=myst.TimeDelta("PT1H")
)

# Add a run policy to the time series.
forecast_time_series.create_run_policy(
    start_timing=myst.TimeDelta("PT1H"),
    end_timing=myst.TimeDelta("PT49H"),
    schedule_timing=myst.TimeDelta("PT1H"),
)

Deploy your NoTS

Once you've finished creating your NoTS, you can now go ahead and deploy your Project.

Web Application

To create a new Deployment, click the Deploy button in the top right corner of the Project Create page. Specify a title for your Deployment and then click the Deploy button.

Once you’ve deployed a project, your Model Fit Policy and Time Series Run Policy will begin to run according to their schedules. This means that your Model will be fitted once a day and your Time Series will be run every hour. Note that these Policies will run indefinitely, until you deactivate your Deployment.

To track and verify the results of your Deployment, navigate to the Project Monitor space by clicking on the Monitor tab at the top of the Project page. The results table shows a list of ongoing results that are being generated by your policy. You can refresh the table by clicking on the refresh icon.

Client Library

The code below will deploy your project, creating a first model fit and time series run immediately.

# Deploy the project.
project.deploy("My Deployment")

# Create ad hoc time series node run job.
time_series_run_job = forecast_time_series.run(
    start_timing=myst.TimeDelta("PT1H"), 
    end_timing=myst.TimeDelta("PT49H"),
)

πŸ‘

Tutorial Complete

You are now generating the 48-hour DA LMP forecasts for ERCOT North Hub on an ongoing basis. See the section on Query Time Series Data to learn more about how to query your stored forecasts.