Last active
September 23, 2015 10:10
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // 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