Skip to content

Instantly share code, notes, and snippets.

@pgorzelany
Last active September 23, 2015 10:10
Show Gist options
  • Select an option

  • Save pgorzelany/3843444c91ecb5b6a024 to your computer and use it in GitHub Desktop.

Select an option

Save pgorzelany/3843444c91ecb5b6a024 to your computer and use it in GitHub Desktop.
Contains a collection of methods and data types needed to perform a random walk simulation of a stock price
//
// Created by Piotr Gorzelany on 23/09/15.
// Copyright © 2015 Piotr Gorzelany. All rights reserved.
//
/** Contains a collection of methods and data types needed to perform a random walk simulation of a stock price.
The random walk is based on an asumption of a normal distribution of the stock daily rates of return. */
public struct SPSimulation {
/** Contains stock information needed to perform a simulation */
public struct Stock: CustomStringConvertible {
/** The name of the stock */
public var name: String
/** Stock initial price at T0 */
public var initialPrice: Double
/** Expected standard deviation of the daily return rates of the stock. */
public var standardDeviationOfDailyRateOfReturn: Double
/** Expected mean of the daily return rates. */
public var expectedDailyRateOfReturn: Double
public var description: String {
return "\(name)"
}
}
public class ResultsBase: CustomStringConvertible {
/** The stock of the simulation */
public let stock: Stock
/** Number of days of the simulation */
public let days: Int
public var description: String {
return "Stock: \(stock), days: \(days)"
}
public init(stock: Stock, days: Int) {
self.stock = stock
self.days = days
}
}
public class Results: ResultsBase {
/** The simulated prices */
public lazy var prices: [Double] = {
return [self.stock.initialPrice]
}()
override public var description: String {
return "\(super.description), prices: \(prices)"
}
}
public class Result: ResultsBase {
/** The simulated end price */
public lazy var price: Double = {
return self.stock.initialPrice
}()
override public var description: String {
return price.description
}
}
/** Returns a Gaussian random number. */
private func randomGausian(sigma sigma: Double, mean: Double) -> Double {
var gausians: [Double] = []
let u1 = Double(arc4random()) / Double(UINT32_MAX)
let u2 = Double(arc4random()) / Double(UINT32_MAX)
let f1 = sqrt(-2 * log(u1))
let f2 = 2 * M_PI * u2
gausians.append(f1 * cos(f2) * sigma + mean)
gausians.append(f1 * sin(f2) * sigma + mean)
let randomIndex = Int(arc4random_uniform(UInt32(gausians.count)))
return gausians[randomIndex]
}
/** Returns a random Gaussian daily return rate for the specified stock. */
private func randomGausianDailyRateOfReturnForStock(stock: Stock) -> Double {
return max(-1, randomGausian(sigma: stock.standardDeviationOfDailyRateOfReturn, mean: stock.expectedDailyRateOfReturn))
}
/** Simulates the stock market prices for the specified number of days. Returns a Result object containing an array of the simulated prices. */
public func simulateStockPriceWithAllResults(stock: Stock, days: Int) -> Results {
let results = Results(stock: stock, days: days)
for _ in 0..<days {
results.prices.append((1 + randomGausianDailyRateOfReturnForStock(stock)) * results.prices[results.prices.endIndex - 1])
}
return results
}
/** Simulates the stock market prices for the specified number of days. Returns only the final result. */
public func simulateStockPriceWithEndResult(stock: Stock, days: Int) -> Result {
let result = Result(stock: stock, days:days)
for _ in 0 ..< days {
result.price = (1 + randomGausianDailyRateOfReturnForStock(stock)) * result.price
}
return result
}
}
// USAGE
let appleStock = SPSimulation.Stock(name: "Apple",initialPrice: 10, standardDeviationOfDailyRateOfReturn: 0.01, expectedDailyRateOfReturn: 0.0)
let simulation = SPSimulation()
print(simulation.simulateStockPriceWithAllResults(appleStock, days: 5))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment