Skip to content

Instantly share code, notes, and snippets.

@patbeagan1
Last active June 29, 2021 03:10
Show Gist options
  • Save patbeagan1/8c581b9b84b6c8d286aa7aadae89a25e to your computer and use it in GitHub Desktop.
Save patbeagan1/8c581b9b84b6c8d286aa7aadae89a25e to your computer and use it in GitHub Desktop.
Calculating EMA and MACD - could be used to parse stock data via csv.
fun main(args: Array<String>) = main2(args)
/**
* Simple Moving Average
*/
fun sma(p: Int): (Double) -> Double {
if (p < 1) throw IllegalArgumentException("Period must be a positive integer")
val list = mutableListOf<Double>()
return {
list.add(it)
if (list.size > p) list.removeAt(0)
list.average()
}
}
data class Ref<T>(var ref: T)
/**
* Exponential Moving Average
*/
fun ema(numberOfDays: Int): (Double) -> Double {
if (numberOfDays < 1) throw IllegalArgumentException("Period must be a positive integer")
val list = mutableListOf<Double>()
val previousEMA = Ref(0.0)
return { curr ->
list.add(curr)
when {
list.size == numberOfDays -> {
list.average().also { previousEMA.ref = it }
}
list.size > numberOfDays -> {
val prev = previousEMA.ref
val smoothingFactor = 2.0
val smoothing = smoothingFactor / (numberOfDays + 1)
val ema = (curr * smoothing) + (prev * (1 - smoothing))
ema.also { previousEMA.ref = it }
}
else -> 0.0
}
}
}
fun List<Double>.macd(short: Int, long: Int, signalStart: Int) = sequence {
val emaShort = ema(short)
val emaLong = ema(long)
val emaSignal = ema(signalStart)
val buyfactorStart = long + short
asSequence().forEachIndexed { index, it ->
val e12 = emaShort(it)
val e26 = emaLong(it)
val macd = if (long < index) e12 - e26 else 0.0
val signal = if (long < index) emaSignal(macd) else 0.0
val buyfactor = if (buyfactorStart < index) macd - signal else 0.0
print("${index}\t")
println(listOf(buyfactor, e12, e26, macd, signal))
yield(buyfactor)
}
}
fun main2(args: Array<String>) {
n2.macd(12, 26, 9).forEach { println(it) }
println()
n2.macd(12, 26, 9).drop(26 + 8).take(10).forEach { println(it) }
val value = -0.8739320861266349 == n2.macd(12, 26, 9).toList().last()
println(value)
Thread.sleep(200)
}
val n2 = listOf(
10.4,
10.5,
10.1,
10.48,
10.51,
10.8,
10.8,
10.71,
10.79,
11.21,
11.42,
11.84,
11.75,
10.51,
10.8,
10.8,
10.71,
10.79,
11.21,
11.42,
11.84,
11.75,
10.51,
10.8,
10.8,
10.71,
10.79,
11.21,
11.42,
11.75,
10.51,
10.8,
10.8,
10.71,
10.79,
11.21,
11.42,
11.84,
11.75,
4.0,
4.0,
4.0,
4.0,
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment