package org.ripple.power.hft;
import org.ripple.power.hft.def.HPeriod;
import org.ripple.power.hft.def.IHStatistics;
public class CBEntrySignalGenerator implements EntrySignalGenerator {
private int period;
public CBEntrySignalGenerator(int period) {
super();
this.period = period;
}
public double generateSignal(IHStatistics stat) {
// 储存进去对应的数组
double[] close = stat.history(period, HPeriod.Day).getClosingPrice();
// 计算周期channel
double[][] channel = computeChannel(close, period);
double[] channelHighest = channel[0];
double[] channelLowest = channel[1];
// 计算当期close
double currentClose = close[close.length - 1];
// 当期close值是channel高值
// 简单起见信号强度绝对值统一设置成1
if (currentClose == channelHighest[0]) {
return 1;
}
// 当期close值是channel低值
else if (currentClose == channelLowest[0]) {
return -1;
}
// 什么也不做
else {
return 0;
}
}
/**
* 计算channel
*
* @param input
* @param period
* @return 2维数组, [0]是highest数组, [1]是lowest数组
*/
public double[][] computeChannel(double[] input, int period) {
int resultLength = input.length - period + 1;
double[][] out = new double[2][resultLength];
double[] outHighest = new double[resultLength];
double[] outLowest = new double[resultLength];
out[0] = outHighest;
out[1] = outLowest;
// 初始化
double currentLowest = input[0];
double currentHighest = input[0];
for (int i = 0; i < input.length; i++) {
// 超过channel周期, 简化为取上一段channel的第一个值, 如果是最大/小值, 重新计算, 否则取当前元素与最大/小值比较
if (i > period) {
double dropValue = input[i - period - 1];
// 重算最小值
if (dropValue == currentLowest) {
currentLowest = this.computeLowest(input, period, i
- period);
} else {
currentLowest = Math.min(currentLowest, input[i]);
}
// 重算最大值
if (dropValue == currentHighest) {
currentHighest = this.computeHighest(input, period, i
- period);
} else {
currentHighest = Math.max(currentHighest, input[i]);
}
outHighest[i - period] = currentHighest;
outLowest[i - period] = currentLowest;
}
// 未到channel周期, 取当前所有元素的最大/小值
else {
currentLowest = Math.min(currentLowest, input[i]);
currentHighest = Math.max(currentHighest, input[i]);
if (i == period) {
outHighest[0] = currentHighest;
outLowest[0] = currentLowest;
}
}
}
return out;
}
private double computeLowest(double[] input, int period, int start) {
double currentLowest = input[start];
for (int i = start; i < start + period; i++) {
currentLowest = Math.min(currentLowest, input[i]);
}
return currentLowest;
}
private double computeHighest(double[] input, int period, int start) {
double currentHighest = input[start];
for (int i = start; i < start + period; i++) {
currentHighest = Math.max(currentHighest, input[i]);
}
return currentHighest;
}
}