Table of Contents

1. Introduction
1.1 Competition Rules
2. Installation
3. Configuration
4. Data Objects
5. Order Flow
6. Sequence Diagrams
7. Self Scheduling
8. FAQ

1. Introduction

Introduction

The current energy landscape will undergo a fundamental redesign within the next decade. There are several major forces driving the change process: First, fossil energy prices are continuously rising, second the reduction of green house gas emissions has become a top priority for governments all over the world, and third the concentration of the remaining fossil energy reserves within rather few, politically unstable countries, drives the desire of many western governments to become more independent from energy imports. These challenges have to be addressed within the next few years. On the generation side small-scale distributed and oftentimes intermittent energy production capacities will be installed. On the consumption side, demand-side-management technologies (DSM) will be established that enable consumers to better observe, actively influence and consciously shift their energy consumption loads adding flexibility to the system as a whole but also making demands harder to predict on an aggregated level. Additionally, the expected transition to electric mobility poses a serious threat of overcharging the current grid infrastructures if introduced without intelligent charging and coordination strategies in place but also promises significant amounts of storage capacity that can be used for load balancing. All these trends conflict with current centralized power grid control infrastructures and strategies, where a few control centers manage limited numbers of large power plants to adjust their output to expected and observed demands in real time.

A more flexible, decentralized, and self-organizing approach towards energy management will have to be developed that allows for an active management of all grid hierarchy levels from local distribution grids to the pan-European ENTSO-E wide area transmission grid. One approach is to apply the distributed resource-allocation power of markets to achieve near-optimal balance between producers and consumers of power at lower levels of the grid hierarchy and to connect the different hierarchical levels through market coupling. So far, only limited guidance is available on how such markets should be designed and operated. Kambil and van Heck point out that poorly-designed markets can do more harm than good; the California energy market breakdown in 2000 demonstrated the problems that can occur if economic incentives of market participants are not clearly understood in the design of such markets.

For these reasons, the TAC Energy Competition was created. From a scientific point of view it will be a laboratory to evaluate proposed market designs and different types of trading strategies in a competitive simulation environment similar to the one of the Trading Agent Competition for Suppy Chain Managment. TAC Energy models a market-based management structure for local and regional energy networks at multiple levels of complexity using real historic data on energy production and consumption, weather, and consumer preferences.

In its current release TAC Energy provides an environment that allows the simulation of intraday energy trading, which is modeled very similar to the one that takes place every day e.g. at the European Stock Exchange (EEX). For more details on related work and on the concept of TAC Energy please refer to the TAC Energy White Paper. Also a short prezi presentation with an introduction to TAC Energy is available online.

1.1 Competition Rules

Balancing Power Calculation

Balancing Power is the difference between the amount of energy (ore more precisely the amount of one particular product) a participant acquired through trading in the market and the true demand for this product. The true demand is ex-ante unknown but approximated with gradually increasing precision over time forecasts the participant receives on each simulation time shift.

Balancing power demand is calculated for all products (timeslots) after the competition has finished.

From a energy consumer's point of view, two cases for balancing power provisioning have to be distinguished:

Case 1: Insufficient energy in stock Example: A Participant had a true demand of 100 units of a certain product but managed to acquire only 50 units. In this case the difference of 50 units is booked into the participants depot after the competition is finished in parallel with a cash deduction for the missing 50 units, that are billed at a balancing power price. The balancing power price for excess demand is calculated as the highest historic price that occurred for this particular product during trading and is further increased by Competition.balancingCostUnder, which is freely defineable for each competition (Default: 0).

If no trade occurred in this product during the competition runtime the average trade price across all other products is calculated instead as balancing power price.

If not trade occurred at all during the competition runtime (which should never be the case in reality) an arbitrarily chosen price of 111 is used as balancing power price.

Case 2: Excess energy in stock Example: A Participant had a true demand of 100 units of a certain product but acquire 110 units. In this case the difference of 10 units is deducted from the participant's depot after the competition is finished. If Competition.balancingCostOver is set to a value > 0, the amount of money for each unit of excess energy is additionally deducted from the participant's cash account as balancing power fee for excess demand.

From an energy supplier's point of view the rules are applied vice versa.

2. Installation

Installation

This section provides a short overview on how to download, install and run the TAC Energy demo client and the TAC Energy server on your local machine.

Installation of TAC Energy demo client

Download and install software dependencies

