2013-04-20 1 views
0

Я новичок в scala, поэтому не уверен, как подойти к этой проблеме? В основном я пытаюсь найти скользящие средние кроссоверы для потока котировок. Я не уверен, как добраться до предыдущих значений, чтобы сравнить их с текущими значениями?В Scala как сравнивать текущие значения с предыдущими значениями при обработке потока?

if (fastMovingAverage(n-1) > slowMovingAverage(n-1) && fastMovingAverage(n) < slowMovingAverage(n)) 
then do some action 



package com.example.csv 

import scala.io.Source 


object FileParser { 
    val TIMESTAMP_LOCATION = 3 
    val BID_LOCATION = 4 
    val OFFER_LOCATION = 5 
    val FAST_WINDOW_SIZE = 5 
    val SLOW_WINDOW_SIZE = 10 

    def main(args: Array[String]) = { 
    val records = Source.fromFile("Sample.csv") 
    .getLines() 
    .drop(1) 
    .map(_.split(",")) 
    .takeWhile(_ != null) 
    .sliding(SLOW_WINDOW_SIZE , 1) 
    .foreach(x => movingAverage(x)) 
    } 

    def movingAverage(numbers: Seq[Array[String]]) = { 
    val listOfBids = numbers.map(x => x(BID_LOCATION).toDouble) 
    val slowAverage = listOfBids.reduceLeft(_ + _)/numbers.length 
    val fastListOfBids = listOfBids.takeRight(FAST_WINDOW_SIZE) 
    val fastAverage = fastListOfBids.reduceLeft(_ + _)/fastListOfBids.length 
    println("Slow Average " + slowAverage + " Fast Average " + fastAverage) 
    } 

} 

ответ

5

Короткий ответ заключается в использовании zip операцию на slowAverage и fastAverage объединить списки, а затем найти разность молний элементов. Когда разница изменяется от отрицательного значения до положительного значения, это указывает на то, что быстрая средняя пересекла выше (большую) медленную среднюю.

Вот данные, которые я использовал, и больше пример:

Price  Fast Average(2) Slow Average(4) Diff 
9   
8   8.5  
7   7.5  
6   6.5    7.5    -1 
5   5.5    6.5    -1 
5   5    5.75    -0.75 
6   5.5    5.5    0 
7   6.5    5.75    0.75 
8   7.5    6.5    1 
9   8.5    7.5    1 

Moving Average Crossover Example

Google Docs Ссылка: https://docs.google.com/spreadsheet/ccc?key=0Alfb-wgy-zTddHdwU2stS0U5ZUxtN2cwdWFoeWNPZFE&usp=sharing

Самая последняя цена последней.

Давайте посмотрим его в Scala:

scala> val prices = List(9,8,7,6,5,5,6,7,8,9) 
prices: List[Int] = List(9, 8, 7, 6, 5, 5, 6, 7, 8, 9) 

scala> val fastAverage = prices.sliding(2).toList.map(xs => xs.sum/2.0) 
fastAverage: List[Double] = List(8.5, 7.5, 6.5, 5.5, 5.0, 5.5, 6.5, 7.5, 8.5) 

scala> val slowAverage = prices.sliding(4).toList.map(xs => xs.sum/4.0) 
slowAverage: List[Double] = List(7.5, 6.5, 5.75, 5.5, 5.75, 6.5, 7.5) 

Zip вместе fastAverage и slowAverage, но так как они разных размеров мы берем последние семь fastAverage с takeRight.

scala> val zipped = fastAverage.takeRight(7) zip slowAverage 
zipped: List[(Double, Double)] = List((6.5,7.5), (5.5,6.5), (5.0,5.75), (5.5,5.5), (6.5,5.75), (7.5,6.5), (8.5,7.5)) 

Учитывайте разницу в средних размерах. Переход от отрицательного к положительному (> = 0) указывает на то, что быстрая средняя больше, чем средний средний скользящий средний кроссовер.

scala> zipped.map(x => x._1 - x._2) 
res44: List[Double] = List(-1.0, -1.0, -0.75, 0.0, 0.75, 1.0, 1.0) 
+0

Не используйте 'takeRight' для потоков, так как это может привести к бесконечной или очень длительной оценке. 'drop' скользящего размера окна кажется более подходящим. Возможно, вместо ответа 'List' на' Stream' в этом примере лучше ответить на вопрос. – Leo

Смежные вопросы