Spaces:
Sleeping
Sleeping
File size: 2,310 Bytes
f5cd2d3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | package com.rods.backtestingstrategies.strategy;
import com.rods.backtestingstrategies.entity.Candle;
import com.rods.backtestingstrategies.entity.TradeSignal;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class SmaCrossoverStrategy implements Strategy {
private final int shortPeriod;
private final int longPeriod;
public SmaCrossoverStrategy() {
// Default values (can later be injected / configured)
this.shortPeriod = 20;
this.longPeriod = 50;
}
public SmaCrossoverStrategy(int shortPeriod, int longPeriod) {
if (shortPeriod >= longPeriod) {
throw new IllegalArgumentException("Short period must be less than long period");
}
this.shortPeriod = shortPeriod;
this.longPeriod = longPeriod;
}
@Override
public TradeSignal evaluate(List<Candle> candles, int index) {
Candle candle = candles.get(index);
// Not enough data to evaluate → HOLD with candle context
if (index < longPeriod) {
return TradeSignal.hold();
}
double prevShortSma = sma(candles, index - 1, shortPeriod);
double prevLongSma = sma(candles, index - 1, longPeriod);
double currShortSma = sma(candles, index, shortPeriod);
double currLongSma = sma(candles, index, longPeriod);
// Cross up → BUY
if (prevShortSma <= prevLongSma && currShortSma > currLongSma) {
return TradeSignal.buy(candle);
}
// Cross down → SELL
if (prevShortSma >= prevLongSma && currShortSma < currLongSma) {
return TradeSignal.sell(candle);
}
// No crossover → HOLD
return TradeSignal.hold();
}
/**
* Simple Moving Average at a specific index
*/
private double sma(List<Candle> candles, int index, int period) {
double sum = 0.0;
for (int i = index - period + 1; i <= index; i++) {
sum += candles.get(i).getClosePrice();
}
return sum / period;
}
@Override
public String getName() {
return "SMA Crossover (" + shortPeriod + ", " + longPeriod + ")";
}
@Override
public StrategyType getType() {
return StrategyType.SMA;
}
}
|