TAC Energy Server and Demo Client are built upon the http://grails.org java web development framework. This is why you have to install the latest version of Java Development Kit (>= v1.6) as well as grails Framework v1.2.2 on your local machine. Follow the respective installation instructions and make sure that everything is up and running correctly before you proceed to the next step.

In particular make sure that the environment variables GRAILS_HOME and JAVA_HOME are set correctly and that the directory GRAILS_HOME/bin is on your PATH variable.

Optionally, if you want to check out the source code from the version control system you need to install Bazaar VCS Client on your machine. Bazaar is a distributed version control system (similar to but at the same time much more sophisticated than svn).

To check that your grails framework is installed correctly simply type grails help anywhere into you command line. If you see a list of possible grails commands as a result, everything is up and running correctly.

Download and Install Demo Client Source Code

Download the source code from launchpad at http://code.launchpad.net/tacenergydemo

mkdir /some/path/mytacenergydemoclient
cd /some/path/mytacenergydemoclient
bzr branch lp:tacenergydemo .

Alternatively you can download and unzip the latest snapshot of the sources from the CI Server (CI = Continuous Integration) and unzip it to a local folder. This folder should not contain white spaces in its directory path.

Test run the Demo Client

Open a command line window and cd to the directory where you unzipped the demo client source code. Type

grails run-app

and the demo client should start automatically as a small web server on your local machine. After some seconds you should see the following line in your command window:

Server running. Browse to http://localhost:8080/tacenergydemo

Point your web browser to http://localhost:8080/tacenergydemo and you should be able to see the welcome page of the TAC Energy demo client. If you now try to connect to the server this will fail as by default the client tries to connect to an instance of TAC Energy server running on localhost too. For the time being stop the client (Ctrl-C) and head over to the next section where the installation of the TAC Energy server is described.

Start your client with grails -Dserver.port=8090 if you run both server and client on your machine to avoid port conflicts.

Installation of TAC Energy Server

Installation of the latest binary version of the TAC Energy Server

Download the latest binary tacenergy-XX.war version of TAC Energy server from the CI Server where the XX stands for the version of the TAC Energy server.

The war file is a specially formatted zip file that is executable without any further actions required by any standard compliant Java Servlet API 2.5 contrainer such as Apache Tomcat 6. Consequently the TAC Energy server should run on all modern servlet containers including the latest versions of Jetty, Glassfish, JBoss, or WebSphere but is tested and verified to run on Apache Tomcat 6 only. If you haven't done so already, download and install the latest version of Tomcat on your local machine. Make sure that Tomcat starts correctly and that you can see its default welcome page in your web browser at http://localhost:8080. Afterwards just copy the downloaded tacenergy-XX.war file to TOMCAT_HOME/webapp while tomcat is running and that's it!

The tacenergy-XX.war is automatically unpacked and the TAC Energy server will be automatically started by Tomcat without any further actions required. After a short while you should be able to see the TAC Energy server welcome page at http://localhost:8080/tacenergy. If this is not the case check the tomcat log file for possible errors. By default they are located at TOMCAT_HOME/logs

The default login for TAC Energy server is user: admin and password: testit

Installation of the latest source version of the TAC Energy Server

Download the source code from launchpad

mkdir /some/path/mytacenergyserver
cd /some/path/mytacenergyserver
bzr branch lp:tacenergy .

Alternatively you can download and unzip the latest snapshot of the sources from the CI Server and unzip it to a local folder. This folder should not contain white spaces in its directory path.

Test run the TAC Energy Server

Open a command line window and cd to the directory where you downloaded the TAC Energy server source code. Type

grails run-app

and the server should start automatically as a small web server on your local machine. After some seconds you should see the following line in your command window:

Server running. Browse to http://localhost:8080/tacenergy

Point your web browser to http://localhost:8080/tacenergy and you should be able to see the welcome page of the TAC Energy server. Also try to point your web browser to http://localhost:61616. You should see some cryptic signs in your browser window. This is the default JMS endpoint of the server. No worries - the TAC Energy demo agent will be able to interpret this cryptic text correctly. ;-)

3. Configuration

Configuration

Demo Client Configuration

Open $TAC_DEMOAGENT_DIR/grails-app/config/Config.groovy and scroll down to the bottom.

