Skip to content

Instantly share code, notes, and snippets.

@pfhayes
Created December 4, 2013 05:09
Show Gist options
  • Save pfhayes/7782653 to your computer and use it in GitHub Desktop.
Save pfhayes/7782653 to your computer and use it in GitHub Desktop.
import scala.util.Random
val random = new Random()
def dollarCostValue(initialCapital: Double, prices: List[Double]): Double = {
val closingPrice = prices.last
val dailySpend = initialCapital / prices.length
val sharesOwned = prices.map(dailySpend / _).sum
sharesOwned * closingPrice
}
def lumpSumValue(initialCapital: Double, prices: List[Double]): Double = {
val startingPrice = prices.head
val closingPrice = prices.last
val sharesOwned = initialCapital / startingPrice
sharesOwned * closingPrice
}
// Price either goes up or down a fixed amount each day
def simpleWalkPrices(initialPrice: Double, deviance: Double): Iterator[Double] = {
Iterator.iterate(initialPrice)(price =>
if (random.nextBoolean()) {
price + (deviance * initialPrice)
} else {
price - (deviance * initialPrice)
})
}
// Price goes up or down a random amount each day
def randomWalkPrices(initialPrice: Double, deviance: Double): Iterator[Double] = {
val range = (initialPrice * deviance)
Iterator.iterate(initialPrice)(price => {
val change = random.nextDouble() * 2 * range - range
price + change
})
}
// Price goes up or down a random percent each day
def percentChangePrices(startingPrice: Double, deviance: Double): Iterator[Double] = {
val range = deviance
Iterator.iterate(initialPrice)(price => {
val change = random.nextDouble() * 2 * range - range
price * (1 + change)
})
}
def logNormalPrices(startingPrice: Double, deviance: Double): Iterator[Double] = {
Iterator.iterate(initialPrice)(price => {
price * (math.exp(random.nextGaussian() * deviance))
})
}
val initialPrice = 100.0
val initialCapital = 1000.0
val deviance = 0.05
val days = 100
val numTrials = 10000
def simulate(
strategy: (Double, List[Double]) => Double,
generator: (Double, Double) => Iterator[Double]
): Double = {
val trials = for {
t <- (1 to numTrials)
} yield {
val prices = generator(initialPrice, deviance).take(days).toList
strategy(initialCapital, prices)
}
trials.sum / numTrials
}
def compare(generator: (Double, Double) => Iterator[Double]): Double = {
simulate(lumpSumValue, generator) / simulate(dollarCostValue, generator)
}
println("Simulated ratio for simpleWalk: " + compare(simpleWalkPrices))
println("Simulated ratio for randomWalk: " + compare(randomWalkPrices))
println("Simulated ratio for percentChange: " + compare(percentChangePrices))
println("Simulated ratio for logNormal: " + compare(logNormalPrices))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment