股市K线图指标算法的代码实现(一)

这几个月在做一个关于证券的项目,项目里一些图表的绘制,包括K线图以及相关指标算法的绘制让我有点为难,毕竟我也不炒股,没接触过过这些东西。原先是使用的ta-lib这个金融库来进行相关的计算。不过有些算法得出的结果有些不太理想(主要是和同花顺的数据进行对比),因此自己动手写了几个算法进行使用。趁现在有时间,记录下计算过程。在计算前首先要明白MA的使用,MA表示移动平均,

即MA(X,10)=  (x1+x2+x3+....+x10)/10;表示最近10天的X的平均数,X为数组,例如X可以取历史收盘价数据。

代码如下:

private void MA(float[] arr,int optInTimePeriod) {
       double ma;
        double closeSum = 0;
        int period;
        for (int i = 0; i < arr.length; i++) {
            closeSum += arr[i];
            if (i >= (optInTimePeriod - 1)) {
                period = i - optInTimePeriod;
                if (period >= 0) {
                    closeSum -= arr[period];
                }
                ma = (float) closeSum / optInTimePeriod;
            }
        }
    }

封装的数据类:

public class ChartDataBean extends BaseBean {
    public double[] open;  //开盘价
    public long[] time;    //时间
    public double[] volume;   //成交量
    public double[] high;    //最高价
    public double[] low;    //最低价
    public double[] close;   //收盘价
    public double[] avgPrice;   //均价
    public double[] price;     //价格
    public boolean isLastPage;   //是否为最后一页数据
    public AskBean askBean;
    public BidBean bidBean;
    public int length = 0;
    public int newLength = 0;
    public double preClose = 1;
}

1.MACD

MACD的图表中包含了dif,dea以及macd三个数据,要计算macd,首先要计算ema,ema表示的是n日的移动平均。

例如:12日EMA的计算:EMA(12) = MA(close,12)

以下以12为快速移动平均值,26为慢速平均值,则 差离值(DIF)的计算:

DIF = EMA(12) - EMA(26) 。

根据差离值计算其9日的EMA,即离差平均值,是所求的DEA值。

DEA = (前一日DEA X 8/10 + 今日DIF X 2/10)

MACD = (DIF-DEA)*2。 

代码如下:

public void setMACD( int shortValue, int longValue, int mValue,) {
        double emaShort = 0.0;
        double emaLong = 0.0;
        double macd;
        double dif;
        double dea = 0.0;
        for (int i = 0; i < mChartData.close.length; i++) {
            if (i == 0) {
                emaShort =mChartData.close[i];
                emaLong = mChartData.close[i];
                dif = 0;
                dea = 0;
                macd = 0;
            } else {
               emaShort = (emaShort * (shortValue - 1) + mChartData.close[i] * 2) / (shortValue + 1);
               emaLong = (emaLong * (longValue - 1) + mChartData.close[i] * 2) / (longValue + 1);
               dif = emaShort - emaLong;
               dea = (dea * (mValue - 1) + dif * 2) / (mValue + 1);
               macd = (dif - dea) * 2;
            }
        }
    }

2.EXPMA

EXPMA=[2*X+(N-1)*Y’]/(N+1),其中X表示的是当日收盘价,N为周期天数

代码如下:

public void EXPMA( int optInTimePeriod) {
        double expma;
        double preExpma = mChartData.close[0];
        double a = 1.0 * 2 / (optInTimePeriod + 1);
        for (int i = 0; i < mChartData.close.length; i++) {
            if (i == 0) {
                expma = mChartData.close[0];
            } else {
                expma = mChartData.close[i] * a + (1 - a) * preExpma;
            }
            preExpma = expma;
        }
    }

3.DMA

DMA涉及到两个数据,DMA,AMA,以下以10为短期平均值,50为长期平均值

DMA=MA(close,10)— MA(close,50)

AMA=MA(DMA,10)

代码如下:

