计算MA和EMA通用方法
def getAverageArray(datas : Array[Double], period : Int, maType : MaType = MaType.Ma, weight : Double = 2.0) : ArrayBuffer[Double] = { val averageArray = ArrayBuffer[Double]() for (i <- 0 until period) averageArray += 0.0 var average = 0.0 for (i <- period until datas.size) { if (average == 0.0) average = datas.slice(0, period).sum / period maType match { case MaType.Ma => average = (average * period - datas.apply(i - period) + datas.apply(i)) / period case MaType.Ema => {val percent = weight / (period + weight - 1);average = datas.apply(i) * percent + average * (1 - percent)} case _ => throw new RuntimeException("unsupport ma type : " + maType) } averageArray += average } averageArray }
计算MA
def calculateMa(wrapperList: Array[StockInfoWrapper], period: Int, maType: MaExporter.MaType, weight: Double, getValue : (StockInfo => java.lang.Double), getAverageMap : (StockInfoWrapper => util.Map[Integer, java.lang.Double])) = { val averageArray = this.getAverageArray(wrapperList.map(wrapper => getValue(wrapper.getStockInfo)).map(_.toDouble), period, maType) for (i <- 0 until wrapperList.length) getAverageMap(wrapperList.apply(i)).put(period, averageArray.apply(i)) }
计算BOLL
def calculateBoll(wrapperList: Array[StockInfoWrapper], period: Int, getValue : (StockInfo => java.lang.Double), getAverageMap : (StockInfoWrapper => util.Map[Integer, java.lang.Double])) = { var md = 0.0 val averageArray = this.getAverageArray(wrapperList.map(wrapper => getValue(wrapper.getStockInfo)).map(_.toDouble), period, MaType.Ma) for (i <- 2 * period until wrapperList.size) { if (md == 0.0) { for (j <- period until 2 * period) md += Math.pow(Math.abs(getValue(wrapperList.apply(j).getStockInfo) - averageArray.apply(j)), 2) md = Math.pow(md / period, 0.5) } if (md > 0) { getAverageMap(wrapperList.apply(i)).put(10000, averageArray.apply(i) + avergeBollDayCount.apply(1) * md) getAverageMap(wrapperList.apply(i)).put(10001, averageArray.apply(i) - avergeBollDayCount.apply(1) * md) md = Math.pow((Math.pow(md, 2) * period - Math.pow(Math.abs(getValue(wrapperList.apply(i - period).getStockInfo) - averageArray.apply(i - period)), 2) + Math.pow(Math.abs(getValue(wrapperList.apply(i).getStockInfo) - averageArray.apply(i)), 2)) / period, 0.5) } } }
计算MACD
def calculateMacd(wrapperList: Array[StockInfoWrapper], period1: Int, period2 : Int, period3 : Int, weight: Double, getValue : (StockInfo => java.lang.Double), getAverageMap : (StockInfoWrapper => util.Map[Integer, java.lang.Double])) = { val average1Array = this.getAverageArray(wrapperList.map(wrapper => getValue(wrapper.getStockInfo)).map(_.toDouble), period1, MaType.Ema, this.weight) val average2Array = this.getAverageArray(wrapperList.map(wrapper => getValue(wrapper.getStockInfo)).map(_.toDouble), period2, MaType.Ema, this.weight) val diffArray = ArrayBuffer[Double]() for (i <- 0 until average1Array.length) diffArray += average1Array.apply(i) - average2Array.apply(i) val averageDiffArray = this.getAverageArray(diffArray.toArray, period3, MaType.Ema, this.weight) for (i <- 1 until wrapperList.length) { getAverageMap(wrapperList.apply(i)).put(0, (diffArray.apply(i) - (averageDiffArray.apply(i - 1) * 0.8 + diffArray.apply(i) * 0.2)) * 2) getAverageMap(wrapperList.apply(i)).put(1, diffArray.apply(i)) getAverageMap(wrapperList.apply(i)).put(2, averageDiffArray.apply(i)) } }
调用
class StockInfo(openingprice : Double, highestprice : Double, lowestprice : Double, closingprice : Double, tradevolumn : Double, transactionvalue : Double){} class StockInfoWrapper(stock : StockInfo) { val averagePriceMap = Map[Int, Double]() val averageVolumnMap = Map[Int, Double]() val averageMacdMap = Map[Int, Double]() } val averagePriceDayCountList = List(18, 28, 50, 250) val averageVolumnDayCountList = List(5) val avergeBollDayCount = List(18, 2) val averageMACDDayCountList = List(12, 26, 9) val weight = 2.0 this.averagePriceDayCountList.foreach(averagePriceDayCount => this.calculateMa(wrapperList, averagePriceDayCount, MaType.Ma, this.weight, _.getClosingprice, _.getAveragePriceMap)) this.averageVolumnDayCountList.foreach(averageVolumnDayCount => this.calculateMa(wrapperList, averageVolumnDayCount, MaType.Ma, this.weight, _.getTradevolumn, _.getAverageVolumnMap)) this.calculateBoll(wrapperList, avergeBollDayCount.apply(0), _.getClosingprice, _.getAveragePriceMap) this.calculateMacd(wrapperList, averageMACDDayCountList.apply(0), averageMACDDayCountList.apply(1), averageMACDDayCountList.apply(2), this.weight, _.getClosingprice, _.getAverageMacdMap)