tacenergy {
  username = 'tacenergy1'
  password = 'secret'
  server = "tcp://localhost:61616"

databinding { retryCount = 5 retryWait = 1000 }

User Credentials and Server Url

Here you can enter your personal login credentials that you received during registration from the TAC Energy Server. The values are set to work without any changes with a locally running TAC Energy Server.

If you want to participate in competitions on a server other than localhost (your local machine) you need to adjust the server url accordingly before starting the demo client. Ask the respective server admin for the correct server url.

Data Binding

By default the TAC Energy demo client tries to parse an incoming XML message and to store the resulting object in the local database. E.g. the server sends a forecast message in XML format to the client. The TAC Energy demo client then automatically tries to read the XML message and to create a new DomainClasses instance in the local database. The raw XML message together with the saved Forecast domain instance is then provided as input for the AgentStrategyService as shown below.

def onForecastUpdateReceived(Forecast forecastInstance, String rawXml) {
  log.info "New Forecast received: ${forecastInstance}"
}

Due to the underlying communication structure sometimes it happens that e.g. a forecast message is retrieved and processed by the client before the corresponding Product notification was received. In this case storing the Forecast in the database will fail as the referenced product cannot be found. To circumvent this problem the TAC Energy demo client will retry parsing the incoming Forecast message several times before giving up. With the parameters retryCount and retryWait you can adjust how often the processing should be retried and how long the agent should wait (in milliseconds) between each attempt.

Database Configuration

HSQL DB Configuration

By default the TAC Energy demo agent uses a Hyper SQL in memory database for persisting and retrieving data. If you wish to see the data stored in this database just follow this tutorial that shows how to set up a database viewer for HSQLDB. Alternatively you may switch to another database like e.g. mysql. as described in the following sub section.

MySQL DB Configuration

If you wish to use a mysql database as data storage for you TAC Energy Client simply follow these instructions.

First you need to download and install the latest MySQL Server on your local machine (v5.1 is the latest version at the time of writing this guide). Make sure that it is installed and running correctly.

Now login to the database using the mysql client and the root user (you need to enter the password you chose for the root user during installation of the server).

mysql -u root -p

Afterwards you create a new database and a database user that the TAC Energy client can use later on.

create database mytacagentdb_dev; 
grant usage on *.* to tacdemoagent@localhost identified by 'my_db_password';
grant all privileges on mytacagentdb_dev.* to tacdemoagent@localhost ;

After you've accomplished this step you need to configure your agent to use the newly created mysql database. First of all you need to make sure that the demo agent uses the mysql jdbc driver. Open $DEMO_AGENT_DIR/grails-app/conf/BuildConfig.groovy and uncomment the line

runtime 'mysql:mysql-connector-java:5.1.5'

The next time you start your agents using grails run-app the jdbc driver will be downloaded from an internet driver repository (maven for the experts) and installed into your agent automatically. No further actions required on this. The last thing that remains is to tell you agent to use the new mysql database instead of HSQLDB. Open $DEMO_AGENT_DIR/grails-app/conf/DataSource.groovy and adjust the database parameters accordingly. For the database above the settings should look like this.

development {
	dataSource {
		dbCreate = "create-drop"
    driverClassName = "com.mysql.jdbc.Driver"
    dialect='org.hibernate.dialect.MySQL5InnoDBDialect'
    username = "tacdemoagent"
    password = 'my_db_password'
		url = "jdbc:mysql://localhost/mytacagentdb_dev"
	}
}

By default grails supports three different environments, test, dev, and prod. Read the corresponding section in the grails reference documentation to understand the details of this concept.

4. Data Objects

wh1. Data Objects

The TAC Energy Client uses a database to store all data that comes in from the TAC Energy server. For your convenience database tables are automatically mapped to java domain classes by means of GORM object relational mapping. Read the section on database mapping in the grails user guide to understand the concept of object relational mapping and how to use this powerful technology for the development of your trading agent.

Also you should read the reference documentation on Domain Classes in order to understand the function, meanings and properties of each of the TAC Energy specific domain classes.

5. Order Flow

Order flow

This section covers the order flow and settlement between client and server, including the order of incoming and outgoing shout notifications and cash and depot positions.

Settings

Assume the market is empty and has two participants.

Orders

  1. Participant 1: Buy 300 at 8 EUR
  2. Participant 1: Buy 150 at 9 EUR
  3. Participant 1: Buy 50 at 9 EUR
  4. Participant 1: Buy 100 at 10 EUR
  5. Participant 2: Sell 350 at 7 EUR

Orders in detail

1. Participant 1: Buy 300 at 8 EUR

ReceiverAction in AgentStrategyServiceContents
Participant 1onOrderStatusUpdateReceivedBuy 300 at 8EUR, ModeReasonCode:INSERT(1); shoutId: 1, transactionId: 1
EverybodyonQuoteUpdateReceivedBid: 8, BidSize: 300, ask: null, askSize: 0, transactionId: 1
EverybodyonOrderbookUpdateReceivedbid1: 8 EUR, bidSize1: 300 transactionId: 1. - all other askN and bidN==null, all other bidSizeN and askSizeN=0

2. Participant 1: Buy 150 at 9 EUR

ReceiverAction in AgentStrategyServiceContents
Participant 1onOrderStatusUpdateReceivedBuy 150 at 9EUR, ModeReasonCode:INSERT(1); shoutId: 2, transactionId: 2
EverybodyonQuoteUpdateReceivedBid: 9, BidSize: 150, ask: null, askSize: 0, transactionId: 2
EverybodyonOrderbookUpdateReceivedbid1: 9 EUR, bidSize1: 150, bid2: 8 EUR, bidSize2: 300, transactionId: 2. - all other askN and bidN==null, all other bidSizeN and askSizeN=0

3. Participant 1: Buy 50 at 9 EUR

ReceiverAction in AgentStrategyServiceContents
Participant 1onOrderStatusUpdateReceivedBuy 50 at 9EUR, ModeReasonCode:INSERT(1); shoutId: 3, transactionId: 3
EverybodyonQuoteUpdateReceivedBid: 9, BidSize: 200, ask: null, askSize: 0, transactionId: 3
EverybodyonOrderbookUpdateReceivedbid1: 9 EUR, bidSize1: 200, bid2: 8 EUR, bidSize2: 300, transactionId: 3. all other askN and bidN==null, all other bidSizeN and askSizeN=0

4. Participant 1: Buy 100 at 10 EUR

ReceiverAction in AgentStrategyServiceContents
Participant 1onOrderStatusUpdateReceivedBuy 100 at 10EUR, ModeReasonCode:INSERT(1); shoutId: 4, transactionId: 4
EverybodyonQuoteUpdateReceivedBid: 10, BidSize: 100, ask: null, askSize: 0, transactionId: 4
EverybodyonOrderbookUpdateReceivedbid1: 10 EUR, bidSize1: 100, bid2: 9 EUR, bidSize2: 200, bid3: 8, bidSize3: 300 transactionId: 4 - all other askN and bidN==null, all other bidSizeN and askSizeN=0

5. Participant 2: Sell 350 at 7 EUR

ReceiverAction in AgentStrategyServiceContents
Participant 2onOrderStatusUpdateReceivedSell 350 at 7EUR; ModeReasonCode:INSERT(1); shoutId: 5, transactionId: 5

5.1 Partial Execution 1

ReceiverAction in AgentStrategyServiceContents
Participant 2onOrderStatusUpdateReceivedSell 100 at 10; ModReasonCode: PARTIALEXECUTION(5); shoutId: 5, transactionId: 5
Participant 2onCashUpdateReceivedchange: 1000, balance: 1000, transactionId: 5
Participant 2onDepotUpdateReceivedchange: -100, balance: -100, transactionId: 5
Participant 1onOrderStatusUpdateReceivedBuy 100 at 10EUR, ModeReasonCode: EXECUTION(4); shoutId: 4, transactionId: 5
Participant 1onCashUpdateReceivedchange: -1000, balance: -1000, transactionId: 5
Participant 1onDepotUpdateReceivedchange: 100, balance: 100, transactionId: 5
EverybodyonTradeUpdateReceivedPrice: 10, Volume 100 transactionId: 5

Note: A trade does not trigger an orderbook update.

5.2 Partial Execution 2

ReceiverAction in AgentStrategyServiceContents
Participant 2onOrderStatusUpdateReceivedSell 150 at 9; ModReasonCode: PARTIALEXECUTION(5); shoutId: 5, transactionId: 5
Participant 2onCashUpdateReceivedchange: 1350, balance: 2350, transactionId: 5
Participant 2onDepotUpdateReceivedchange: -150, balance: -250, transactionId: 5
Participant 1onOrderStatusUpdateReceivedBuy 150 at 9EUR, ModeReasonCode:EXECUTION(4); shoutId: 2, transactionId: 5
Participant 1onCashUpdateReceivedchange: -1350, balance: -2350, transactionId: 5
Participant 1onDepotUpdateReceivedchange: 150, balance: 250, transactionId: 5
EverybodyonTradeUpdateReceivedPrice: 9, Volume 150 transactionId: 5

Note: A trade does not trigger an orderbook update.

5.3 Partial Execution 3

ReceiverAction in AgentStrategyServiceContents
Participant 2onOrderStatusUpdateReceivedSell 50 at 9; ModReasonCode: PARTIALEXECUTION(5); shoutId: 5, transactionId: 5
Participant 2onCashUpdateReceivedchange: 450, balance: 2800, transactionId: 5
Participant 2onDepotUpdateReceivedchange: -50, balance: -300, transactionId: 5
Participant 1onOrderStatusUpdateReceivedBUY 50 at 9; ModReasonCode: EXECUTION(4); shoutId: 3, transactionId: 5
Participant 1onCashUpdateReceivedchange: -450, balance: -2800, transactionId: 5
Participant 1onDepotUpdateReceivedchange: 50, balance: 300, transactionId: 5
EverybodyonTradeUpdateReceivedPrice: 9, Volume 50 transactionId: 5

Note: A trade does not trigger an orderbook update.

5.4 Partial Execution 4

ReceiverAction in AgentStrategyServiceContents
Participant 2onOrderStatusUpdateReceivedSell 50 at 8; ModReasonCode: EXECUTION(4); shoutId: 5, transactionId: 5
Participant 2onCashUpdateReceivedchange: 400, balance: 3200, transactionId: 5
Participant 2onDepotUpdateReceivedchange: -50, balance: -350, transactionId: 5
Participant 1onOrderStatusUpdateReceivedBuy 50 at 8EUR, ModeReasonCode:PARTIALEXECUTION(5); shoutId: 1,
Participant 1onCashUpdateReceivedchange: -400, balance: -3200, transactionId: 5
Participant 1onDepotUpdateReceivedchange: 50, balance: 350, transactionId: 5
EverybodyonTradeUpdateReceivedPrice: 8, Volume 50 transactionId: 5
EverybodyonQuoteUpdateReceivedBid: 8, BidSize: 250, ask: null, askSize: 0, transactionId: 5
EverybodyonOrderbookUpdateReceivedtransactionId: 5, bid1: 8 EUR, bidSize1: 250 - all other askN and bidN==null, all other bidSizeN and askSizeN=0

Note: Only after the last partial execution a new quote and a new orderbook is generated and sent out to all participants.

6. Sequence Diagrams

Sequence Diagrams

This section provides a couple of sequence diagrams to help you understand how client/server communication in TAC Energy works.

Limit Order

This sequence diagram describes what happens when a client issues a shout on an product with an empty orderbook.

Limit Order on same side of orderbook

This sequence diagram describes what happens when several limit orders enter the orderbook on the same side (Ask/Bid).

Trade

This sequence diagram describes what happens when an incoming order in the book matches completely and therefore is fully executed.

Partially executed Limit Order

This sequence diagram describes what happens when an incoming limit order can only be matched for a certain quantity that is lower than the intended quantity.

Partially executed Market Order

This sequence diagram describes what happens when an incoming market order can only be matched for a certain quantity that is lower than the intended quantity. In difference to the limit order the unmatched part of the market order is deleted.

Unmatched Market Order

This sequence diagram describes what happens when an incoming market order can not be matched with any order from the orderbook. The market order is therefore deleted.

Time advancement

This sequence diagram describes the basic logic on a timeslot shift. A regular timeslot shift means that a product is closed, a new product is opened and the time advances.

7. Self Scheduling

Self Scheduling

This section covers how you can compete against other users' agents on the TAC server.

Description & Overview

As registered participant you can self-schedule a new competition on the TAC Server. Other registered are able to view or this competition and can be invited. No user other than you can change the competition setup.

The TAC server will send out a mail to all participants of a competition notifying them that the competition starts soon so that they can prepare their agents in advance. Competitions are queued so that previously registered competitions are executed first. The server will continuously observe the "future competitions" list and execute the first competition in this list whenever the previous competition was finished so that only one competition runs at a time.

Within a grace period users can submit their ready notification before the competition is removed from the "future competitions" list.

Competition States

Created: Initial state after a new competition was created be a registered participant (initiator) and stored in the database.

Scheduled: After the initiator finished adding participants to the competition, he can schedule it for execution by clicking the "start" button in the competion view of the web interface

Initialized: Competitions with state "scheduled" are picked up by a (java quartz) cron job, which then initializes the respectie competition by creating products (timeslots) and by computing all required demand / supply forecasts for it.

Ready: After the competition was initialized, the TAC server sends out a mail to all competition participants asking them to submit a "ready notification" to the server. After the last competition participant submitted the ready notification, the competition state is changed to ready

Running: A competition runner job picks up on "ready" competition after another. During the execution of a competition its state is set to running.

Finished: After a competition is finished regularly, its state is set to finished.

Interrupted: Whenever technical or human interruptions in the competition workflow occur, its state is set to interrupted.

Deleted

Possible Transitions

Created -> Created, Scheduled, Deleted

Scheduled -> Interrupted

Initialized -> Interrupted

Ready -> Interrupted

Running -> Interrupted

Finished -> Created, Deleted

Interrupted -> Created, Deleted

Diagram

8. FAQ

FAQ

Some questions are frequently asked. We tried to answer them here to help you solve one or the other common issue when getting started with the TAC Energy Server and demo client.

I get a LifecycleException or BindException: Protocol handler initialization failed Error. What can I do

This error occurs if you try to run to different programs, e.g. the TAC Energy Server and the TAC Energy Demo client at the same port. By default both programs try listen on port 8080 and this leads to the conflict as ports cannot be shared. Make sure that one of the programs uses a different port. For grails you can use the following command line parameter to change the port:

grails -Dserver.port=8090 run-app

Where can I download the TAC Energy Demo client?

You can download the source code of the client from its development homepage at http://launchpad.net/tacenergydemo

The latest binaries are available for download at the CI Server.

I want to run a TAC Energy server and a TAC Energy demo client on my machine in parallel. What do I have to do?

Make sure that server and client run on different ports. To switch the port for your TAC Energy client from 8080 (default) to e.g. 8090, start the agent with the following command line arguments:

grails -Dserver.port=8090 run-app

For more information on how to install TAC Energy Server and TAC Energy Client on your machine please refer to Installation section of this guide.

If a competition instance is deleted on the server, why is it not automatically deleted on the client too?

The client is owner of his own local data and responsible for handling it. Enforced deletion of (parts of) this data via a server signal might be counterproductive, e.g. in case an agent programmer wants to do some post analysis on the performance of his client based on the data stored in the agent's database.

If you want to automatically delete competition data you can use one of the provided listeners in the AgentStrategyService to accomplish this for example by using the code snippet below.

def onCompetitionReceived(Competition competitionInstance, String rawXml) {
  log.info "Competition received: ${competitionInstance}"

if (competitionInstance.action == ActionType.Stopped || competitionInstance.action == ActionType.Reset) { deleteAllLocalData(competitionInstance) } }

private deleteAllLocalData(Competition competitionInstance) { Forecast.executeUpdate('delete from Forecast f where f.competition = ?', [competitionInstance]) DepotPosition.executeUpdate('delete from DepotPosition d where d.competition = ?', [competitionInstance]) CashPosition.executeUpdate('delete from CashPosition c where c.competition = ?', [competitionInstance]) Orderbook.executeUpdate('delete from Orderbook o where o.competition = ?', [competitionInstance]) Shout.executeUpdate('delete from Shout s where s.competition = ?', [competitionInstance]) TradeLog.executeUpdate('delete from TradeLog t where t.competition = ?', [competitionInstance]) QuoteLog.executeUpdate('delete from QuoteLog q where q.competition = ?', [competitionInstance]) Product.executeUpdate('delete from Product p where p.competition = ?', [competitionInstance]) }

How exactly is the deactivation of future products based on the "Deactivate ahead" option realized?

Example: With the "Deactivate ahead" option set to 1 (default) and a time slot length of 60 minutes (default) trading for products is suspended one hour ahead of competition time. You will see a scenario like this:

Competition Time: 00:00
[00:00-00:59]: Stopped
[01:00-01:59]: Started
[02:00-02:59]: Started

The first time slot is deactivated, and in order to ensure that you will receive a forecast that represents the real energy demand when trading is already deactivated, the competition time has to be 00:00, although you might expect (01:00-01:59) to be deactivated since the competition time is already at 00:00.