/*******************************************************************************
* Copyright (c) 2013 Luigi Sgro. All rights reserved. This
* program and the accompanying materials are made available under the terms of
* the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Luigi Sgro - initial API and implementation
******************************************************************************/
package com.quantcomponents.algo.ta;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import com.quantcomponents.algo.ITradingAgentFactory;
import com.quantcomponents.core.calendar.FlatCalendar;
import com.quantcomponents.core.calendar.ITradingCalendar;
import com.quantcomponents.core.calendar.ITradingCalendarManager;
/**
* Factory for the example algorithm {@link AverageCrossingTradingAgent}.
* It performs configuration validation and creates executable instances of the algorithm
*
*/
public class AverageCrossingTradingAgentFactory implements ITradingAgentFactory {
private static class Configuration {
ITradingCalendar tradingCalendar;
Integer shortAveragePeriods;
Integer longAveragePeriods;
Integer positionSize;
Boolean ignoreLastPeriod;
}
static final String[] INPUT_SERIES_NAMES = new String[] { "stock" };
private static final int DEFAULT_SHORT_AVERAGE_PERIODS = 5;
private static final int DEFAULT_LONG_AVERAGE_PERIODS = 20;
private static final int DEFAULT_POSITION_SIZE = 1;
private volatile ITradingCalendarManager tradingCalendarManager;
public void setTradingCalendarManager(ITradingCalendarManager tradingCalendarManager) {
this.tradingCalendarManager = tradingCalendarManager;
}
@Override
public AverageCrossingTradingAgent createProcessor(Properties properties) {
Map<String, String> messages = new HashMap<String, String>();
Configuration config = parseConfiguration(properties, messages);
return new AverageCrossingTradingAgent(config.tradingCalendar, config.shortAveragePeriods, config.longAveragePeriods, config.positionSize, config.ignoreLastPeriod);
}
@Override
public String[] getConfigurationKeys() {
return new String[] { AverageCrossingTradingAgent.TRADING_CALENDAR_NAME,
AverageCrossingTradingAgent.SHORT_AVERAGE_PERIODS,
AverageCrossingTradingAgent.LONG_AVERAGE_PERIODS,
AverageCrossingTradingAgent.POSITION_SIZE,
AverageCrossingTradingAgent.IGNORE_LAST_PERIOD };
}
@Override
public String[] getInputSeriesNames() {
return INPUT_SERIES_NAMES;
}
@Override
public boolean isConfigurationValid(Properties properties, Map<String, String> messages) {
parseConfiguration(properties, messages);
if (messages.size() > 0) {
return false;
} else {
return true;
}
}
private Configuration parseConfiguration(Properties properties, Map<String, String> messages) {
Configuration config = new Configuration();
String tradingCalendarName = properties.getProperty(AverageCrossingTradingAgent.TRADING_CALENDAR_NAME);
if (tradingCalendarName != null && !tradingCalendarName.trim().equals("")) {
config.tradingCalendar = tradingCalendarManager.tradingCalendarByName(tradingCalendarName);
if (config.tradingCalendar == null) {
messages.put(AverageCrossingTradingAgent.TRADING_CALENDAR_NAME, "Trading calendar not found: " + tradingCalendarName);
}
} else {
config.tradingCalendar = new FlatCalendar();
}
config.shortAveragePeriods = DEFAULT_SHORT_AVERAGE_PERIODS;
String tmp = properties.getProperty(AverageCrossingTradingAgent.SHORT_AVERAGE_PERIODS);
if (tmp != null) {
try {
config.shortAveragePeriods = Integer.parseInt(tmp);
} catch (Exception e) {
messages.put(AverageCrossingTradingAgent.SHORT_AVERAGE_PERIODS, "Short average periods not parseable: " + tmp);
}
}
config.longAveragePeriods = DEFAULT_LONG_AVERAGE_PERIODS;
tmp = properties.getProperty(AverageCrossingTradingAgent.LONG_AVERAGE_PERIODS);
if (tmp != null) {
try {
config.longAveragePeriods = Integer.parseInt(tmp);
} catch (Exception e) {
messages.put(AverageCrossingTradingAgent.LONG_AVERAGE_PERIODS, "Long average periods not parseable: " + tmp);
}
}
config.positionSize = DEFAULT_POSITION_SIZE;
tmp = properties.getProperty(AverageCrossingTradingAgent.POSITION_SIZE);
if (tmp != null) {
try {
config.positionSize = Integer.parseInt(tmp);
} catch (Exception e) {
messages.put(AverageCrossingTradingAgent.POSITION_SIZE, "Position size not parseable: " + tmp);
}
}
config.ignoreLastPeriod = false;
tmp = properties.getProperty(AverageCrossingTradingAgent.IGNORE_LAST_PERIOD);
if (tmp != null) {
config.ignoreLastPeriod = Boolean.valueOf(tmp);
}
return config;
}
}