public void setDMA(int shortValue, int longValue, int mValue,List<Entry> firstData, List<Entry> secondData) {
        firstData.clear();
        secondData.clear();
        if (mChartData==null){
            return;
        }
        double[] dma = new double[mChartData.close.length];
        int period;
        double dmaSum = 0;
        double closeLongSum = 0;
        double closeShortSum = 0;
        double closeLongAve;
        double closeShortAve;
        for (int i = 0; i < mChartData.close.length; i++) {
            closeLongSum += mChartData.close[i];
            if (i >= (longValue - shortValue)) {
                period = i - shortValue;
                closeShortSum += mChartData.close[i];
                if (period >= (longValue - shortValue)) {
                    closeShortSum -= mChartData.close[period];
                }
            }
            if (i >= (longValue - 1)) {
                period = i - longValue;
                if (period >= 0) {
                    closeLongSum -= mChartData.close[period];
                }
                closeLongAve = closeLongSum / longValue;
                closeShortAve = closeShortSum / shortValue;
                dma[i] = closeShortAve - closeLongAve;
                dmaSum += dma[i];
                Entry dmaEntry = new Entry(i, (float) dma[i]);
                firstData.add(dmaEntry);
                if (i >= (longValue + mValue - 2)) {
                    period = i - mValue;
                    if (period >= (longValue - 1)) {
                        dmaSum -= dma[period];
                    }
                    Entry amaEntry = new Entry(i, (float) (dmaSum / mValue));
                    secondData.add(amaEntry);
                }
            }
        }
    }

4.DMI

DMI指标共有+DI(即PDI,下同)、-DI(即MDI,下同)、ADX、ADXR四条线,也是它的四个参数值,它分为多空指标(+DI、-DI)和趋向指标(ADX、ADXR)两组指标.
(1)DM表示当日动向,有正动向(+dm)以及负动向(-dm)
+dm = 今日最高价-昨日最高价,如果+dm<0或+dm<=-dm,取+dm = 0;
-dm = 昨日最低价-今日最低价,如果-dm<0或-dm<=+dm,取-dm = 0;

(2)TR表示真实波幅
A、当日的最高价减去当日的最低价的价差。
B、当日的最高价减去前一日的收盘价的价差。
C、当日的最低价减去前一日的收盘价的价差。
TR是A、B、C中的数值最大者

(3) 以12日作为计算周期为例
+DI(12)=(+DM12÷TR12)×100   (DM12表示近12天的DM的和,TR12表示近12天的tr的和)
-DI(12)=(-DM12÷TR12)×100

(4)以6日为周期计算adxr,adx
DX = |(-DM)-(+DM)| / ((-DM)+(+DM))*100;
ADX = MA(DX,6);
ADXR=(当日的ADX+前n日的ADX)÷2
代码如下:
public void setDMI(int m1, int m2,List<Entry> firstData, List<Entry> secondData, List<Entry> thirdData, List<Entry> fourthData) {
        firstData.clear();
        secondData.clear();
        thirdData.clear();
        fourthData.clear();
        if (mChartData==null){
            return;
        }
        double[] plusDi = new double[mChartData.close.length];
        double[] minusDi = new double[mChartData.close.length];
        double[] adx = new double[mChartData.close.length];
        double[] tr = new double[mChartData.close.length];
        double[] plusDm = new double[mChartData.close.length];
        double[] minusDm = new double[mChartData.close.length];
        double[] adxValue = new double[mChartData.close.length];
        int period;
        double adxValueSum = 0;
        plusDi[0] = 0;
        tr[0] = mChartData.high[0] - mChartData.low[0];
        plusDm[0] = 0;
        minusDm[0] = 0;
        double sumPlusDm = 0;
        double sumMinusDm = 0;
        double sumTr = mChartData.high[0] - mChartData.low[0];
        firstData.add(new Entry(0, (float) plusDi[0]));
        secondData.add(new Entry(0, (float) minusDi[0]));
        for (int i = 1; i < mChartData.close.length; i++) {
            plusDm[i] = mChartData.high[i] - mChartData.high[i - 1];
            minusDm[i] = mChartData.low[i - 1] - mChartData.low[i];
            if (plusDm[i] < 0 || plusDm[i] <= minusDm[i]) {
                plusDm[i] = 0;
            }
            if (minusDm[i] < 0 || minusDm[i] <= plusDm[i]) {
                minusDm[i] = 0;
            }
            tr[i] = getAbsMax(mChartData.high[i] - mChartData.low[i], mChartData.high[i] - mChartData.close[i - 1], mChartData.low[i] - mChartData.close[i - 1]);
            sumTr += tr[i];
            sumPlusDm += plusDm[i];
            sumMinusDm += minusDm[i];
            if (i >= (m1 - 1)) {
                period = i - m1;
                if (period >= 0) {
                    sumPlusDm -= plusDm[period];
                    sumMinusDm -= minusDm[period];
                    sumTr -= tr[period];
                }
            }
            plusDi[i] = 100.0 * sumPlusDm / sumTr;
            minusDi[i] = 100 * sumMinusDm / sumTr;
            Entry pdiEntry = new Entry(i, (float) plusDi[i]);
            Entry mdiEntry = new Entry(i, (float) minusDi[i]);
            firstData.add(pdiEntry);
            secondData.add(mdiEntry);
            adxValue[i] = Math.abs(minusDi[i] - plusDi[i]) / (minusDi[i] + plusDi[i]) * 100.0;
            adxValueSum += adxValue[i];
            if (i >= m2) {
                adxValueSum -= adxValue[i - m2];
                adx[i] = adxValueSum / m2;
                Entry adxEntry = new Entry(i, (float) adx[i]);
                thirdData.add(adxEntry);
            }
            if (i >= 2 * m2) {
                Entry adxrEntry = new Entry(i, (float) ((adx[i] + adx[i - m2]) / 2));
                fourthData.add(adxrEntry);
            }
        }
    }
