郑重声明:股市有风险,投资需谨慎,利用本模型实盘请自行承担风险
MACD是一个指标,具体用法是MACD>0看涨,反之看跌,果真是这样的吗?由于所有的技术指标都基于对历史数据的统计,指标的滞后性也就难免,有时候MACD明明大于0,股价仍然跌,有时候macd小于0,股价仍然涨。 本文基于Adaboost算法提出了一种基于macd的线性阀值分类器作为若分类器,通过在限定的解空间内寻找使得错误率最小的阀值和偏置,这样做避免了训练若分类器的复杂性,经验证,这种方法有效。
关于什么是adaboost算法,这里还需要简单说一下。算法的核心思想是,用大量的若分类器进行决策,采用一定的方法对若分类器的结果进行加权,从而得出一个具有强分类能力的分类器。值得注意的是,在计算若分类器的错误率e的时候,应该针对每个类别分别计算错误率,多个类别的错误率,这里是两类,涨和跌,分别用1和-1表示。每个类别的错误率同时<0.5,这样的弱分类器才合格。好了闲话少说,一下程序完全是Java写的,并没有做什么优化,先跑出结果再说。
首先我们需要一个弱分类器,定义如下:
package implementation;
import java.util.List;
public /**
* 你可以根据自己的需要,继承这个类,实现自己的弱分类器,只需要实现两个方法即可
* @author zhangshiming
*/
abstract class WeakClassifier{
public static final int RIGHT = 1;
public static final int WRONG = 0;
public double weight;//alpha
public final double calculateErrorPositive(double[][] inputX, double[] inputY, int[] rightOrWrong){
double errorTimes = 0;//预测错误的次数
double pnum = 0;
for(int i = 0; i < inputX.length; i++){
if(inputY[i] == 1){
pnum++;
int res = predict(inputX[i], inputY[i]);
if(res == WRONG){
errorTimes++;
}
rightOrWrong[i] = res;
}
}
return errorTimes / pnum;//错误率
}
public final double calculateErrorNegative(double[][] inputX, double[] inputY, int[] rightOrWrong){
double errorTimes = 0;//预测错误的次数
double nnum = 0;
for(int i = 0; i < inputX.length; i++){
if(inputY[i] == -1){
nnum++;
int res = predict(inputX[i], inputY[i]);
if(res == WRONG){
errorTimes++;
}
rightOrWrong[i] = res;
}
}
return errorTimes / nnum;//错误率
}
public final double calculateError(double[][] inputX, double[] inputY, int[] rightOrWrong){
double errorTimes = 0;//预测错误的次数
for(int i = 0; i < inputX.length; i++){
int res = predict(inputX[i], inputY[i]);
if(res == WRONG){
errorTimes++;
}
rightOrWrong[i] = res;
}
return errorTimes / inputY.length;//错误率
}
public final double calculateIR(double[][] inputX, double[] inputY, int[] rightOrWrong,List<double[]> irlist){
double sumIr = 0;
for(int i = 0; i < inputX.length; i++){
if(inputY[i] > 0 && rightOrWrong[i] == WeakClassifier.RIGHT){
sumIr += irlist.get(i)[0];
}
if(inputY[i] < 0 && rightOrWrong[i] == WeakClassifier.WRONG){
sumIr += irlist.get(i)[0];
}
}
return sumIr;
}
//预测正确返回RIGHT,错误返回WRONG
public final int predict(double[] x, double y){
double res = predict(x);
//System.out.println(res);s
if(res == y){
return RIGHT;
}else{
return WRONG;
}
}
public abstract double predict(double[] x);
public abstract void train(double[][] inputX, double[] inputY, double[] weights);
}
这个弱分类器是个抽象类,由你负责实现训练和预测两个抽象方法。如果你了解训练,那么参数是很容易理解的。
接下来我们继承这个类来实现我们的阀值分类器: