/**
* The MIT License (MIT)
*
* Copyright (c) 2014-2017 Marc de Verdelhan & respective authors (see AUTHORS)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package ta4jexamples.walkforward;
import eu.verdelhan.ta4j.AnalysisCriterion;
import eu.verdelhan.ta4j.Strategy;
import eu.verdelhan.ta4j.TimeSeries;
import eu.verdelhan.ta4j.TradingRecord;
import eu.verdelhan.ta4j.analysis.criteria.TotalProfitCriterion;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.joda.time.Period;
import ta4jexamples.loaders.CsvTradesLoader;
import ta4jexamples.strategies.CCICorrectionStrategy;
import ta4jexamples.strategies.GlobalExtremaStrategy;
import ta4jexamples.strategies.MovingMomentumStrategy;
import ta4jexamples.strategies.RSI2Strategy;
/**
* Walk-forward optimization example.
* <p>
* @see http://en.wikipedia.org/wiki/Walk_forward_optimization
* @see http://www.futuresmag.com/2010/04/01/can-your-system-do-the-walk
*/
public class WalkForward {
/**
* @param series the time series
* @return a map (key: strategy, value: name) of trading strategies
*/
public static Map<Strategy, String> buildStrategiesMap(TimeSeries series) {
HashMap<Strategy, String> strategies = new HashMap<Strategy, String>();
strategies.put(CCICorrectionStrategy.buildStrategy(series), "CCI Correction");
strategies.put(GlobalExtremaStrategy.buildStrategy(series), "Global Extrema");
strategies.put(MovingMomentumStrategy.buildStrategy(series), "Moving Momentum");
strategies.put(RSI2Strategy.buildStrategy(series), "RSI-2");
return strategies;
}
public static void main(String[] args) {
// Splitting the series into slices
TimeSeries series = CsvTradesLoader.loadBitstampSeries();
List<TimeSeries> subseries = series.split(Period.hours(6), Period.weeks(1));
// Building the map of strategies
Map<Strategy, String> strategies = buildStrategiesMap(series);
// The analysis criterion
AnalysisCriterion profitCriterion = new TotalProfitCriterion();
for (TimeSeries slice : subseries) {
// For each sub-series...
System.out.println("Sub-series: " + slice.getSeriesPeriodDescription());
for (Map.Entry<Strategy, String> entry : strategies.entrySet()) {
Strategy strategy = entry.getKey();
String name = entry.getValue();
// For each strategy...
TradingRecord tradingRecord = slice.run(strategy);
double profit = profitCriterion.calculate(slice, tradingRecord);
System.out.println("\tProfit for " + name + ": " + profit);
}
Strategy bestStrategy = profitCriterion.chooseBest(slice, new ArrayList<Strategy>(strategies.keySet()));
System.out.println("\t\t--> Best strategy: " + strategies.get(bestStrategy) + "\n");
}
}
}