private double getAbsMax(double a, double b, double c) {
        a = Math.abs(a);
        b = Math.abs(b);
        c = Math.abs(c);
        double temp = Math.max(a, b);
        return Math.max(temp, c);
    }


5.OBV
如果当日收盘价比昨日收盘价高,则obv为昨日obv加上今日成交量,反之则减去今日成交量,若二者相等,则不增不减。
代码如下:
public void setOBV() {
        double obv;
        double preObv = 0;
        for (int i = 0; i < mChartData.close.length; i++) {
            if (i == 0) {
                obv = 0;
            } else {
                if (mChartData.close[i] > mChartData.close[i - 1]) {
                    obv = (preObv + mChartData.volume[i]);
                } else if (mChartData.close[i] < mChartData.close[i - 1]) {
                    obv = (preObv - mChartData.volume[i]);
                } else {
                    obv = preObv;
                }
            }
            preObv = obv;
        }
    }









  • 8
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
当使用K近邻算法进行图像分类时,一种常见的方法是将每个图像表示为特征向量,然后使用KNN算法根据特征向量的距离进行分类。以下是一个使用KNN算法实现图片识别的示例代码: ```python import numpy as np from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # 加载图像数据集 def load_dataset(): # TODO: 加载图像数据集,将图像转换为特征向量 # 返回特征矩阵 X 和标签向量 y pass # 划分训练集和测试集 def split_dataset(X, y): X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) return X_train, X_test, y_train, y_test # 使用KNN算法进行图像分类 def image_classification(X_train, X_test, y_train, y_test): knn = KNeighborsClassifier(n_neighbors=5) # 创建KNN分类器对象 knn.fit(X_train, y_train) # 在训练集上训练KNN模型 y_pred = knn.predict(X_test) # 在测试集上进行预测 accuracy = accuracy_score(y_test, y_pred) # 计算准确率 return accuracy def main(): X, y = load_dataset() # 加载图像数据集 X_train, X_test, y_train, y_test = split_dataset(X, y) # 划分训练集和测试集 accuracy = image_classification(X_train, X_test, y_train, y_test) # 使用KNN算法进行图像分类 print("准确率:", accuracy) if __name__ == '__main__': main() ``` 在上述代码中,你需要自行实现 `load_dataset()` 函数来加载图像数据集并将图像转换为特征向量。可以使用图像处理库(如OpenCV)来读取和处理图像,然后将每个图像转换为特征向量。通常,可以使用图像的像素值、颜色直方图、梯度直方图等作为特征。然后,通过调用 `split_dataset()` 函数将数据集划分为训练集和测试集。最后,通过调用 `image_classification()` 函数使用KNN算法进行图像分类,并计算准确率。 请注意,这只是一个示例代码框架,你需要根据你的具体需求和数据集进行相应的实现和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值