AlgoTraderAlgoTrader Documentation

Chapter 4. Creating a Trading Strategy

4.1. AlgoTrader Strategy Wizard
4.2. Adding Strategy Logic

This section will give a quick introduction on how to create a trading strategy by discussing the EMA (Exponential Moving Average) Strategy

Note

The AlgoTrader 30-day free trial already contains the final EMA strategy with all artifacts. In case you want to follow below steps please delete the existing EMA strategy first.

The AlgoTrader Strategy Wizard provides an easy way to automatically create all artifacts necessary for an AlgoTrader based trading strategy. The Wizard can be started via the File / New / Other which will bring up the following screen where the Maven Project wizard can be selected:

On the next screen please click Next.

On the next screen please select the Catalog AlgoTrader select algotrader-archetype-simple and click Next.

On the next screen, the following items have to be entered:

When clicking Finish the Strategy Wizard will create a new Eclipse project called ema.

The Strategy Wizard also generated boiler plate code that needs to be replaced with the actual logic of the EMA strategy.

AlgoTrader strategies are regular Java programs. Due to this any type of java library or add-ons can be used. The EMA strategy is based on the TA4J library which contains a collection of over 100 technical indicators.

Now, double click the EMAService.java file which contains the main logic of the EMA strategy.

The header of the EMAService.java is already generated and no further changes are necessary. It contains the java class name (EMAService) as well as the name of the interface it is derived from (StrategyService). Also, it contains an @Component annotation which marks the Java class as a Spring bean and automatically gets references to necessary service like the OrderService and the LookupService.

Note

For Spring Auto-Wiring to work the package name needs to be ch.algotrader.strategy. If a different package is assigned services (e.g. OrderService and LookupService) will not be available.

@Component

public class EMAService extends StrategyService {

The next part of the EMAService.java contains settings the strategy will use. Three of them are already generated by the Wizard but a few more need to be added.



private final long accountId = 204;
private final long securityId = 860;
private final BigDecimal orderQuantity = new BigDecimal("0.002");
private final int emaPeriodShort = 10;
private final int emaPeriodLong = 20;
private final String defaultFeedType = "BNC";
private TimeSeries series;
private DifferenceIndicator emaDifference;
            
  • The accountId defines the id of the account the strategy will use for trading.

  • The securityId will define the id of the instrument the strategy will trade.

  • The orderQuantity is the number of contracts the strategy will trade.

  • The emaPeriodSort is the look back period of the shorter EMA indicator.

  • The emaPeriodLong is the look back period of the longer EMA indicator.

  • The defaultFeedType indicates we want to get market data from Binance by default.

In addition, the following two fields need to be defined:

  • The TimeSeries object used by the exponential moving average indicators

  • The DifferenceIndicator which will contain the difference between the short and the long EMA

Next, the Java Constructor for the EMAService class needs to be created:

public EMAService() {


        setStrategyName("EMA");
        this.series = new BaseTimeSeries();
        this.series.setMaximumTickCount(this.emaPeriodLong);
        ClosePriceIndicator closePriceIndicator = new ClosePriceIndicator(this.series);
        EMAIndicator emaShort = new EMAIndicator(closePriceIndicator, this.emaPeriodShort);
        EMAIndicator emaLong = new EMAIndicator(closePriceIndicator, this.emaPeriodLong);
        this.emaDifference = new DifferenceIndicator(emaShort, emaLong);
    }
  • First the EMAService constructor sets the name of the Strategy used during the back test.

  • Next the TimeSeries object is initialized to a length of one Bar. In addition, the number of bars the Time Series is set (in this case 20 Bars).

  • Next a ClosePriceIndicator is created which causes the system to look at closing prices of Bar events.

  • Then both the short and the long EMA indicator need to be created by associating them with the ClosePriceIndicator and setting the lookbackPeriod (in this case 10 and 20).

  • Last the DifferenceIndicator needs to be created which contains the difference between the sort EMA and the long EMA indicator.

Next, update the onStart (an AlgoTrader Live Cycle Method) method, which will be called when the strategy starts up.

@Override

public void onStart(final LifecycleEventVO event) {
    getSubscriptionService().subscribeMarketDataEvent(getStrategyName(), this.securityId, defaultFeedType);
}

For further details please visit the AlgoTrader documentation regarding Life Cycle Events.

The onStart methods calls subscribeMarketDataEvent of the SubscriptionService by passing the strategyName and the securityId of the instrument the strategy wants to receive market data for. The SubscriptionService is automatically made available to the strategy through Spring Auto Wiring.

Next, update the onBar method, which will be invoked on every incoming Bar:

@Override

public void onBar(BarVO bar) {
    this.series.addTick(toTick(bar));
    int i = this.series.getEndIndex();
    Decimal currentValue = this.emaDifference.getValue(i);
    Decimal previousValue = this.emaDifference.getValue(- 1);
    if (currentValue.isPositive() && previousValue.isNegativeOrZero()) {
        sendOrder(Side.BUY);
    } else if (currentValue.isNegative() && previousValue.isPositiveOrZero()) {
        sendOrder(Side.SELL);
    }
}
  • The method first calls the addTick method which will add the incoming Bar to the Time Series defined above

  • Next, the index i of the last element of the Time Series is retrieved

  • Then the value of the last and the second-last element of the DifferenceIndicator is retrieved

Then the actual trading rules need to be defined:

  • If the current value of the DifferenceIndicator is positive and the previous value was negative or zero a BUY order is sent. In other words, if the short EMA crossed above the long EMA a BUY order is sent.

  • If the current value of the DifferenceIndicator is negative and the previous value was positive or zero a SELL order is sent. In other words, if the short EMA crossed below the long EMA a SELL order is sent.

The trading logic is depicted in the following chart also.

As the last item, create the sendOrder method, which will take care of constructing an order object and handing it over to the OrderService:

private void sendOrder(Side side) {


    MarketOrderVO order = MarketOrderVOBuilder.create()
            .setStrategyId(getStrategy().getId())
            .setAccountId(this.accountId)
            .setSecurityId(this.securityId)
            .setQuantity(this.orderQuantity)
            .setSide(side)
            .build();
    getOrderService().sendOrder(order);
}

The sendOrder method creates a MarketOrder by using the MarketOrderVOBuilder and assigns the strategyId, the accountId, the securityId, the orderQuantity, the order side (BUY or SELL) and finally calls build to create the MarketOrder object. The order object is then handed over to the OrderService which will execute the order. The OrderService is automatically made available to the strategy through Spring Auto Wiring.

For further details on how order are please visit the AlgoTrader documentation regarding Order Management

In addition the following Java import statements need to be added to the top:



import org.ta4j.core.BaseTimeSeries;
import org.ta4j.core.Decimal;
import org.ta4j.core.TimeSeries;
import org.ta4j.core.indicators.EMAIndicator;
import org.ta4j.core.indicators.helpers.ClosePriceIndicator;
import org.ta4j.core.indicators.helpers.DifferenceIndicator;
import static ch.algotrader.util.TA4JUtil.toTick;
              

The implementation of the trading strategy is now finished a first back test can be started according to Chapter 3, Starting a Trading Strategy.

The EMA strategy is an example strategy based on Java code only. For details on how to build a trading strategy using Esper please visit the AlgoTrader documentation regarding Strategy Development