├── .gitignore ├── Notes.pdf ├── images ├── Experiment-01-Prices.png ├── Experiment-02-Belief.png ├── Experiment-02-Prices.png ├── Experiment-03-Belief.png ├── Experiment-03-Prices.png ├── Experiment-04-Belief.png ├── Experiment-04-Prices.png ├── Experiment-05-Belief.png ├── Experiment-05-Prices.png ├── Experiment-06-Belief.png ├── Experiment-06-Prices.png ├── Experiment-07-Belief.png └── Experiment-07-Prices.png ├── Experiment-05 ├── App.config ├── packages.config ├── Program.fs ├── Compute.fs ├── Chart.fs └── Experiment-05.fsproj ├── Experiment-06 ├── App.config ├── packages.config ├── Program.fs ├── Chart.fs ├── Experiment-06.fsproj └── Compute.fs ├── Experiment-07 ├── App.config ├── packages.config ├── Program.fs ├── Chart.fs ├── Experiment-07.fsproj └── Compute.fs ├── Experiment-01 ├── packages.config ├── Program.fs ├── App.config ├── Chart.fs ├── Compute.fs └── Experiment-01.fsproj ├── Experiment-02 ├── packages.config ├── Program.fs ├── App.config ├── Compute.fs ├── Chart.fs └── Experiment-02.fsproj ├── Experiment-03 ├── packages.config ├── Program.fs ├── App.config ├── Chart.fs ├── Experiment-03.fsproj └── Compute.fs ├── Experiment-04 ├── packages.config ├── Program.fs ├── App.config ├── Compute.fs ├── Chart.fs └── Experiment-04.fsproj ├── README.md └── Workspace.sln /.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | build 3 | packages 4 | -------------------------------------------------------------------------------- /Notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkillingsworth/mm-glosten-milgrom/HEAD/Notes.pdf -------------------------------------------------------------------------------- /images/Experiment-01-Prices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkillingsworth/mm-glosten-milgrom/HEAD/images/Experiment-01-Prices.png -------------------------------------------------------------------------------- /images/Experiment-02-Belief.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkillingsworth/mm-glosten-milgrom/HEAD/images/Experiment-02-Belief.png -------------------------------------------------------------------------------- /images/Experiment-02-Prices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkillingsworth/mm-glosten-milgrom/HEAD/images/Experiment-02-Prices.png -------------------------------------------------------------------------------- /images/Experiment-03-Belief.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkillingsworth/mm-glosten-milgrom/HEAD/images/Experiment-03-Belief.png -------------------------------------------------------------------------------- /images/Experiment-03-Prices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkillingsworth/mm-glosten-milgrom/HEAD/images/Experiment-03-Prices.png -------------------------------------------------------------------------------- /images/Experiment-04-Belief.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkillingsworth/mm-glosten-milgrom/HEAD/images/Experiment-04-Belief.png -------------------------------------------------------------------------------- /images/Experiment-04-Prices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkillingsworth/mm-glosten-milgrom/HEAD/images/Experiment-04-Prices.png -------------------------------------------------------------------------------- /images/Experiment-05-Belief.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkillingsworth/mm-glosten-milgrom/HEAD/images/Experiment-05-Belief.png -------------------------------------------------------------------------------- /images/Experiment-05-Prices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkillingsworth/mm-glosten-milgrom/HEAD/images/Experiment-05-Prices.png -------------------------------------------------------------------------------- /images/Experiment-06-Belief.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkillingsworth/mm-glosten-milgrom/HEAD/images/Experiment-06-Belief.png -------------------------------------------------------------------------------- /images/Experiment-06-Prices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkillingsworth/mm-glosten-milgrom/HEAD/images/Experiment-06-Prices.png -------------------------------------------------------------------------------- /images/Experiment-07-Belief.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkillingsworth/mm-glosten-milgrom/HEAD/images/Experiment-07-Belief.png -------------------------------------------------------------------------------- /images/Experiment-07-Prices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jkillingsworth/mm-glosten-milgrom/HEAD/images/Experiment-07-Prices.png -------------------------------------------------------------------------------- /Experiment-05/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Experiment-06/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Experiment-07/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Experiment-01/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Experiment-02/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Experiment-03/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Experiment-04/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Experiment-05/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Experiment-06/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Experiment-07/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Experiment-01/Program.fs: -------------------------------------------------------------------------------- 1 | module Program 2 | 3 | open System 4 | 5 | //------------------------------------------------------------------------------------------------- 6 | 7 | let random = Random() 8 | let policy = Compute.StochasticHi 9 | let result = Compute.generateResults random policy |> Seq.take (25 + 1) |> Seq.toArray 10 | 11 | Chart.renderPrices @"..\..\..\Experiment-01-Prices.png" result 12 | 13 | for (value, bid, ask) in result do 14 | printfn "(%f, %f) %f" bid ask (ask - bid) 15 | -------------------------------------------------------------------------------- /Experiment-02/Program.fs: -------------------------------------------------------------------------------- 1 | module Program 2 | 3 | open System 4 | 5 | //------------------------------------------------------------------------------------------------- 6 | 7 | let random = Random() 8 | let policy = Compute.StochasticHi 9 | let result = Compute.generateResults random policy |> Seq.take (25 + 1) |> Seq.toArray 10 | 11 | Chart.renderPrices @"..\..\..\Experiment-02-Prices.png" result 12 | Chart.renderBelief @"..\..\..\Experiment-02-Belief.png" result.[10] 13 | 14 | for (value, bid, ask, p) in result do 15 | printfn "(%f, %f) %f" bid ask (ask - bid) 16 | -------------------------------------------------------------------------------- /Experiment-03/Program.fs: -------------------------------------------------------------------------------- 1 | module Program 2 | 3 | open System 4 | 5 | //------------------------------------------------------------------------------------------------- 6 | 7 | let random = Random() 8 | let policy = Compute.Stochastic75 9 | let result = Compute.generateResults random policy |> Seq.take (25 + 1) |> Seq.toArray 10 | 11 | Chart.renderPrices @"..\..\..\Experiment-03-Prices.png" result 12 | Chart.renderBelief @"..\..\..\Experiment-03-Belief.png" result.[25] 13 | 14 | for (value, bid, ask, p) in result do 15 | printfn "(%f, %f) %f" bid ask (ask - bid) 16 | -------------------------------------------------------------------------------- /Experiment-04/Program.fs: -------------------------------------------------------------------------------- 1 | module Program 2 | 3 | open System 4 | 5 | //------------------------------------------------------------------------------------------------- 6 | 7 | let random = Random() 8 | let policy = Compute.Stochastic 50.75 9 | let result = Compute.generateResults random policy |> Seq.take (25 + 1) |> Seq.toArray 10 | 11 | Chart.renderPrices @"..\..\..\Experiment-04-Prices.png" result 12 | Chart.renderBelief @"..\..\..\Experiment-04-Belief.png" result.[25] 13 | 14 | for (value, bid, ask, p) in result do 15 | printfn "(%f, %f) %f" bid ask (ask - bid) 16 | -------------------------------------------------------------------------------- /Experiment-05/Program.fs: -------------------------------------------------------------------------------- 1 | module Program 2 | 3 | open System 4 | 5 | //------------------------------------------------------------------------------------------------- 6 | 7 | let random = Random() 8 | let policy = Compute.Stochastic 50.75 9 | let result = Compute.generateResults random policy |> Seq.take (25 + 1) |> Seq.toArray 10 | 11 | Chart.renderPrices @"..\..\..\Experiment-05-Prices.png" result 12 | Chart.renderBelief @"..\..\..\Experiment-05-Belief.png" result.[25] 13 | 14 | for (value, bid, ask, p) in result do 15 | printfn "(%f, %f) %f" bid ask (ask - bid) 16 | -------------------------------------------------------------------------------- /Experiment-01/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Experiment-02/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Experiment-03/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Experiment-04/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Experiment-06/Program.fs: -------------------------------------------------------------------------------- 1 | module Program 2 | 3 | open System 4 | 5 | //------------------------------------------------------------------------------------------------- 6 | 7 | let random = Random() 8 | let policy = Compute.Stochastic 50.75 9 | let result = Compute.generateResults random policy |> Seq.take (25 + 1) |> Seq.toArray 10 | 11 | Chart.renderPrices @"..\..\..\Experiment-06-Prices.png" result 12 | Chart.renderBelief @"..\..\..\Experiment-06-Belief.png" result.[25] 13 | 14 | for (value, bid, ask, p) in result do 15 | let _, _, vBid = bid 16 | let _, _, vAsk = ask 17 | printfn "(%f, %f) %f" vBid vAsk (vAsk - vBid) 18 | -------------------------------------------------------------------------------- /Experiment-07/Program.fs: -------------------------------------------------------------------------------- 1 | module Program 2 | 3 | open System 4 | 5 | //------------------------------------------------------------------------------------------------- 6 | 7 | let random = Random() 8 | let policy = Compute.Stochastic 50.75 9 | let result = Compute.generateResults random policy |> Seq.take (25 + 1) |> Seq.toArray 10 | 11 | Chart.renderPrices @"..\..\..\Experiment-07-Prices.png" result 12 | Chart.renderBelief @"..\..\..\Experiment-07-Belief.png" result.[25] 13 | 14 | for (value, bid, ask, p) in result do 15 | let _, _, vBid = bid 16 | let _, _, vAsk = ask 17 | printfn "(%f, %f) %f" vBid vAsk (vAsk - vBid) 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Overview 2 | 3 | This is a study of the Glosten and Milgrom model for market making. 4 | 5 | #### Experiment 01 6 | 7 | This chart shows the true price and market price over a period of 25 time steps: 8 | 9 | ![Experiment-01-Prices](images/Experiment-01-Prices.png) 10 | 11 | #### Experiment 02 12 | 13 | This chart shows the true price and market price over a period of 25 time steps: 14 | 15 | ![Experiment-02-Prices](images/Experiment-02-Prices.png) 16 | 17 | This chart shows the market maker's belief about the price after 10 time steps: 18 | 19 | ![Experiment-02-Belief](images/Experiment-02-Belief.png) 20 | 21 | #### Experiment 03 22 | 23 | This chart shows the true price and market price over a period of 25 time steps: 24 | 25 | ![Experiment-03-Prices](images/Experiment-03-Prices.png) 26 | 27 | This chart shows the market maker's belief about the price after 25 time steps: 28 | 29 | ![Experiment-03-Belief](images/Experiment-03-Belief.png) 30 | 31 | #### Experiment 04 32 | 33 | This chart shows the true price and market price over a period of 25 time steps: 34 | 35 | ![Experiment-04-Prices](images/Experiment-04-Prices.png) 36 | 37 | This chart shows the market maker's belief about the price after 25 time steps: 38 | 39 | ![Experiment-04-Belief](images/Experiment-04-Belief.png) 40 | 41 | #### Experiment 05 42 | 43 | This chart shows the true price and market price over a period of 25 time steps: 44 | 45 | ![Experiment-05-Prices](images/Experiment-05-Prices.png) 46 | 47 | This chart shows the market maker's belief about the price after 25 time steps: 48 | 49 | ![Experiment-05-Belief](images/Experiment-05-Belief.png) 50 | 51 | #### Experiment 06 52 | 53 | This chart shows the true price and market price over a period of 25 time steps: 54 | 55 | ![Experiment-06-Prices](images/Experiment-06-Prices.png) 56 | 57 | This chart shows the market maker's belief about the price after 25 time steps: 58 | 59 | ![Experiment-06-Belief](images/Experiment-06-Belief.png) 60 | 61 | #### Experiment 07 62 | 63 | This chart shows the true price and market price over a period of 25 time steps: 64 | 65 | ![Experiment-07-Prices](images/Experiment-07-Prices.png) 66 | 67 | This chart shows the market maker's belief about the price after 25 time steps: 68 | 69 | ![Experiment-07-Belief](images/Experiment-07-Belief.png) 70 | 71 | ## References 72 | 73 | * *Bid, Ask, and Transaction Prices in a Specialist Market with Heterogeneously Informed Traders* by Lawrence R. Glosten and Paul R. Milgrom 74 | 75 | * *A Learning Market-Maker in the Glosten-Milgrom Model* by Sanmay Das 76 | 77 | * *Market Microstructure Theory* by Maureen O'Hara 78 | 79 | * *An Intuitive (and Short) Explanation of Bayes' Theorem* by Kalid Azad 80 | -------------------------------------------------------------------------------- /Experiment-01/Chart.fs: -------------------------------------------------------------------------------- 1 | module Chart 2 | 3 | open OxyPlot 4 | open OxyPlot.Axes 5 | open OxyPlot.Series 6 | 7 | //------------------------------------------------------------------------------------------------- 8 | 9 | let private exportToPng path w h model = 10 | 11 | use writeStream = System.IO.File.OpenWrite(path) 12 | let pngExporter = OxyPlot.WindowsForms.PngExporter() 13 | pngExporter.Width <- w 14 | pngExporter.Height <- h 15 | pngExporter.Export(model, writeStream) 16 | 17 | let private defaultColorsToUseForPlots = 18 | 19 | [| OxyColors.Red 20 | OxyColors.Blue 21 | OxyColors.Green 22 | OxyColors.Orange 23 | OxyColors.Purple 24 | OxyColors.Teal |] 25 | 26 | //------------------------------------------------------------------------------------------------- 27 | 28 | let renderPrices path data = 29 | 30 | let model = PlotModel() 31 | 32 | model.DefaultColors <- defaultColorsToUseForPlots 33 | model.LegendBackground <- OxyColors.White 34 | model.LegendBorder <- OxyColors.Gray 35 | model.LegendBorderThickness <- 1.0 36 | model.LegendPlacement <- LegendPlacement.Inside 37 | model.LegendPosition <- LegendPosition.RightTop 38 | model.PlotMargins <- OxyThickness(nan, nan, 10.0, nan) 39 | 40 | let axis = LinearAxis() 41 | axis.Title <- "Time" 42 | axis.Position <- AxisPosition.Bottom 43 | axis.Minimum <- 0.0 44 | axis.Maximum <- float (Array.length data - 1) 45 | axis.MajorStep <- 1.0 46 | axis.MinorStep <- 1.0 47 | axis.MajorGridlineColor <- OxyColors.LightGray 48 | axis.MajorGridlineStyle <- LineStyle.Dot 49 | model.Axes.Add(axis) 50 | 51 | let axis = LinearAxis() 52 | axis.Title <- "Price" 53 | axis.Position <- AxisPosition.Left 54 | axis.Minimum <- Compute.valueLo - 0.05 55 | axis.Maximum <- Compute.valueHi + 0.05 56 | axis.MajorStep <- 0.25 57 | axis.MinorStep <- 0.05 58 | axis.MajorGridlineColor <- OxyColors.LightGray 59 | axis.MajorGridlineStyle <- LineStyle.Dot 60 | axis.MinorGridlineColor <- OxyColors.LightGray 61 | axis.MinorGridlineStyle <- LineStyle.Dot 62 | axis.StringFormat <- "F2" 63 | axis.AxisTitleDistance <- 9.0 64 | model.Axes.Add(axis) 65 | 66 | let series = LineSeries() 67 | series.Title <- "True price" 68 | series.StrokeThickness <- 1.0 69 | data 70 | |> Array.mapi (fun i (value, bid, ask) -> DataPoint(float i, value)) 71 | |> Array.iter series.Points.Add 72 | model.Series.Add(series) 73 | 74 | let series = AreaSeries() 75 | series.Title <- "MM price" 76 | series.StrokeThickness <- 1.0 77 | data 78 | |> Array.mapi (fun i (value, bid, ask) -> DataPoint(float i, bid)) 79 | |> Array.iter series.Points.Add 80 | data 81 | |> Array.mapi (fun i (value, bid, ask) -> DataPoint(float i, ask)) 82 | |> Array.iter series.Points2.Add 83 | model.Series.Add(series) 84 | 85 | model |> exportToPng path 700 400 86 | -------------------------------------------------------------------------------- /Workspace.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Experiment-01", "Experiment-01\Experiment-01.fsproj", "{E7C6B2A2-FAD3-45EC-8553-71A926D5EADD}" 7 | EndProject 8 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Experiment-02", "Experiment-02\Experiment-02.fsproj", "{FB7B94C7-2B26-4D39-9434-81D0D24984F3}" 9 | EndProject 10 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Experiment-03", "Experiment-03\Experiment-03.fsproj", "{79CDCB72-B5DD-4078-9CE3-F1F6E0637B66}" 11 | EndProject 12 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Experiment-04", "Experiment-04\Experiment-04.fsproj", "{0E93BE94-C42F-4DBB-A2C0-BA08F464BDD6}" 13 | EndProject 14 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Experiment-05", "Experiment-05\Experiment-05.fsproj", "{AAF071CF-A53F-4156-B2F7-AF47D62B4690}" 15 | EndProject 16 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Experiment-06", "Experiment-06\Experiment-06.fsproj", "{1E47EC4A-3E5C-4633-8C7A-D1940EB6CB68}" 17 | EndProject 18 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Experiment-07", "Experiment-07\Experiment-07.fsproj", "{E0B8DC52-9D18-4D4D-AC4E-F6A5135CABB4}" 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Release|Any CPU = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {E7C6B2A2-FAD3-45EC-8553-71A926D5EADD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {E7C6B2A2-FAD3-45EC-8553-71A926D5EADD}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {E7C6B2A2-FAD3-45EC-8553-71A926D5EADD}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {E7C6B2A2-FAD3-45EC-8553-71A926D5EADD}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {FB7B94C7-2B26-4D39-9434-81D0D24984F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {FB7B94C7-2B26-4D39-9434-81D0D24984F3}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {FB7B94C7-2B26-4D39-9434-81D0D24984F3}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {FB7B94C7-2B26-4D39-9434-81D0D24984F3}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {79CDCB72-B5DD-4078-9CE3-F1F6E0637B66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {79CDCB72-B5DD-4078-9CE3-F1F6E0637B66}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {79CDCB72-B5DD-4078-9CE3-F1F6E0637B66}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {79CDCB72-B5DD-4078-9CE3-F1F6E0637B66}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {0E93BE94-C42F-4DBB-A2C0-BA08F464BDD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {0E93BE94-C42F-4DBB-A2C0-BA08F464BDD6}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {0E93BE94-C42F-4DBB-A2C0-BA08F464BDD6}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {0E93BE94-C42F-4DBB-A2C0-BA08F464BDD6}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {AAF071CF-A53F-4156-B2F7-AF47D62B4690}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {AAF071CF-A53F-4156-B2F7-AF47D62B4690}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {AAF071CF-A53F-4156-B2F7-AF47D62B4690}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {AAF071CF-A53F-4156-B2F7-AF47D62B4690}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {1E47EC4A-3E5C-4633-8C7A-D1940EB6CB68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {1E47EC4A-3E5C-4633-8C7A-D1940EB6CB68}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {1E47EC4A-3E5C-4633-8C7A-D1940EB6CB68}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {1E47EC4A-3E5C-4633-8C7A-D1940EB6CB68}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {E0B8DC52-9D18-4D4D-AC4E-F6A5135CABB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {E0B8DC52-9D18-4D4D-AC4E-F6A5135CABB4}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {E0B8DC52-9D18-4D4D-AC4E-F6A5135CABB4}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {E0B8DC52-9D18-4D4D-AC4E-F6A5135CABB4}.Release|Any CPU.Build.0 = Release|Any CPU 54 | EndGlobalSection 55 | GlobalSection(SolutionProperties) = preSolution 56 | HideSolutionNode = FALSE 57 | EndGlobalSection 58 | EndGlobal 59 | -------------------------------------------------------------------------------- /Experiment-02/Compute.fs: -------------------------------------------------------------------------------- 1 | module Compute 2 | 3 | open MathNet.Numerics.Distributions 4 | 5 | //------------------------------------------------------------------------------------------------- 6 | 7 | let valueHi = 51.0 8 | let valueLo = 50.0 9 | 10 | let probInitValueHi = 0.5 11 | let probInitValueLo = 0.5 12 | 13 | let probInf = 0.5 14 | let probUnf = 1.0 - probInf 15 | 16 | let probInfSellValueHi = 0.0 17 | let probInfSellValueLo = 1.0 18 | let probInfTakeValueHi = 1.0 19 | let probInfTakeValueLo = 0.0 20 | 21 | let probUnfSellValueHi = 0.5 22 | let probUnfSellValueLo = 0.5 23 | let probUnfTakeValueHi = 0.5 24 | let probUnfTakeValueLo = 0.5 25 | 26 | let probSellValueHi = (probInf * probInfSellValueHi) + (probUnf * probUnfSellValueHi) 27 | let probSellValueLo = (probInf * probInfSellValueLo) + (probUnf * probUnfSellValueLo) 28 | let probTakeValueHi = (probInf * probInfTakeValueHi) + (probUnf * probUnfTakeValueHi) 29 | let probTakeValueLo = (probInf * probInfTakeValueLo) + (probUnf * probUnfTakeValueLo) 30 | 31 | //------------------------------------------------------------------------------------------------- 32 | 33 | let private computeBid pHi pLo = 34 | 35 | let probValueHiSell = (pHi * probSellValueHi) / ((pHi * probSellValueHi) + (pLo * probSellValueLo)) 36 | let probValueLoSell = (pLo * probSellValueLo) / ((pHi * probSellValueHi) + (pLo * probSellValueLo)) 37 | 38 | (valueHi * probValueHiSell) + (valueLo * probValueLoSell) 39 | 40 | let private computeAsk pHi pLo = 41 | 42 | let probValueHiTake = (pHi * probTakeValueHi) / ((pHi * probTakeValueHi) + (pLo * probTakeValueLo)) 43 | let probValueLoTake = (pLo * probTakeValueLo) / ((pHi * probTakeValueHi) + (pLo * probTakeValueLo)) 44 | 45 | (valueHi * probValueHiTake) + (valueLo * probValueLoTake) 46 | 47 | let private executeSell (pHi, pLo) = 48 | 49 | let pHi' = pHi * probSellValueHi / ((pHi * probSellValueHi) + (pLo * probSellValueLo)) 50 | let pLo' = pLo * probSellValueLo / ((pHi * probSellValueHi) + (pLo * probSellValueLo)) 51 | 52 | let bid = computeBid pHi' pLo' 53 | let ask = computeAsk pHi' pLo' 54 | 55 | (bid, ask, (pHi', pLo')) 56 | 57 | let private executeTake (pHi, pLo) = 58 | 59 | let pHi' = pHi * probTakeValueHi / ((pHi * probTakeValueHi) + (pLo * probTakeValueLo)) 60 | let pLo' = pLo * probTakeValueLo / ((pHi * probTakeValueHi) + (pLo * probTakeValueLo)) 61 | 62 | let bid = computeBid pHi' pLo' 63 | let ask = computeAsk pHi' pLo' 64 | 65 | (bid, ask, (pHi', pLo')) 66 | 67 | //------------------------------------------------------------------------------------------------- 68 | 69 | type ExecutionPolicy = 70 | | AlwaysTakeHi 71 | | AlwaysSellLo 72 | | StochasticHi 73 | | StochasticLo 74 | 75 | let private matchStochasticHi random state = 76 | match Sample.continuousUniform 0.0 1.0 random with 77 | | sample when sample < probTakeValueHi 78 | -> executeTake state 79 | | _ -> executeSell state 80 | 81 | let private matchStochasticLo random state = 82 | match Sample.continuousUniform 0.0 1.0 random with 83 | | sample when sample < probSellValueLo 84 | -> executeSell state 85 | | _ -> executeTake state 86 | 87 | let private matchExecutionPolicy random = function 88 | | AlwaysTakeHi -> valueHi, executeTake 89 | | AlwaysSellLo -> valueLo, executeSell 90 | | StochasticHi -> valueHi, matchStochasticHi random 91 | | StochasticLo -> valueLo, matchStochasticLo random 92 | 93 | let generateResults random executionPolicy = 94 | 95 | let pHi = probInitValueHi 96 | let pLo = probInitValueLo 97 | let p = (pHi, pLo) 98 | 99 | let bid = computeBid pHi pLo 100 | let ask = computeAsk pHi pLo 101 | 102 | let value, execute = matchExecutionPolicy random executionPolicy 103 | 104 | let generator p = 105 | let (bid, ask, p) = execute p 106 | Some ((value, bid, ask, p), p) 107 | 108 | seq { 109 | yield (value, bid, ask, p) 110 | yield! Seq.unfold generator p 111 | } 112 | -------------------------------------------------------------------------------- /Experiment-05/Compute.fs: -------------------------------------------------------------------------------- 1 | module Compute 2 | 3 | open MathNet.Numerics.Distributions 4 | open MathNet.Numerics.Integration 5 | 6 | //------------------------------------------------------------------------------------------------- 7 | 8 | let private integrate f lower upper = 9 | let f = System.Func<_,_>(f) 10 | let partitions = 10000 11 | NewtonCotesTrapeziumRule.IntegrateComposite(f, lower, upper, partitions) 12 | 13 | //------------------------------------------------------------------------------------------------- 14 | 15 | let valueUpper = 100.0 16 | let valueLower = 0.0 17 | 18 | let probInit value = Normal.PDF(50.50, 0.5, value) 19 | 20 | let probInf = 0.5 21 | let probUnf = 1.0 - probInf 22 | 23 | let probInfSell value estimate = 1.0 - Normal.CDF(estimate, 0.1, value) 24 | let probInfTake value estimate = 0.0 + Normal.CDF(estimate, 0.1, value) 25 | 26 | let probUnfSell value = 0.5 27 | let probUnfTake value = 0.5 28 | 29 | //------------------------------------------------------------------------------------------------- 30 | 31 | let private computePosteriorSell p = 32 | 33 | let estimate = 34 | let f value = (p value) * value 35 | integrate f valueLower valueUpper 36 | 37 | let probSell value 38 | = (probInf * (probInfSell value estimate)) 39 | + (probUnf * (probUnfSell value)) 40 | 41 | let f value = (p value) * (probSell value) 42 | let probSellOverall = integrate f valueLower valueUpper 43 | let p' value = (f value) / probSellOverall 44 | 45 | p' 46 | 47 | let private computePosteriorTake p = 48 | 49 | let estimate = 50 | let f value = (p value) * value 51 | integrate f valueLower valueUpper 52 | 53 | let probTake value 54 | = (probInf * (probInfTake value estimate)) 55 | + (probUnf * (probUnfTake value)) 56 | 57 | let f value = (p value) * (probTake value) 58 | let probTakeOverall = integrate f valueLower valueUpper 59 | let p' value = (f value) / probTakeOverall 60 | 61 | p' 62 | 63 | //------------------------------------------------------------------------------------------------- 64 | 65 | let private computeBid p = 66 | 67 | let p' = computePosteriorSell p 68 | let f value = (p' value) * value 69 | integrate f valueLower valueUpper 70 | 71 | let private computeAsk p = 72 | 73 | let p' = computePosteriorTake p 74 | let f value = (p' value) * value 75 | integrate f valueLower valueUpper 76 | 77 | //------------------------------------------------------------------------------------------------- 78 | 79 | let private executeTake p = 80 | 81 | let p' = computePosteriorTake p 82 | 83 | let bid = computeBid p' 84 | let ask = computeAsk p' 85 | 86 | (bid, ask, p') 87 | 88 | let private executeSell p = 89 | 90 | let p' = computePosteriorSell p 91 | 92 | let bid = computeBid p' 93 | let ask = computeAsk p' 94 | 95 | (bid, ask, p') 96 | 97 | let private executeNone p = 98 | 99 | let p' = p 100 | 101 | let bid = computeBid p' 102 | let ask = computeAsk p' 103 | 104 | (bid, ask, p') 105 | 106 | //------------------------------------------------------------------------------------------------- 107 | 108 | type ExecutionPolicy = 109 | | Stochastic of float 110 | 111 | let private getValue = function 112 | | Stochastic value -> value 113 | 114 | let private getExecuteFunc random (value, bid, ask) = 115 | match Sample.continuousUniform 0.0 1.0 random with 116 | | sample when (sample < probInf) && (value > ask) -> executeTake 117 | | sample when (sample < probInf) && (value < bid) -> executeSell 118 | | sample when (sample < probInf) -> executeNone 119 | | sample when (sample < probInf + probUnf * 0.50) 120 | -> executeTake 121 | | _ -> executeSell 122 | 123 | let generateResults random executionPolicy = 124 | 125 | let p = probInit 126 | 127 | let bid = computeBid p 128 | let ask = computeAsk p 129 | 130 | let value = getValue executionPolicy 131 | 132 | let generator (bid, ask, p) = 133 | let execute = getExecuteFunc random (value, bid, ask) 134 | let (bid, ask, p) = execute p 135 | Some ((value, bid, ask, p), (bid, ask, p)) 136 | 137 | seq { 138 | yield (value, bid, ask, p) 139 | yield! Seq.unfold generator (bid, ask, p) 140 | } 141 | -------------------------------------------------------------------------------- /Experiment-01/Compute.fs: -------------------------------------------------------------------------------- 1 | module Compute 2 | 3 | open MathNet.Numerics.Distributions 4 | 5 | //------------------------------------------------------------------------------------------------- 6 | 7 | let valueHi = 51.0 8 | let valueLo = 50.0 9 | 10 | let probInitValueHi = 0.5 11 | let probInitValueLo = 0.5 12 | 13 | let probInf = 0.5 14 | let probUnf = 1.0 - probInf 15 | 16 | let probInfSellValueHi = 0.0 17 | let probInfSellValueLo = 1.0 18 | let probInfTakeValueHi = 1.0 19 | let probInfTakeValueLo = 0.0 20 | 21 | let probUnfSellValueHi = 0.5 22 | let probUnfSellValueLo = 0.5 23 | let probUnfTakeValueHi = 0.5 24 | let probUnfTakeValueLo = 0.5 25 | 26 | let probSellValueHi = (probInf * probInfSellValueHi) + (probUnf * probUnfSellValueHi) 27 | let probSellValueLo = (probInf * probInfSellValueLo) + (probUnf * probUnfSellValueLo) 28 | let probTakeValueHi = (probInf * probInfTakeValueHi) + (probUnf * probUnfTakeValueHi) 29 | let probTakeValueLo = (probInf * probInfTakeValueLo) + (probUnf * probUnfTakeValueLo) 30 | 31 | //------------------------------------------------------------------------------------------------- 32 | 33 | let private computeProbValueHi sells takes = 34 | 35 | let sells = float sells 36 | let takes = float takes 37 | 38 | let pHi = probInitValueHi * (probSellValueHi ** sells) * (probTakeValueHi ** takes) 39 | let pLo = probInitValueLo * (probSellValueLo ** sells) * (probTakeValueLo ** takes) 40 | 41 | pHi / (pHi + pLo) 42 | 43 | let private computeProbValueLo sells takes = 44 | 45 | let sells = float sells 46 | let takes = float takes 47 | 48 | let pHi = probInitValueHi * (probSellValueHi ** sells) * (probTakeValueHi ** takes) 49 | let pLo = probInitValueLo * (probSellValueLo ** sells) * (probTakeValueLo ** takes) 50 | 51 | pLo / (pHi + pLo) 52 | 53 | let private computeBid sells takes = 54 | 55 | let probValueHiSell = computeProbValueHi (sells + 1) takes 56 | let probValueLoSell = computeProbValueLo (sells + 1) takes 57 | 58 | (valueHi * probValueHiSell) + (valueLo * probValueLoSell) 59 | 60 | let private computeAsk sells takes = 61 | 62 | let probValueHiTake = computeProbValueHi sells (takes + 1) 63 | let probValueLoTake = computeProbValueLo sells (takes + 1) 64 | 65 | (valueHi * probValueHiTake) + (valueLo * probValueLoTake) 66 | 67 | let private executeSell (sells, takes) = 68 | 69 | let sells' = sells + 1 70 | let takes' = takes 71 | 72 | let bid = computeBid sells' takes' 73 | let ask = computeAsk sells' takes' 74 | 75 | (bid, ask, sells', takes') 76 | 77 | let private executeTake (sells, takes) = 78 | 79 | let sells' = sells 80 | let takes' = takes + 1 81 | 82 | let bid = computeBid sells' takes' 83 | let ask = computeAsk sells' takes' 84 | 85 | (bid, ask, sells', takes') 86 | 87 | //------------------------------------------------------------------------------------------------- 88 | 89 | type ExecutionPolicy = 90 | | AlwaysTakeHi 91 | | AlwaysSellLo 92 | | StochasticHi 93 | | StochasticLo 94 | 95 | let private matchStochasticHi random state = 96 | match Sample.continuousUniform 0.0 1.0 random with 97 | | sample when sample < probTakeValueHi 98 | -> executeTake state 99 | | _ -> executeSell state 100 | 101 | let private matchStochasticLo random state = 102 | match Sample.continuousUniform 0.0 1.0 random with 103 | | sample when sample < probSellValueLo 104 | -> executeSell state 105 | | _ -> executeTake state 106 | 107 | let private matchExecutionPolicy random = function 108 | | AlwaysTakeHi -> valueHi, executeTake 109 | | AlwaysSellLo -> valueLo, executeSell 110 | | StochasticHi -> valueHi, matchStochasticHi random 111 | | StochasticLo -> valueLo, matchStochasticLo random 112 | 113 | let generateResults random executionPolicy = 114 | 115 | let sells = 0 116 | let takes = 0 117 | 118 | let bid = computeBid sells takes 119 | let ask = computeAsk sells takes 120 | 121 | let value, execute = matchExecutionPolicy random executionPolicy 122 | 123 | let generator (sells, takes) = 124 | let (bid, ask, sells, takes) = execute (sells, takes) 125 | Some ((value, bid, ask), (sells, takes)) 126 | 127 | seq { 128 | yield (value, bid, ask) 129 | yield! Seq.unfold generator (sells, takes) 130 | } 131 | -------------------------------------------------------------------------------- /Experiment-04/Compute.fs: -------------------------------------------------------------------------------- 1 | module Compute 2 | 3 | open MathNet.Numerics.Distributions 4 | open MathNet.Numerics.Integration 5 | 6 | //------------------------------------------------------------------------------------------------- 7 | 8 | let private integrate f lower upper = 9 | let f = System.Func<_,_>(f) 10 | let partitions = 10000 11 | NewtonCotesTrapeziumRule.IntegrateComposite(f, lower, upper, partitions) 12 | 13 | //------------------------------------------------------------------------------------------------- 14 | 15 | let valueUpper = 51.0 16 | let valueLower = 50.0 17 | 18 | let probInit value = ContinuousUniform.PDF(valueLower, valueUpper, value) 19 | 20 | let probInf = 0.5 21 | let probUnf = 1.0 - probInf 22 | 23 | let probInfSell value estimate = if value < estimate then 1.0 else 0.0 24 | let probInfTake value estimate = if value > estimate then 1.0 else 0.0 25 | 26 | let probUnfSell value = 0.5 27 | let probUnfTake value = 0.5 28 | 29 | //------------------------------------------------------------------------------------------------- 30 | 31 | let private computePosteriorSell p = 32 | 33 | let estimate = 34 | let f value = (p value) * value 35 | integrate f valueLower valueUpper 36 | 37 | let probSell value 38 | = (probInf * (probInfSell value estimate)) 39 | + (probUnf * (probUnfSell value)) 40 | 41 | let f value = (p value) * (probSell value) 42 | let probSellOverall = integrate f valueLower valueUpper 43 | let p' value = (f value) / probSellOverall 44 | 45 | p' 46 | 47 | let private computePosteriorTake p = 48 | 49 | let estimate = 50 | let f value = (p value) * value 51 | integrate f valueLower valueUpper 52 | 53 | let probTake value 54 | = (probInf * (probInfTake value estimate)) 55 | + (probUnf * (probUnfTake value)) 56 | 57 | let f value = (p value) * (probTake value) 58 | let probTakeOverall = integrate f valueLower valueUpper 59 | let p' value = (f value) / probTakeOverall 60 | 61 | p' 62 | 63 | //------------------------------------------------------------------------------------------------- 64 | 65 | let private computeBid p = 66 | 67 | let p' = computePosteriorSell p 68 | let f value = (p' value) * value 69 | integrate f valueLower valueUpper 70 | 71 | let private computeAsk p = 72 | 73 | let p' = computePosteriorTake p 74 | let f value = (p' value) * value 75 | integrate f valueLower valueUpper 76 | 77 | //------------------------------------------------------------------------------------------------- 78 | 79 | let private executeSell p = 80 | 81 | let p' = computePosteriorSell p 82 | 83 | let bid = computeBid p' 84 | let ask = computeAsk p' 85 | 86 | (bid, ask, p') 87 | 88 | let private executeTake p = 89 | 90 | let p' = computePosteriorTake p 91 | 92 | let bid = computeBid p' 93 | let ask = computeAsk p' 94 | 95 | (bid, ask, p') 96 | 97 | let private executeNone p = 98 | 99 | let p' = p 100 | 101 | let bid = computeBid p' 102 | let ask = computeAsk p' 103 | 104 | (bid, ask, p') 105 | 106 | //------------------------------------------------------------------------------------------------- 107 | 108 | type ExecutionPolicy = 109 | | Stochastic of float 110 | 111 | let private getValue = function 112 | | Stochastic value -> value 113 | 114 | let private getExecuteFunc random (value, bid, ask) = 115 | match Sample.continuousUniform 0.0 1.0 random with 116 | | sample when (sample < probInf) && (value > ask) -> executeTake 117 | | sample when (sample < probInf) && (value < bid) -> executeSell 118 | | sample when (sample < probInf) -> executeNone 119 | | sample when (sample < probInf + probUnf * 0.50) 120 | -> executeTake 121 | | _ -> executeSell 122 | 123 | let generateResults random executionPolicy = 124 | 125 | let p = probInit 126 | 127 | let bid = computeBid p 128 | let ask = computeAsk p 129 | 130 | let value = getValue executionPolicy 131 | 132 | let generator (bid, ask, p) = 133 | let execute = getExecuteFunc random (value, bid, ask) 134 | let (bid, ask, p) = execute p 135 | Some ((value, bid, ask, p), (bid, ask, p)) 136 | 137 | seq { 138 | yield (value, bid, ask, p) 139 | yield! Seq.unfold generator (bid, ask, p) 140 | } 141 | -------------------------------------------------------------------------------- /Experiment-04/Chart.fs: -------------------------------------------------------------------------------- 1 | module Chart 2 | 3 | open OxyPlot 4 | open OxyPlot.Axes 5 | open OxyPlot.Series 6 | 7 | //------------------------------------------------------------------------------------------------- 8 | 9 | let private exportToPng path w h model = 10 | 11 | use writeStream = System.IO.File.OpenWrite(path) 12 | let pngExporter = OxyPlot.WindowsForms.PngExporter() 13 | pngExporter.Width <- w 14 | pngExporter.Height <- h 15 | pngExporter.Export(model, writeStream) 16 | 17 | let private defaultColorsToUseForPlots = 18 | 19 | [| OxyColors.Red 20 | OxyColors.Blue 21 | OxyColors.Green 22 | OxyColors.Orange 23 | OxyColors.Purple 24 | OxyColors.Teal |] 25 | 26 | //------------------------------------------------------------------------------------------------- 27 | 28 | let renderPrices path data = 29 | 30 | let upper = 51.00 31 | let lower = 50.00 32 | 33 | let model = PlotModel() 34 | 35 | model.DefaultColors <- defaultColorsToUseForPlots 36 | model.LegendBackground <- OxyColors.White 37 | model.LegendBorder <- OxyColors.Gray 38 | model.LegendBorderThickness <- 1.0 39 | model.LegendPlacement <- LegendPlacement.Inside 40 | model.LegendPosition <- LegendPosition.RightTop 41 | model.PlotMargins <- OxyThickness(nan, nan, 10.0, nan) 42 | 43 | let axis = LinearAxis() 44 | axis.Title <- "Time" 45 | axis.Position <- AxisPosition.Bottom 46 | axis.Minimum <- 0.0 47 | axis.Maximum <- float (Array.length data - 1) 48 | axis.MajorStep <- 1.0 49 | axis.MinorStep <- 1.0 50 | axis.MajorGridlineColor <- OxyColors.LightGray 51 | axis.MajorGridlineStyle <- LineStyle.Dot 52 | model.Axes.Add(axis) 53 | 54 | let axis = LinearAxis() 55 | axis.Title <- "Price" 56 | axis.Position <- AxisPosition.Left 57 | axis.Minimum <- lower - 0.05 58 | axis.Maximum <- upper + 0.05 59 | axis.MajorStep <- 0.25 60 | axis.MinorStep <- 0.05 61 | axis.MajorGridlineColor <- OxyColors.LightGray 62 | axis.MajorGridlineStyle <- LineStyle.Dot 63 | axis.MinorGridlineColor <- OxyColors.LightGray 64 | axis.MinorGridlineStyle <- LineStyle.Dot 65 | axis.StringFormat <- "F2" 66 | axis.AxisTitleDistance <- 9.0 67 | model.Axes.Add(axis) 68 | 69 | let series = LineSeries() 70 | series.Title <- "True price" 71 | series.StrokeThickness <- 1.0 72 | data 73 | |> Array.mapi (fun i (value, bid, ask, p) -> DataPoint(float i, value)) 74 | |> Array.iter series.Points.Add 75 | model.Series.Add(series) 76 | 77 | let series = AreaSeries() 78 | series.Title <- "MM price" 79 | series.StrokeThickness <- 1.0 80 | data 81 | |> Array.mapi (fun i (value, bid, ask, p) -> DataPoint(float i, bid)) 82 | |> Array.iter series.Points.Add 83 | data 84 | |> Array.mapi (fun i (value, bid, ask, p) -> DataPoint(float i, ask)) 85 | |> Array.iter series.Points2.Add 86 | model.Series.Add(series) 87 | 88 | model |> exportToPng path 700 400 89 | 90 | let renderBelief path data = 91 | 92 | let upper = 51.00 93 | let lower = 50.00 94 | 95 | let (value, bid, ask, p) = data 96 | 97 | let model = PlotModel() 98 | 99 | model.DefaultColors <- defaultColorsToUseForPlots 100 | model.LegendBackground <- OxyColors.White 101 | model.LegendBorder <- OxyColors.Gray 102 | model.LegendBorderThickness <- 1.0 103 | model.LegendPlacement <- LegendPlacement.Inside 104 | model.LegendPosition <- LegendPosition.RightTop 105 | model.PlotMargins <- OxyThickness(nan, nan, 10.0, nan) 106 | 107 | let axis = LinearAxis() 108 | axis.Title <- "Price" 109 | axis.Position <- AxisPosition.Bottom 110 | axis.Minimum <- lower 111 | axis.Maximum <- upper 112 | axis.MajorStep <- 0.25 113 | axis.MinorStep <- 0.05 114 | axis.MajorGridlineColor <- OxyColors.LightGray 115 | axis.MajorGridlineStyle <- LineStyle.Dot 116 | axis.StringFormat <- "F2" 117 | model.Axes.Add(axis) 118 | 119 | let axis = LinearAxis() 120 | axis.Title <- "Belief" 121 | axis.Position <- AxisPosition.Left 122 | axis.Minimum <- 0.0 - 0.5 123 | axis.Maximum <- 10.0 + 0.5 124 | axis.MajorStep <- 2.5 125 | axis.MinorStep <- 0.5 126 | axis.MajorGridlineColor <- OxyColors.LightGray 127 | axis.MajorGridlineStyle <- LineStyle.Dot 128 | axis.MinorGridlineColor <- OxyColors.LightGray 129 | axis.MinorGridlineStyle <- LineStyle.Dot 130 | axis.StringFormat <- "F2" 131 | axis.AxisTitleDistance <- 9.0 132 | model.Axes.Add(axis) 133 | 134 | let series = FunctionSeries(System.Func<_,_>(p), lower, upper, 0.001) 135 | series.Title <- "Probability" 136 | series.StrokeThickness <- 1.0 137 | model.Series.Add(series) 138 | 139 | let series = StemSeries() 140 | series.Title <- "MM price" 141 | series.StrokeThickness <- 1.0 142 | series.Points.Add(DataPoint(bid, p bid)) 143 | series.Points.Add(DataPoint(ask, p ask)) 144 | model.Series.Add(series) 145 | 146 | model |> exportToPng path 700 400 147 | -------------------------------------------------------------------------------- /Experiment-05/Chart.fs: -------------------------------------------------------------------------------- 1 | module Chart 2 | 3 | open OxyPlot 4 | open OxyPlot.Axes 5 | open OxyPlot.Series 6 | 7 | //------------------------------------------------------------------------------------------------- 8 | 9 | let private exportToPng path w h model = 10 | 11 | use writeStream = System.IO.File.OpenWrite(path) 12 | let pngExporter = OxyPlot.WindowsForms.PngExporter() 13 | pngExporter.Width <- w 14 | pngExporter.Height <- h 15 | pngExporter.Export(model, writeStream) 16 | 17 | let private defaultColorsToUseForPlots = 18 | 19 | [| OxyColors.Red 20 | OxyColors.Blue 21 | OxyColors.Green 22 | OxyColors.Orange 23 | OxyColors.Purple 24 | OxyColors.Teal |] 25 | 26 | //------------------------------------------------------------------------------------------------- 27 | 28 | let renderPrices path data = 29 | 30 | let upper = 51.00 31 | let lower = 50.00 32 | 33 | let model = PlotModel() 34 | 35 | model.DefaultColors <- defaultColorsToUseForPlots 36 | model.LegendBackground <- OxyColors.White 37 | model.LegendBorder <- OxyColors.Gray 38 | model.LegendBorderThickness <- 1.0 39 | model.LegendPlacement <- LegendPlacement.Inside 40 | model.LegendPosition <- LegendPosition.RightTop 41 | model.PlotMargins <- OxyThickness(nan, nan, 10.0, nan) 42 | 43 | let axis = LinearAxis() 44 | axis.Title <- "Time" 45 | axis.Position <- AxisPosition.Bottom 46 | axis.Minimum <- 0.0 47 | axis.Maximum <- float (Array.length data - 1) 48 | axis.MajorStep <- 1.0 49 | axis.MinorStep <- 1.0 50 | axis.MajorGridlineColor <- OxyColors.LightGray 51 | axis.MajorGridlineStyle <- LineStyle.Dot 52 | model.Axes.Add(axis) 53 | 54 | let axis = LinearAxis() 55 | axis.Title <- "Price" 56 | axis.Position <- AxisPosition.Left 57 | axis.Minimum <- lower - 0.05 58 | axis.Maximum <- upper + 0.05 59 | axis.MajorStep <- 0.25 60 | axis.MinorStep <- 0.05 61 | axis.MajorGridlineColor <- OxyColors.LightGray 62 | axis.MajorGridlineStyle <- LineStyle.Dot 63 | axis.MinorGridlineColor <- OxyColors.LightGray 64 | axis.MinorGridlineStyle <- LineStyle.Dot 65 | axis.StringFormat <- "F2" 66 | axis.AxisTitleDistance <- 9.0 67 | model.Axes.Add(axis) 68 | 69 | let series = LineSeries() 70 | series.Title <- "True price" 71 | series.StrokeThickness <- 1.0 72 | data 73 | |> Array.mapi (fun i (value, bid, ask, p) -> DataPoint(float i, value)) 74 | |> Array.iter series.Points.Add 75 | model.Series.Add(series) 76 | 77 | let series = AreaSeries() 78 | series.Title <- "MM price" 79 | series.StrokeThickness <- 1.0 80 | data 81 | |> Array.mapi (fun i (value, bid, ask, p) -> DataPoint(float i, bid)) 82 | |> Array.iter series.Points.Add 83 | data 84 | |> Array.mapi (fun i (value, bid, ask, p) -> DataPoint(float i, ask)) 85 | |> Array.iter series.Points2.Add 86 | model.Series.Add(series) 87 | 88 | model |> exportToPng path 700 400 89 | 90 | let renderBelief path data = 91 | 92 | let upper = 51.00 93 | let lower = 50.00 94 | 95 | let (value, bid, ask, p) = data 96 | 97 | let model = PlotModel() 98 | 99 | model.DefaultColors <- defaultColorsToUseForPlots 100 | model.LegendBackground <- OxyColors.White 101 | model.LegendBorder <- OxyColors.Gray 102 | model.LegendBorderThickness <- 1.0 103 | model.LegendPlacement <- LegendPlacement.Inside 104 | model.LegendPosition <- LegendPosition.RightTop 105 | model.PlotMargins <- OxyThickness(nan, nan, 10.0, nan) 106 | 107 | let axis = LinearAxis() 108 | axis.Title <- "Price" 109 | axis.Position <- AxisPosition.Bottom 110 | axis.Minimum <- lower 111 | axis.Maximum <- upper 112 | axis.MajorStep <- 0.25 113 | axis.MinorStep <- 0.05 114 | axis.MajorGridlineColor <- OxyColors.LightGray 115 | axis.MajorGridlineStyle <- LineStyle.Dot 116 | axis.StringFormat <- "F2" 117 | model.Axes.Add(axis) 118 | 119 | let axis = LinearAxis() 120 | axis.Title <- "Belief" 121 | axis.Position <- AxisPosition.Left 122 | axis.Minimum <- 0.0 - 0.5 123 | axis.Maximum <- 10.0 + 0.5 124 | axis.MajorStep <- 2.5 125 | axis.MinorStep <- 0.5 126 | axis.MajorGridlineColor <- OxyColors.LightGray 127 | axis.MajorGridlineStyle <- LineStyle.Dot 128 | axis.MinorGridlineColor <- OxyColors.LightGray 129 | axis.MinorGridlineStyle <- LineStyle.Dot 130 | axis.StringFormat <- "F2" 131 | axis.AxisTitleDistance <- 9.0 132 | model.Axes.Add(axis) 133 | 134 | let series = FunctionSeries(System.Func<_,_>(p), lower, upper, 0.001) 135 | series.Title <- "Probability" 136 | series.StrokeThickness <- 1.0 137 | model.Series.Add(series) 138 | 139 | let series = StemSeries() 140 | series.Title <- "MM price" 141 | series.StrokeThickness <- 1.0 142 | series.Points.Add(DataPoint(bid, p bid)) 143 | series.Points.Add(DataPoint(ask, p ask)) 144 | model.Series.Add(series) 145 | 146 | model |> exportToPng path 700 400 147 | -------------------------------------------------------------------------------- /Experiment-02/Chart.fs: -------------------------------------------------------------------------------- 1 | module Chart 2 | 3 | open OxyPlot 4 | open OxyPlot.Axes 5 | open OxyPlot.Series 6 | 7 | //------------------------------------------------------------------------------------------------- 8 | 9 | let private exportToPng path w h model = 10 | 11 | use writeStream = System.IO.File.OpenWrite(path) 12 | let pngExporter = OxyPlot.WindowsForms.PngExporter() 13 | pngExporter.Width <- w 14 | pngExporter.Height <- h 15 | pngExporter.Export(model, writeStream) 16 | 17 | let private defaultColorsToUseForPlots = 18 | 19 | [| OxyColors.Red 20 | OxyColors.Blue 21 | OxyColors.Green 22 | OxyColors.Orange 23 | OxyColors.Purple 24 | OxyColors.Teal |] 25 | 26 | //------------------------------------------------------------------------------------------------- 27 | 28 | let renderPrices path data = 29 | 30 | let model = PlotModel() 31 | 32 | model.DefaultColors <- defaultColorsToUseForPlots 33 | model.LegendBackground <- OxyColors.White 34 | model.LegendBorder <- OxyColors.Gray 35 | model.LegendBorderThickness <- 1.0 36 | model.LegendPlacement <- LegendPlacement.Inside 37 | model.LegendPosition <- LegendPosition.RightTop 38 | model.PlotMargins <- OxyThickness(nan, nan, 10.0, nan) 39 | 40 | let axis = LinearAxis() 41 | axis.Title <- "Time" 42 | axis.Position <- AxisPosition.Bottom 43 | axis.Minimum <- 0.0 44 | axis.Maximum <- float (Array.length data - 1) 45 | axis.MajorStep <- 1.0 46 | axis.MinorStep <- 1.0 47 | axis.MajorGridlineColor <- OxyColors.LightGray 48 | axis.MajorGridlineStyle <- LineStyle.Dot 49 | model.Axes.Add(axis) 50 | 51 | let axis = LinearAxis() 52 | axis.Title <- "Price" 53 | axis.Position <- AxisPosition.Left 54 | axis.Minimum <- Compute.valueLo - 0.05 55 | axis.Maximum <- Compute.valueHi + 0.05 56 | axis.MajorStep <- 0.25 57 | axis.MinorStep <- 0.05 58 | axis.MajorGridlineColor <- OxyColors.LightGray 59 | axis.MajorGridlineStyle <- LineStyle.Dot 60 | axis.MinorGridlineColor <- OxyColors.LightGray 61 | axis.MinorGridlineStyle <- LineStyle.Dot 62 | axis.StringFormat <- "F2" 63 | axis.AxisTitleDistance <- 9.0 64 | model.Axes.Add(axis) 65 | 66 | let series = LineSeries() 67 | series.Title <- "True price" 68 | series.StrokeThickness <- 1.0 69 | data 70 | |> Array.mapi (fun i (value, bid, ask, p) -> DataPoint(float i, value)) 71 | |> Array.iter series.Points.Add 72 | model.Series.Add(series) 73 | 74 | let series = AreaSeries() 75 | series.Title <- "MM price" 76 | series.StrokeThickness <- 1.0 77 | data 78 | |> Array.mapi (fun i (value, bid, ask, p) -> DataPoint(float i, bid)) 79 | |> Array.iter series.Points.Add 80 | data 81 | |> Array.mapi (fun i (value, bid, ask, p) -> DataPoint(float i, ask)) 82 | |> Array.iter series.Points2.Add 83 | model.Series.Add(series) 84 | 85 | model |> exportToPng path 700 400 86 | 87 | let renderBelief path data = 88 | 89 | let (value, bid, ask, (pHi, pLo)) = data 90 | 91 | let model = PlotModel() 92 | 93 | model.DefaultColors <- defaultColorsToUseForPlots 94 | model.LegendBackground <- OxyColors.White 95 | model.LegendBorder <- OxyColors.Gray 96 | model.LegendBorderThickness <- 1.0 97 | model.LegendPlacement <- LegendPlacement.Inside 98 | model.LegendPosition <- LegendPosition.RightTop 99 | model.PlotMargins <- OxyThickness(nan, nan, 10.0, nan) 100 | 101 | let axis = LinearAxis() 102 | axis.Title <- "Price" 103 | axis.Position <- AxisPosition.Bottom 104 | axis.Minimum <- Compute.valueLo 105 | axis.Maximum <- Compute.valueHi 106 | axis.MajorStep <- 0.25 107 | axis.MinorStep <- 0.05 108 | axis.MajorGridlineColor <- OxyColors.LightGray 109 | axis.MajorGridlineStyle <- LineStyle.Dot 110 | axis.StringFormat <- "F2" 111 | model.Axes.Add(axis) 112 | 113 | let axis = LinearAxis() 114 | axis.Title <- "Belief" 115 | axis.Position <- AxisPosition.Left 116 | axis.Minimum <- 0.0 - 0.05 117 | axis.Maximum <- 1.0 + 0.05 118 | axis.MajorStep <- 0.25 119 | axis.MinorStep <- 0.05 120 | axis.MajorGridlineColor <- OxyColors.LightGray 121 | axis.MajorGridlineStyle <- LineStyle.Dot 122 | axis.MinorGridlineColor <- OxyColors.LightGray 123 | axis.MinorGridlineStyle <- LineStyle.Dot 124 | axis.StringFormat <- "F" 125 | axis.AxisTitleDistance <- 9.0 126 | model.Axes.Add(axis) 127 | 128 | let series = LineSeries() 129 | series.Title <- "Probability" 130 | series.StrokeThickness <- 1.0 131 | series.Points.Add(DataPoint(Compute.valueHi, pHi)) 132 | series.Points.Add(DataPoint(Compute.valueLo, pLo)) 133 | 134 | model.Series.Add(series) 135 | 136 | let series = StemSeries() 137 | series.Title <- "MM price" 138 | series.StrokeThickness <- 1.0 139 | series.Points.Add(DataPoint(bid, 1.0)) 140 | series.Points.Add(DataPoint(ask, 1.0)) 141 | model.Series.Add(series) 142 | 143 | model |> exportToPng path 700 400 144 | -------------------------------------------------------------------------------- /Experiment-03/Chart.fs: -------------------------------------------------------------------------------- 1 | module Chart 2 | 3 | open OxyPlot 4 | open OxyPlot.Axes 5 | open OxyPlot.Series 6 | 7 | //------------------------------------------------------------------------------------------------- 8 | 9 | let private exportToPng path w h model = 10 | 11 | use writeStream = System.IO.File.OpenWrite(path) 12 | let pngExporter = OxyPlot.WindowsForms.PngExporter() 13 | pngExporter.Width <- w 14 | pngExporter.Height <- h 15 | pngExporter.Export(model, writeStream) 16 | 17 | let private defaultColorsToUseForPlots = 18 | 19 | [| OxyColors.Red 20 | OxyColors.Blue 21 | OxyColors.Green 22 | OxyColors.Orange 23 | OxyColors.Purple 24 | OxyColors.Teal |] 25 | 26 | //------------------------------------------------------------------------------------------------- 27 | 28 | let renderPrices path data = 29 | 30 | let model = PlotModel() 31 | 32 | model.DefaultColors <- defaultColorsToUseForPlots 33 | model.LegendBackground <- OxyColors.White 34 | model.LegendBorder <- OxyColors.Gray 35 | model.LegendBorderThickness <- 1.0 36 | model.LegendPlacement <- LegendPlacement.Inside 37 | model.LegendPosition <- LegendPosition.RightTop 38 | model.PlotMargins <- OxyThickness(nan, nan, 10.0, nan) 39 | 40 | let axis = LinearAxis() 41 | axis.Title <- "Time" 42 | axis.Position <- AxisPosition.Bottom 43 | axis.Minimum <- 0.0 44 | axis.Maximum <- float (Array.length data - 1) 45 | axis.MajorStep <- 1.0 46 | axis.MinorStep <- 1.0 47 | axis.MajorGridlineColor <- OxyColors.LightGray 48 | axis.MajorGridlineStyle <- LineStyle.Dot 49 | model.Axes.Add(axis) 50 | 51 | let axis = LinearAxis() 52 | axis.Title <- "Price" 53 | axis.Position <- AxisPosition.Left 54 | axis.Minimum <- Compute.valueLo - 0.05 55 | axis.Maximum <- Compute.valueHi + 0.05 56 | axis.MajorStep <- 0.25 57 | axis.MinorStep <- 0.05 58 | axis.MajorGridlineColor <- OxyColors.LightGray 59 | axis.MajorGridlineStyle <- LineStyle.Dot 60 | axis.MinorGridlineColor <- OxyColors.LightGray 61 | axis.MinorGridlineStyle <- LineStyle.Dot 62 | axis.StringFormat <- "F2" 63 | axis.AxisTitleDistance <- 9.0 64 | model.Axes.Add(axis) 65 | 66 | let series = LineSeries() 67 | series.Title <- "True price" 68 | series.StrokeThickness <- 1.0 69 | data 70 | |> Array.mapi (fun i (value, bid, ask, p) -> DataPoint(float i, value)) 71 | |> Array.iter series.Points.Add 72 | model.Series.Add(series) 73 | 74 | let series = AreaSeries() 75 | series.Title <- "MM price" 76 | series.StrokeThickness <- 1.0 77 | data 78 | |> Array.mapi (fun i (value, bid, ask, p) -> DataPoint(float i, bid)) 79 | |> Array.iter series.Points.Add 80 | data 81 | |> Array.mapi (fun i (value, bid, ask, p) -> DataPoint(float i, ask)) 82 | |> Array.iter series.Points2.Add 83 | model.Series.Add(series) 84 | 85 | model |> exportToPng path 700 400 86 | 87 | let renderBelief path data = 88 | 89 | let (value, bid, ask, (pHi, p75, p50, p25, pLo)) = data 90 | 91 | let model = PlotModel() 92 | 93 | model.DefaultColors <- defaultColorsToUseForPlots 94 | model.LegendBackground <- OxyColors.White 95 | model.LegendBorder <- OxyColors.Gray 96 | model.LegendBorderThickness <- 1.0 97 | model.LegendPlacement <- LegendPlacement.Inside 98 | model.LegendPosition <- LegendPosition.RightTop 99 | model.PlotMargins <- OxyThickness(nan, nan, 10.0, nan) 100 | 101 | let axis = LinearAxis() 102 | axis.Title <- "Price" 103 | axis.Position <- AxisPosition.Bottom 104 | axis.Minimum <- Compute.valueLo 105 | axis.Maximum <- Compute.valueHi 106 | axis.MajorStep <- 0.25 107 | axis.MinorStep <- 0.05 108 | axis.MajorGridlineColor <- OxyColors.LightGray 109 | axis.MajorGridlineStyle <- LineStyle.Dot 110 | axis.StringFormat <- "F2" 111 | model.Axes.Add(axis) 112 | 113 | let axis = LinearAxis() 114 | axis.Title <- "Belief" 115 | axis.Position <- AxisPosition.Left 116 | axis.Minimum <- 0.0 - 0.05 117 | axis.Maximum <- 1.0 + 0.05 118 | axis.MajorStep <- 0.25 119 | axis.MinorStep <- 0.05 120 | axis.MajorGridlineColor <- OxyColors.LightGray 121 | axis.MajorGridlineStyle <- LineStyle.Dot 122 | axis.MinorGridlineColor <- OxyColors.LightGray 123 | axis.MinorGridlineStyle <- LineStyle.Dot 124 | axis.StringFormat <- "F" 125 | axis.AxisTitleDistance <- 9.0 126 | model.Axes.Add(axis) 127 | 128 | let series = LineSeries() 129 | series.Title <- "Probability" 130 | series.StrokeThickness <- 1.0 131 | series.Points.Add(DataPoint(Compute.valueHi, pHi)) 132 | series.Points.Add(DataPoint(Compute.value75, p75)) 133 | series.Points.Add(DataPoint(Compute.value50, p50)) 134 | series.Points.Add(DataPoint(Compute.value25, p25)) 135 | series.Points.Add(DataPoint(Compute.valueLo, pLo)) 136 | 137 | model.Series.Add(series) 138 | 139 | let series = StemSeries() 140 | series.Title <- "MM price" 141 | series.StrokeThickness <- 1.0 142 | series.Points.Add(DataPoint(bid, 1.0)) 143 | series.Points.Add(DataPoint(ask, 1.0)) 144 | model.Series.Add(series) 145 | 146 | model |> exportToPng path 700 400 147 | -------------------------------------------------------------------------------- /Experiment-06/Chart.fs: -------------------------------------------------------------------------------- 1 | module Chart 2 | 3 | open OxyPlot 4 | open OxyPlot.Axes 5 | open OxyPlot.Series 6 | 7 | //------------------------------------------------------------------------------------------------- 8 | 9 | let private exportToPng path w h model = 10 | 11 | use writeStream = System.IO.File.OpenWrite(path) 12 | let pngExporter = OxyPlot.WindowsForms.PngExporter() 13 | pngExporter.Width <- w 14 | pngExporter.Height <- h 15 | pngExporter.Export(model, writeStream) 16 | 17 | let private defaultColorsToUseForPlots = 18 | 19 | [| OxyColors.Red 20 | OxyColors.Blue 21 | OxyColors.Green 22 | OxyColors.Orange 23 | OxyColors.Purple 24 | OxyColors.Teal |] 25 | 26 | //------------------------------------------------------------------------------------------------- 27 | 28 | let renderPrices path data = 29 | 30 | let upper = 51.00 31 | let lower = 50.00 32 | 33 | let model = PlotModel() 34 | 35 | model.DefaultColors <- defaultColorsToUseForPlots 36 | model.LegendBackground <- OxyColors.White 37 | model.LegendBorder <- OxyColors.Gray 38 | model.LegendBorderThickness <- 1.0 39 | model.LegendPlacement <- LegendPlacement.Inside 40 | model.LegendPosition <- LegendPosition.RightTop 41 | model.PlotMargins <- OxyThickness(nan, nan, 10.0, nan) 42 | 43 | let axis = LinearAxis() 44 | axis.Title <- "Time" 45 | axis.Position <- AxisPosition.Bottom 46 | axis.Minimum <- 0.0 47 | axis.Maximum <- float (Array.length data - 1) 48 | axis.MajorStep <- 1.0 49 | axis.MinorStep <- 1.0 50 | axis.MajorGridlineColor <- OxyColors.LightGray 51 | axis.MajorGridlineStyle <- LineStyle.Dot 52 | model.Axes.Add(axis) 53 | 54 | let axis = LinearAxis() 55 | axis.Title <- "Price" 56 | axis.Position <- AxisPosition.Left 57 | axis.Minimum <- lower - 0.05 58 | axis.Maximum <- upper + 0.05 59 | axis.MajorStep <- 0.25 60 | axis.MinorStep <- 0.05 61 | axis.MajorGridlineColor <- OxyColors.LightGray 62 | axis.MajorGridlineStyle <- LineStyle.Dot 63 | axis.MinorGridlineColor <- OxyColors.LightGray 64 | axis.MinorGridlineStyle <- LineStyle.Dot 65 | axis.StringFormat <- "F2" 66 | axis.AxisTitleDistance <- 9.0 67 | model.Axes.Add(axis) 68 | 69 | let series = LineSeries() 70 | series.Title <- "True price" 71 | series.StrokeThickness <- 1.0 72 | data 73 | |> Array.mapi (fun i (value, bid, ask, p) -> DataPoint(float i, value)) 74 | |> Array.iter series.Points.Add 75 | model.Series.Add(series) 76 | 77 | let series = AreaSeries() 78 | series.Title <- "MM price" 79 | series.StrokeThickness <- 1.0 80 | data 81 | |> Array.mapi (fun i (value, (_, _, bid), (_, _, ask), p) -> DataPoint(float i, bid)) 82 | |> Array.iter series.Points.Add 83 | data 84 | |> Array.mapi (fun i (value, (_, _, bid), (_, _, ask), p) -> DataPoint(float i, ask)) 85 | |> Array.iter series.Points2.Add 86 | model.Series.Add(series) 87 | 88 | model |> exportToPng path 700 400 89 | 90 | let renderBelief path data = 91 | 92 | let upper = 51.00 93 | let lower = 50.00 94 | 95 | let (value, bid, ask, p) = data 96 | let iBid, _, vBid = bid 97 | let iAsk, _, vAsk = ask 98 | 99 | let model = PlotModel() 100 | 101 | model.DefaultColors <- defaultColorsToUseForPlots 102 | model.LegendBackground <- OxyColors.White 103 | model.LegendBorder <- OxyColors.Gray 104 | model.LegendBorderThickness <- 1.0 105 | model.LegendPlacement <- LegendPlacement.Inside 106 | model.LegendPosition <- LegendPosition.RightTop 107 | model.PlotMargins <- OxyThickness(nan, nan, 10.0, nan) 108 | 109 | let axis = LinearAxis() 110 | axis.Title <- "Price" 111 | axis.Position <- AxisPosition.Bottom 112 | axis.Minimum <- lower 113 | axis.Maximum <- upper 114 | axis.MajorStep <- 0.25 115 | axis.MinorStep <- 0.05 116 | axis.MajorGridlineColor <- OxyColors.LightGray 117 | axis.MajorGridlineStyle <- LineStyle.Dot 118 | axis.StringFormat <- "F2" 119 | model.Axes.Add(axis) 120 | 121 | let axis = LinearAxis() 122 | axis.Title <- "Belief" 123 | axis.Position <- AxisPosition.Left 124 | axis.Minimum <- 0.0 - 0.5 125 | axis.Maximum <- 10.0 + 0.5 126 | axis.MajorStep <- 2.5 127 | axis.MinorStep <- 0.5 128 | axis.MajorGridlineColor <- OxyColors.LightGray 129 | axis.MajorGridlineStyle <- LineStyle.Dot 130 | axis.MinorGridlineColor <- OxyColors.LightGray 131 | axis.MinorGridlineStyle <- LineStyle.Dot 132 | axis.StringFormat <- "F" 133 | axis.AxisTitleDistance <- 9.0 134 | model.Axes.Add(axis) 135 | 136 | let adjustment = float Compute.scale / Compute.sigma 137 | 138 | let series = LineSeries() 139 | series.Title <- "Probability" 140 | series.StrokeThickness <- 1.0 141 | p 142 | |> Array.mapi (fun i x -> DataPoint(Compute.vMin + float i * Compute.vInc, x * adjustment)) 143 | |> Array.iter series.Points.Add 144 | model.Series.Add(series) 145 | 146 | let series = StemSeries() 147 | series.Title <- "MM price" 148 | series.StrokeThickness <- 1.0 149 | series.Points.Add(DataPoint(vBid, p.[iBid] * adjustment)) 150 | series.Points.Add(DataPoint(vAsk, p.[iAsk] * adjustment)) 151 | model.Series.Add(series) 152 | 153 | model |> exportToPng path 700 400 154 | -------------------------------------------------------------------------------- /Experiment-07/Chart.fs: -------------------------------------------------------------------------------- 1 | module Chart 2 | 3 | open OxyPlot 4 | open OxyPlot.Axes 5 | open OxyPlot.Series 6 | 7 | //------------------------------------------------------------------------------------------------- 8 | 9 | let private exportToPng path w h model = 10 | 11 | use writeStream = System.IO.File.OpenWrite(path) 12 | let pngExporter = OxyPlot.WindowsForms.PngExporter() 13 | pngExporter.Width <- w 14 | pngExporter.Height <- h 15 | pngExporter.Export(model, writeStream) 16 | 17 | let private defaultColorsToUseForPlots = 18 | 19 | [| OxyColors.Red 20 | OxyColors.Blue 21 | OxyColors.Green 22 | OxyColors.Orange 23 | OxyColors.Purple 24 | OxyColors.Teal |] 25 | 26 | //------------------------------------------------------------------------------------------------- 27 | 28 | let renderPrices path data = 29 | 30 | let upper = 51.00 31 | let lower = 50.00 32 | 33 | let model = PlotModel() 34 | 35 | model.DefaultColors <- defaultColorsToUseForPlots 36 | model.LegendBackground <- OxyColors.White 37 | model.LegendBorder <- OxyColors.Gray 38 | model.LegendBorderThickness <- 1.0 39 | model.LegendPlacement <- LegendPlacement.Inside 40 | model.LegendPosition <- LegendPosition.RightTop 41 | model.PlotMargins <- OxyThickness(nan, nan, 10.0, nan) 42 | 43 | let axis = LinearAxis() 44 | axis.Title <- "Time" 45 | axis.Position <- AxisPosition.Bottom 46 | axis.Minimum <- 0.0 47 | axis.Maximum <- float (Array.length data - 1) 48 | axis.MajorStep <- 1.0 49 | axis.MinorStep <- 1.0 50 | axis.MajorGridlineColor <- OxyColors.LightGray 51 | axis.MajorGridlineStyle <- LineStyle.Dot 52 | model.Axes.Add(axis) 53 | 54 | let axis = LinearAxis() 55 | axis.Title <- "Price" 56 | axis.Position <- AxisPosition.Left 57 | axis.Minimum <- lower - 0.05 58 | axis.Maximum <- upper + 0.05 59 | axis.MajorStep <- 0.25 60 | axis.MinorStep <- 0.05 61 | axis.MajorGridlineColor <- OxyColors.LightGray 62 | axis.MajorGridlineStyle <- LineStyle.Dot 63 | axis.MinorGridlineColor <- OxyColors.LightGray 64 | axis.MinorGridlineStyle <- LineStyle.Dot 65 | axis.StringFormat <- "F2" 66 | axis.AxisTitleDistance <- 9.0 67 | model.Axes.Add(axis) 68 | 69 | let series = LineSeries() 70 | series.Title <- "True price" 71 | series.StrokeThickness <- 1.0 72 | data 73 | |> Array.mapi (fun i (value, bid, ask, p) -> DataPoint(float i, value)) 74 | |> Array.iter series.Points.Add 75 | model.Series.Add(series) 76 | 77 | let series = AreaSeries() 78 | series.Title <- "MM price" 79 | series.StrokeThickness <- 1.0 80 | data 81 | |> Array.mapi (fun i (value, (_, _, bid), (_, _, ask), p) -> DataPoint(float i, bid)) 82 | |> Array.iter series.Points.Add 83 | data 84 | |> Array.mapi (fun i (value, (_, _, bid), (_, _, ask), p) -> DataPoint(float i, ask)) 85 | |> Array.iter series.Points2.Add 86 | model.Series.Add(series) 87 | 88 | model |> exportToPng path 700 400 89 | 90 | let renderBelief path data = 91 | 92 | let upper = 51.00 93 | let lower = 50.00 94 | 95 | let (value, bid, ask, p) = data 96 | let iBid, _, vBid = bid 97 | let iAsk, _, vAsk = ask 98 | 99 | let model = PlotModel() 100 | 101 | model.DefaultColors <- defaultColorsToUseForPlots 102 | model.LegendBackground <- OxyColors.White 103 | model.LegendBorder <- OxyColors.Gray 104 | model.LegendBorderThickness <- 1.0 105 | model.LegendPlacement <- LegendPlacement.Inside 106 | model.LegendPosition <- LegendPosition.RightTop 107 | model.PlotMargins <- OxyThickness(nan, nan, 10.0, nan) 108 | 109 | let axis = LinearAxis() 110 | axis.Title <- "Price" 111 | axis.Position <- AxisPosition.Bottom 112 | axis.Minimum <- lower 113 | axis.Maximum <- upper 114 | axis.MajorStep <- 0.25 115 | axis.MinorStep <- 0.05 116 | axis.MajorGridlineColor <- OxyColors.LightGray 117 | axis.MajorGridlineStyle <- LineStyle.Dot 118 | axis.StringFormat <- "F2" 119 | model.Axes.Add(axis) 120 | 121 | let axis = LinearAxis() 122 | axis.Title <- "Belief" 123 | axis.Position <- AxisPosition.Left 124 | axis.Minimum <- 0.0 - 0.5 125 | axis.Maximum <- 10.0 + 0.5 126 | axis.MajorStep <- 2.5 127 | axis.MinorStep <- 0.5 128 | axis.MajorGridlineColor <- OxyColors.LightGray 129 | axis.MajorGridlineStyle <- LineStyle.Dot 130 | axis.MinorGridlineColor <- OxyColors.LightGray 131 | axis.MinorGridlineStyle <- LineStyle.Dot 132 | axis.StringFormat <- "F" 133 | axis.AxisTitleDistance <- 9.0 134 | model.Axes.Add(axis) 135 | 136 | let adjustment = float Compute.scale / Compute.sigma 137 | 138 | let series = LineSeries() 139 | series.Title <- "Probability" 140 | series.StrokeThickness <- 1.0 141 | p 142 | |> Array.mapi (fun i x -> DataPoint(Compute.vMin + float i * Compute.vInc, x * adjustment)) 143 | |> Array.iter series.Points.Add 144 | model.Series.Add(series) 145 | 146 | let series = StemSeries() 147 | series.Title <- "MM price" 148 | series.StrokeThickness <- 1.0 149 | series.Points.Add(DataPoint(vBid, p.[iBid] * adjustment)) 150 | series.Points.Add(DataPoint(vAsk, p.[iAsk] * adjustment)) 151 | model.Series.Add(series) 152 | 153 | model |> exportToPng path 700 400 154 | -------------------------------------------------------------------------------- /Experiment-01/Experiment-01.fsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 2.0 8 | e7c6b2a2-fad3-45ec-8553-71a926d5eadd 9 | Exe 10 | Experiment_01 11 | Experiment_01 12 | v4.6 13 | true 14 | 4.4.0.0 15 | Experiment-01 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | false 23 | ..\build\bin 24 | $(BaseOutputPath)\$(Platform)\$(Configuration)\ 25 | ..\build\obj 26 | $(BaseIntermediateOutputPath)\$(Platform)\$(Configuration)\ 27 | DEBUG;TRACE 28 | 3 29 | AnyCPU 30 | 31 | 32 | false 33 | 34 | 35 | pdbonly 36 | true 37 | true 38 | ..\build\bin 39 | $(BaseOutputPath)\$(Platform)\$(Configuration)\ 40 | ..\build\obj 41 | $(BaseIntermediateOutputPath)\$(Platform)\$(Configuration)\ 42 | TRACE 43 | 3 44 | AnyCPU 45 | 46 | 47 | false 48 | 49 | 50 | 11 51 | 52 | 53 | 54 | 55 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets 56 | 57 | 58 | 59 | 60 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | ..\packages\MathNet.Numerics.3.7.0\lib\net40\MathNet.Numerics.dll 75 | True 76 | 77 | 78 | ..\packages\MathNet.Numerics.FSharp.3.7.0\lib\net40\MathNet.Numerics.FSharp.dll 79 | True 80 | 81 | 82 | 83 | True 84 | 85 | 86 | ..\packages\OxyPlot.Core.2014.1.546\lib\portable-net4+sl4+wp71+win8\OxyPlot.dll 87 | True 88 | 89 | 90 | ..\packages\OxyPlot.WindowsForms.2014.1.546\lib\net45\OxyPlot.WindowsForms.dll 91 | True 92 | 93 | 94 | 95 | 96 | 97 | 98 | 105 | -------------------------------------------------------------------------------- /Experiment-02/Experiment-02.fsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 2.0 8 | fb7b94c7-2b26-4d39-9434-81d0d24984f3 9 | Exe 10 | Experiment_02 11 | Experiment_02 12 | v4.6 13 | true 14 | 4.4.0.0 15 | Experiment-02 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | false 23 | ..\build\bin 24 | $(BaseOutputPath)\$(Platform)\$(Configuration)\ 25 | ..\build\obj 26 | $(BaseIntermediateOutputPath)\$(Platform)\$(Configuration)\ 27 | DEBUG;TRACE 28 | 3 29 | AnyCPU 30 | 31 | 32 | false 33 | 34 | 35 | pdbonly 36 | true 37 | true 38 | ..\build\bin 39 | $(BaseOutputPath)\$(Platform)\$(Configuration)\ 40 | ..\build\obj 41 | $(BaseIntermediateOutputPath)\$(Platform)\$(Configuration)\ 42 | TRACE 43 | 3 44 | AnyCPU 45 | 46 | 47 | false 48 | 49 | 50 | 11 51 | 52 | 53 | 54 | 55 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets 56 | 57 | 58 | 59 | 60 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | ..\packages\MathNet.Numerics.3.7.0\lib\net40\MathNet.Numerics.dll 75 | True 76 | 77 | 78 | ..\packages\MathNet.Numerics.FSharp.3.7.0\lib\net40\MathNet.Numerics.FSharp.dll 79 | True 80 | 81 | 82 | 83 | True 84 | 85 | 86 | ..\packages\OxyPlot.Core.2014.1.546\lib\portable-net4+sl4+wp71+win8\OxyPlot.dll 87 | True 88 | 89 | 90 | ..\packages\OxyPlot.WindowsForms.2014.1.546\lib\net45\OxyPlot.WindowsForms.dll 91 | True 92 | 93 | 94 | 95 | 96 | 97 | 98 | 105 | -------------------------------------------------------------------------------- /Experiment-03/Experiment-03.fsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 2.0 8 | 79cdcb72-b5dd-4078-9ce3-f1f6e0637b66 9 | Exe 10 | Experiment_03 11 | Experiment_03 12 | v4.6 13 | true 14 | 4.4.0.0 15 | Experiment-03 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | false 23 | ..\build\bin 24 | $(BaseOutputPath)\$(Platform)\$(Configuration)\ 25 | ..\build\obj 26 | $(BaseIntermediateOutputPath)\$(Platform)\$(Configuration)\ 27 | DEBUG;TRACE 28 | 3 29 | AnyCPU 30 | 31 | 32 | false 33 | 34 | 35 | pdbonly 36 | true 37 | true 38 | ..\build\bin 39 | $(BaseOutputPath)\$(Platform)\$(Configuration)\ 40 | ..\build\obj 41 | $(BaseIntermediateOutputPath)\$(Platform)\$(Configuration)\ 42 | TRACE 43 | 3 44 | AnyCPU 45 | 46 | 47 | false 48 | 49 | 50 | 11 51 | 52 | 53 | 54 | 55 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets 56 | 57 | 58 | 59 | 60 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | ..\packages\MathNet.Numerics.3.7.0\lib\net40\MathNet.Numerics.dll 75 | True 76 | 77 | 78 | ..\packages\MathNet.Numerics.FSharp.3.7.0\lib\net40\MathNet.Numerics.FSharp.dll 79 | True 80 | 81 | 82 | 83 | True 84 | 85 | 86 | ..\packages\OxyPlot.Core.2014.1.546\lib\portable-net4+sl4+wp71+win8\OxyPlot.dll 87 | True 88 | 89 | 90 | ..\packages\OxyPlot.WindowsForms.2014.1.546\lib\net45\OxyPlot.WindowsForms.dll 91 | True 92 | 93 | 94 | 95 | 96 | 97 | 98 | 105 | -------------------------------------------------------------------------------- /Experiment-04/Experiment-04.fsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 2.0 8 | 0e93be94-c42f-4dbb-a2c0-ba08f464bdd6 9 | Exe 10 | Experiment_04 11 | Experiment_04 12 | v4.6 13 | true 14 | 4.4.0.0 15 | Experiment-04 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | false 23 | ..\build\bin 24 | $(BaseOutputPath)\$(Platform)\$(Configuration)\ 25 | ..\build\obj 26 | $(BaseIntermediateOutputPath)\$(Platform)\$(Configuration)\ 27 | DEBUG;TRACE 28 | 3 29 | AnyCPU 30 | 31 | 32 | false 33 | 34 | 35 | pdbonly 36 | true 37 | true 38 | ..\build\bin 39 | $(BaseOutputPath)\$(Platform)\$(Configuration)\ 40 | ..\build\obj 41 | $(BaseIntermediateOutputPath)\$(Platform)\$(Configuration)\ 42 | TRACE 43 | 3 44 | AnyCPU 45 | 46 | 47 | false 48 | 49 | 50 | 11 51 | 52 | 53 | 54 | 55 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets 56 | 57 | 58 | 59 | 60 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | ..\packages\MathNet.Numerics.3.7.0\lib\net40\MathNet.Numerics.dll 75 | True 76 | 77 | 78 | ..\packages\MathNet.Numerics.FSharp.3.7.0\lib\net40\MathNet.Numerics.FSharp.dll 79 | True 80 | 81 | 82 | 83 | True 84 | 85 | 86 | ..\packages\OxyPlot.Core.2014.1.546\lib\portable-net4+sl4+wp71+win8\OxyPlot.dll 87 | True 88 | 89 | 90 | ..\packages\OxyPlot.WindowsForms.2014.1.546\lib\net45\OxyPlot.WindowsForms.dll 91 | True 92 | 93 | 94 | 95 | 96 | 97 | 98 | 105 | -------------------------------------------------------------------------------- /Experiment-05/Experiment-05.fsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 2.0 8 | aaf071cf-a53f-4156-b2f7-af47d62b4690 9 | Exe 10 | Experiment_05 11 | Experiment_05 12 | v4.6 13 | true 14 | 4.4.0.0 15 | Experiment-05 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | false 23 | ..\build\bin 24 | $(BaseOutputPath)\$(Platform)\$(Configuration)\ 25 | ..\build\obj 26 | $(BaseIntermediateOutputPath)\$(Platform)\$(Configuration)\ 27 | DEBUG;TRACE 28 | 3 29 | AnyCPU 30 | 31 | 32 | false 33 | 34 | 35 | pdbonly 36 | true 37 | true 38 | ..\build\bin 39 | $(BaseOutputPath)\$(Platform)\$(Configuration)\ 40 | ..\build\obj 41 | $(BaseIntermediateOutputPath)\$(Platform)\$(Configuration)\ 42 | TRACE 43 | 3 44 | AnyCPU 45 | 46 | 47 | false 48 | 49 | 50 | 11 51 | 52 | 53 | 54 | 55 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets 56 | 57 | 58 | 59 | 60 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | ..\packages\MathNet.Numerics.3.7.0\lib\net40\MathNet.Numerics.dll 75 | True 76 | 77 | 78 | ..\packages\MathNet.Numerics.FSharp.3.7.0\lib\net40\MathNet.Numerics.FSharp.dll 79 | True 80 | 81 | 82 | 83 | True 84 | 85 | 86 | ..\packages\OxyPlot.Core.2014.1.546\lib\portable-net4+sl4+wp71+win8\OxyPlot.dll 87 | True 88 | 89 | 90 | ..\packages\OxyPlot.WindowsForms.2014.1.546\lib\net45\OxyPlot.WindowsForms.dll 91 | True 92 | 93 | 94 | 95 | 96 | 97 | 98 | 105 | -------------------------------------------------------------------------------- /Experiment-06/Experiment-06.fsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 2.0 8 | 1e47ec4a-3e5c-4633-8c7a-d1940eb6cb68 9 | Exe 10 | Experiment_06 11 | Experiment_06 12 | v4.6 13 | true 14 | 4.4.0.0 15 | Experiment-06 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | false 23 | ..\build\bin 24 | $(BaseOutputPath)\$(Platform)\$(Configuration)\ 25 | ..\build\obj 26 | $(BaseIntermediateOutputPath)\$(Platform)\$(Configuration)\ 27 | DEBUG;TRACE 28 | 3 29 | AnyCPU 30 | 31 | 32 | false 33 | 34 | 35 | pdbonly 36 | true 37 | true 38 | ..\build\bin 39 | $(BaseOutputPath)\$(Platform)\$(Configuration)\ 40 | ..\build\obj 41 | $(BaseIntermediateOutputPath)\$(Platform)\$(Configuration)\ 42 | TRACE 43 | 3 44 | AnyCPU 45 | 46 | 47 | false 48 | 49 | 50 | 11 51 | 52 | 53 | 54 | 55 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets 56 | 57 | 58 | 59 | 60 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | ..\packages\MathNet.Numerics.3.7.0\lib\net40\MathNet.Numerics.dll 75 | True 76 | 77 | 78 | ..\packages\MathNet.Numerics.FSharp.3.7.0\lib\net40\MathNet.Numerics.FSharp.dll 79 | True 80 | 81 | 82 | 83 | True 84 | 85 | 86 | ..\packages\OxyPlot.Core.2014.1.546\lib\portable-net4+sl4+wp71+win8\OxyPlot.dll 87 | True 88 | 89 | 90 | ..\packages\OxyPlot.WindowsForms.2014.1.546\lib\net45\OxyPlot.WindowsForms.dll 91 | True 92 | 93 | 94 | 95 | 96 | 97 | 98 | 105 | -------------------------------------------------------------------------------- /Experiment-07/Experiment-07.fsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 2.0 8 | e0b8dc52-9d18-4d4d-ac4e-f6a5135cabb4 9 | Exe 10 | Experiment_07 11 | Experiment_07 12 | v4.6 13 | true 14 | 4.4.0.0 15 | Experiment-07 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | false 23 | ..\build\bin 24 | $(BaseOutputPath)\$(Platform)\$(Configuration)\ 25 | ..\build\obj 26 | $(BaseIntermediateOutputPath)\$(Platform)\$(Configuration)\ 27 | DEBUG;TRACE 28 | 3 29 | AnyCPU 30 | 31 | 32 | false 33 | 34 | 35 | pdbonly 36 | true 37 | true 38 | ..\build\bin 39 | $(BaseOutputPath)\$(Platform)\$(Configuration)\ 40 | ..\build\obj 41 | $(BaseIntermediateOutputPath)\$(Platform)\$(Configuration)\ 42 | TRACE 43 | 3 44 | AnyCPU 45 | 46 | 47 | false 48 | 49 | 50 | 11 51 | 52 | 53 | 54 | 55 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets 56 | 57 | 58 | 59 | 60 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | ..\packages\MathNet.Numerics.3.7.0\lib\net40\MathNet.Numerics.dll 75 | True 76 | 77 | 78 | ..\packages\MathNet.Numerics.FSharp.3.7.0\lib\net40\MathNet.Numerics.FSharp.dll 79 | True 80 | 81 | 82 | 83 | True 84 | 85 | 86 | ..\packages\OxyPlot.Core.2014.1.546\lib\portable-net4+sl4+wp71+win8\OxyPlot.dll 87 | True 88 | 89 | 90 | ..\packages\OxyPlot.WindowsForms.2014.1.546\lib\net45\OxyPlot.WindowsForms.dll 91 | True 92 | 93 | 94 | 95 | 96 | 97 | 98 | 105 | -------------------------------------------------------------------------------- /Experiment-06/Compute.fs: -------------------------------------------------------------------------------- 1 | module Compute 2 | 3 | open MathNet.Numerics.Distributions 4 | 5 | //------------------------------------------------------------------------------------------------- 6 | 7 | let probInf = 0.5 8 | let probUnf = 1.0 - probInf 9 | let probEta = 0.4 10 | 11 | let mu = 50.50 12 | let sigma = 0.5 13 | 14 | let range = 5.0 15 | let scale = 100 16 | let count = int (2.0 * range * float scale) 17 | 18 | let vInc = 2.0 * range * sigma / float count 19 | let vMin = mu - (range * sigma) 20 | let vMax = mu + (range * sigma) 21 | 22 | let values = Array.init count (fun i -> vMin + (float i * vInc)) 23 | 24 | let probInitializer mu' sigma' i = 25 | let i = vInc * (float i) 26 | let a = Normal.CDF(mu' - mu, sigma', (-range * sigma) + i) 27 | let b = Normal.CDF(mu' - mu, sigma', (-range * sigma) + i + vInc) 28 | b - a 29 | 30 | let probInit = probInitializer mu sigma |> Array.init count 31 | 32 | //------------------------------------------------------------------------------------------------- 33 | 34 | let private computeProbSell (p : float[]) iBid = 35 | 36 | let mutable acc = 0.0 37 | 38 | for i = 0 to count - 1 do 39 | acc <- acc + p.[i] * probUnf * probEta 40 | 41 | for i = 0 to iBid - 1 do 42 | acc <- acc + p.[i] * probInf 43 | 44 | acc 45 | 46 | let private computeProbTake (p : float[]) iAsk = 47 | 48 | let mutable acc = 0.0 49 | 50 | for i = 0 to count - 1 do 51 | acc <- acc + p.[i] * probUnf * probEta 52 | 53 | for i = iAsk + 1 to count - 1 do 54 | acc <- acc + p.[i] * probInf 55 | 56 | acc 57 | 58 | let private computeProbNone (p : float[]) iBid iAsk = 59 | 60 | let mutable acc = 0.0 61 | 62 | for i = 0 to count - 1 do 63 | acc <- acc + p.[i] * probUnf * (1.0 - 2.0 * probEta) 64 | 65 | for i = iBid to iAsk do 66 | acc <- acc + p.[i] * probInf 67 | 68 | acc 69 | 70 | //------------------------------------------------------------------------------------------------- 71 | 72 | let private computePosteriorSell p iBid = 73 | 74 | let pSell = computeProbSell p iBid 75 | 76 | let mapping i x = 77 | x * ((probUnf * probEta) + if i < iBid then probInf else 0.0) 78 | 79 | p 80 | |> Array.mapi mapping 81 | |> Array.map (fun x -> x / pSell) 82 | 83 | let private computePosteriorTake p iAsk = 84 | 85 | let pTake = computeProbTake p iAsk 86 | 87 | let mapping i x = 88 | x * ((probUnf * probEta) + if i > iAsk then probInf else 0.0) 89 | 90 | p 91 | |> Array.mapi mapping 92 | |> Array.map (fun x -> x / pTake) 93 | 94 | let private computePosteriorNone p iBid iAsk = 95 | 96 | let pNone = computeProbNone p iBid iAsk 97 | 98 | let mapping i x = 99 | x * ((probUnf * (1.0 - 2.0 * probEta)) + if i >= iBid && i <= iAsk then probInf else 0.0) 100 | 101 | p 102 | |> Array.mapi mapping 103 | |> Array.map (fun x -> x / pNone) 104 | 105 | //------------------------------------------------------------------------------------------------- 106 | 107 | let private computePricesBid p iBid = 108 | 109 | let pSell = computeProbSell p iBid 110 | 111 | let mutable acc = 0.0 112 | 113 | for i = 0 to iBid - 1 do 114 | acc <- acc + values.[i] * p.[i] * (probInf + (probUnf * probEta)) 115 | 116 | for i = iBid to count - 1 do 117 | acc <- acc + values.[i] * p.[i] * (probUnf * probEta) 118 | 119 | acc / pSell 120 | 121 | let private computePricesAsk p iAsk = 122 | 123 | let pTake = computeProbTake p iAsk 124 | 125 | let mutable acc = 0.0 126 | 127 | for i = 0 to iAsk do 128 | acc <- acc + values.[i] * p.[i] * (probUnf * probEta) 129 | 130 | for i = iAsk + 1 to count - 1 do 131 | acc <- acc + values.[i] * p.[i] * (probInf + (probUnf * probEta)) 132 | 133 | acc / pTake 134 | 135 | let private computeBid p = 136 | 137 | let initializer i = (i, values.[i], computePricesBid p i) 138 | 139 | initializer 140 | |> Seq.init count 141 | |> Seq.minBy (fun (_, _, v) -> v) 142 | 143 | let private computeAsk p = 144 | 145 | let initializer i = (i, values.[i], computePricesAsk p i) 146 | 147 | initializer 148 | |> Seq.init count 149 | |> Seq.maxBy (fun (_, _, v) -> v) 150 | 151 | //------------------------------------------------------------------------------------------------- 152 | 153 | let private executeSell p (bid, ask) = 154 | 155 | let iBid, _, _ = bid 156 | let p' = computePosteriorSell p iBid 157 | 158 | let bid = computeBid p' 159 | let ask = computeAsk p' 160 | 161 | (bid, ask, p') 162 | 163 | let private executeTake p (bid, ask) = 164 | 165 | let iAsk, _, _ = ask 166 | let p' = computePosteriorTake p iAsk 167 | 168 | let bid = computeBid p' 169 | let ask = computeAsk p' 170 | 171 | (bid, ask, p') 172 | 173 | let private executeNone p (bid, ask) = 174 | 175 | let iBid, _, _ = bid 176 | let iAsk, _, _ = ask 177 | let p' = computePosteriorNone p iBid iAsk 178 | 179 | let bid = computeBid p' 180 | let ask = computeAsk p' 181 | 182 | (bid, ask, p') 183 | 184 | //------------------------------------------------------------------------------------------------- 185 | 186 | type ExecutionPolicy = 187 | | Stochastic of float 188 | 189 | let private getValue = function 190 | | Stochastic value -> value 191 | 192 | let private getExecuteFunc random (value, bid, ask) = 193 | let _, _, vBid = bid 194 | let _, _, vAsk = ask 195 | match Sample.continuousUniform 0.0 1.0 random with 196 | | sample when (sample < probInf) && (value > vAsk) -> executeTake 197 | | sample when (sample < probInf) && (value < vBid) -> executeSell 198 | | sample when (sample < probInf) -> executeNone 199 | | sample when (sample < probInf + probUnf * 0.50) 200 | -> executeTake 201 | | _ -> executeSell 202 | 203 | let generateResults random executionPolicy = 204 | 205 | let p = probInit 206 | 207 | let bid = computeBid p 208 | let ask = computeAsk p 209 | 210 | let value = getValue executionPolicy 211 | 212 | let generator (bid, ask, p) = 213 | let execute = getExecuteFunc random (value, bid, ask) 214 | let (bid, ask, p) = execute p (bid, ask) 215 | Some ((value, bid, ask, p), (bid, ask, p)) 216 | 217 | seq { 218 | yield (value, bid, ask, p) 219 | yield! Seq.unfold generator (bid, ask, p) 220 | } 221 | -------------------------------------------------------------------------------- /Experiment-07/Compute.fs: -------------------------------------------------------------------------------- 1 | module Compute 2 | 3 | open MathNet.Numerics.Distributions 4 | 5 | //------------------------------------------------------------------------------------------------- 6 | 7 | let probInf = 0.5 8 | let probUnf = 1.0 - probInf 9 | let probEta = 0.4 10 | 11 | let mu = 50.50 12 | let sigma = 0.5 13 | 14 | let range = 5.0 15 | let scale = 100 16 | let count = int (2.0 * range * float scale) 17 | 18 | let vInc = 2.0 * range * sigma / float count 19 | let vMin = mu - (range * sigma) 20 | let vMax = mu + (range * sigma) 21 | 22 | let values = Array.init count (fun i -> vMin + (float i * vInc)) 23 | 24 | let probInitializer mu' sigma' i = 25 | let i = vInc * (float i) 26 | let a = Normal.CDF(mu' - mu, sigma', (-range * sigma) + i) 27 | let b = Normal.CDF(mu' - mu, sigma', (-range * sigma) + i + vInc) 28 | b - a 29 | 30 | let probInit = probInitializer mu sigma |> Array.init count 31 | 32 | //------------------------------------------------------------------------------------------------- 33 | 34 | let private computeProbSell (p : float[]) iBid = 35 | 36 | let mutable acc = 0.0 37 | 38 | for i = 0 to count - 1 do 39 | acc <- acc + p.[i] * probUnf * probEta 40 | 41 | for i = 0 to iBid - 1 do 42 | acc <- acc + p.[i] * probInf 43 | 44 | acc 45 | 46 | let private computeProbTake (p : float[]) iAsk = 47 | 48 | let mutable acc = 0.0 49 | 50 | for i = 0 to count - 1 do 51 | acc <- acc + p.[i] * probUnf * probEta 52 | 53 | for i = iAsk + 1 to count - 1 do 54 | acc <- acc + p.[i] * probInf 55 | 56 | acc 57 | 58 | let private computeProbNone (p : float[]) iBid iAsk = 59 | 60 | let mutable acc = 0.0 61 | 62 | for i = 0 to count - 1 do 63 | acc <- acc + p.[i] * probUnf * (1.0 - 2.0 * probEta) 64 | 65 | for i = iBid to iAsk do 66 | acc <- acc + p.[i] * probInf 67 | 68 | acc 69 | 70 | //------------------------------------------------------------------------------------------------- 71 | 72 | let private normalizePosterior (p : float[]) = 73 | 74 | let mutable acc = 0.0 75 | 76 | for i = 0 to count - 1 do 77 | let weight = p.[i] 78 | let value = vMin + (float i) * vInc 79 | let x = weight * value 80 | acc <- acc + x 81 | 82 | let mu' = acc 83 | 84 | let mutable acc = 0.0 85 | 86 | for i = 0 to count - 1 do 87 | let weight = p.[i] 88 | let value = vMin + (float i) * vInc 89 | let x = weight * ((mu' - value) ** 2.0) 90 | acc <- acc + x 91 | 92 | let sigma' = sqrt acc 93 | 94 | probInitializer mu' sigma' |> Array.init count 95 | 96 | let private computePosteriorSell p iBid = 97 | 98 | let pSell = computeProbSell p iBid 99 | 100 | let mapping i x = 101 | x * ((probUnf * probEta) + if i < iBid then probInf else 0.0) 102 | 103 | p 104 | |> Array.mapi mapping 105 | |> Array.map (fun x -> x / pSell) 106 | |> normalizePosterior 107 | 108 | let private computePosteriorTake p iAsk = 109 | 110 | let pTake = computeProbTake p iAsk 111 | 112 | let mapping i x = 113 | x * ((probUnf * probEta) + if i > iAsk then probInf else 0.0) 114 | 115 | p 116 | |> Array.mapi mapping 117 | |> Array.map (fun x -> x / pTake) 118 | |> normalizePosterior 119 | 120 | let private computePosteriorNone p iBid iAsk = 121 | 122 | let pNone = computeProbNone p iBid iAsk 123 | 124 | let mapping i x = 125 | x * ((probUnf * (1.0 - 2.0 * probEta)) + if i >= iBid && i <= iAsk then probInf else 0.0) 126 | 127 | p 128 | |> Array.mapi mapping 129 | |> Array.map (fun x -> x / pNone) 130 | |> normalizePosterior 131 | 132 | //------------------------------------------------------------------------------------------------- 133 | 134 | let private computePricesBid p iBid = 135 | 136 | let pSell = computeProbSell p iBid 137 | 138 | let mutable acc = 0.0 139 | 140 | for i = 0 to iBid - 1 do 141 | acc <- acc + values.[i] * p.[i] * (probInf + (probUnf * probEta)) 142 | 143 | for i = iBid to count - 1 do 144 | acc <- acc + values.[i] * p.[i] * (probUnf * probEta) 145 | 146 | acc / pSell 147 | 148 | let private computePricesAsk p iAsk = 149 | 150 | let pTake = computeProbTake p iAsk 151 | 152 | let mutable acc = 0.0 153 | 154 | for i = 0 to iAsk do 155 | acc <- acc + values.[i] * p.[i] * (probUnf * probEta) 156 | 157 | for i = iAsk + 1 to count - 1 do 158 | acc <- acc + values.[i] * p.[i] * (probInf + (probUnf * probEta)) 159 | 160 | acc / pTake 161 | 162 | let private computeBid p = 163 | 164 | let initializer i = (i, values.[i], computePricesBid p i) 165 | 166 | initializer 167 | |> Seq.init count 168 | |> Seq.minBy (fun (_, _, v) -> v) 169 | 170 | let private computeAsk p = 171 | 172 | let initializer i = (i, values.[i], computePricesAsk p i) 173 | 174 | initializer 175 | |> Seq.init count 176 | |> Seq.maxBy (fun (_, _, v) -> v) 177 | 178 | //------------------------------------------------------------------------------------------------- 179 | 180 | let private executeSell p (bid, ask) = 181 | 182 | let iBid, _, _ = bid 183 | let p' = computePosteriorSell p iBid 184 | 185 | let bid = computeBid p' 186 | let ask = computeAsk p' 187 | 188 | (bid, ask, p') 189 | 190 | let private executeTake p (bid, ask) = 191 | 192 | let iAsk, _, _ = ask 193 | let p' = computePosteriorTake p iAsk 194 | 195 | let bid = computeBid p' 196 | let ask = computeAsk p' 197 | 198 | (bid, ask, p') 199 | 200 | let private executeNone p (bid, ask) = 201 | 202 | let iBid, _, _ = bid 203 | let iAsk, _, _ = ask 204 | let p' = computePosteriorNone p iBid iAsk 205 | 206 | let bid = computeBid p' 207 | let ask = computeAsk p' 208 | 209 | (bid, ask, p') 210 | 211 | //------------------------------------------------------------------------------------------------- 212 | 213 | type ExecutionPolicy = 214 | | Stochastic of float 215 | 216 | let private getValue = function 217 | | Stochastic value -> value 218 | 219 | let private getExecuteFunc random (value, bid, ask) = 220 | let _, _, vBid = bid 221 | let _, _, vAsk = ask 222 | match Sample.continuousUniform 0.0 1.0 random with 223 | | sample when (sample < probInf) && (value > vAsk) -> executeTake 224 | | sample when (sample < probInf) && (value < vBid) -> executeSell 225 | | sample when (sample < probInf) -> executeNone 226 | | sample when (sample < probInf + probUnf * 0.50) 227 | -> executeTake 228 | | _ -> executeSell 229 | 230 | let generateResults random executionPolicy = 231 | 232 | let p = probInit 233 | 234 | let bid = computeBid p 235 | let ask = computeAsk p 236 | 237 | let value = getValue executionPolicy 238 | 239 | let generator (bid, ask, p) = 240 | let execute = getExecuteFunc random (value, bid, ask) 241 | let (bid, ask, p) = execute p (bid, ask) 242 | Some ((value, bid, ask, p), (bid, ask, p)) 243 | 244 | seq { 245 | yield (value, bid, ask, p) 246 | yield! Seq.unfold generator (bid, ask, p) 247 | } 248 | -------------------------------------------------------------------------------- /Experiment-03/Compute.fs: -------------------------------------------------------------------------------- 1 | module Compute 2 | 3 | open MathNet.Numerics.Distributions 4 | 5 | //------------------------------------------------------------------------------------------------- 6 | 7 | let valueHi = 51.00 8 | let value75 = 50.75 9 | let value50 = 50.50 10 | let value25 = 50.25 11 | let valueLo = 50.00 12 | 13 | let probInitValueHi = 0.2 14 | let probInitValue75 = 0.2 15 | let probInitValue50 = 0.2 16 | let probInitValue25 = 0.2 17 | let probInitValueLo = 0.2 18 | 19 | let probInf = 0.5 20 | let probUnf = 1.0 - probInf 21 | 22 | let probUnfSellValueHi = 0.5 23 | let probUnfSellValue75 = 0.5 24 | let probUnfSellValue50 = 0.5 25 | let probUnfSellValue25 = 0.5 26 | let probUnfSellValueLo = 0.5 27 | 28 | let probUnfTakeValueHi = 0.5 29 | let probUnfTakeValue75 = 0.5 30 | let probUnfTakeValue50 = 0.5 31 | let probUnfTakeValue25 = 0.5 32 | let probUnfTakeValueLo = 0.5 33 | 34 | //------------------------------------------------------------------------------------------------- 35 | 36 | let private computePosteriorSell (pHi, p75, p50, p25, pLo) = 37 | 38 | let estimate 39 | = (pHi * valueHi) 40 | + (p75 * value75) 41 | + (p50 * value50) 42 | + (p25 * value25) 43 | + (pLo * valueLo) 44 | 45 | let probInfSellValueHi = if valueHi < estimate then 1.0 else 0.0 46 | let probInfSellValue75 = if value75 < estimate then 1.0 else 0.0 47 | let probInfSellValue50 = if value50 < estimate then 1.0 else 0.0 48 | let probInfSellValue25 = if value25 < estimate then 1.0 else 0.0 49 | let probInfSellValueLo = if valueLo < estimate then 1.0 else 0.0 50 | 51 | let probSellValueHi = (probInf * probInfSellValueHi) + (probUnf * probUnfSellValueHi) 52 | let probSellValue75 = (probInf * probInfSellValue75) + (probUnf * probUnfSellValue75) 53 | let probSellValue50 = (probInf * probInfSellValue50) + (probUnf * probUnfSellValue50) 54 | let probSellValue25 = (probInf * probInfSellValue25) + (probUnf * probUnfSellValue25) 55 | let probSellValueLo = (probInf * probInfSellValueLo) + (probUnf * probUnfSellValueLo) 56 | 57 | let probSell 58 | = (pHi * probSellValueHi) 59 | + (p75 * probSellValue75) 60 | + (p50 * probSellValue50) 61 | + (p25 * probSellValue25) 62 | + (pLo * probSellValueLo) 63 | 64 | let pHi' = (pHi * probSellValueHi) / probSell 65 | let p75' = (p75 * probSellValue75) / probSell 66 | let p50' = (p50 * probSellValue50) / probSell 67 | let p25' = (p25 * probSellValue25) / probSell 68 | let pLo' = (pLo * probSellValueLo) / probSell 69 | 70 | (pHi', p75', p50', p25', pLo') 71 | 72 | let private computePosteriorTake (pHi, p75, p50, p25, pLo) = 73 | 74 | let estimate 75 | = (pHi * valueHi) 76 | + (p75 * value75) 77 | + (p50 * value50) 78 | + (p25 * value25) 79 | + (pLo * valueLo) 80 | 81 | let probInfTakeValueHi = if valueHi > estimate then 1.0 else 0.0 82 | let probInfTakeValue75 = if value75 > estimate then 1.0 else 0.0 83 | let probInfTakeValue50 = if value50 > estimate then 1.0 else 0.0 84 | let probInfTakeValue25 = if value25 > estimate then 1.0 else 0.0 85 | let probInfTakeValueLo = if valueLo > estimate then 1.0 else 0.0 86 | 87 | let probTakeValueHi = (probInf * probInfTakeValueHi) + (probUnf * probUnfTakeValueHi) 88 | let probTakeValue75 = (probInf * probInfTakeValue75) + (probUnf * probUnfTakeValue75) 89 | let probTakeValue50 = (probInf * probInfTakeValue50) + (probUnf * probUnfTakeValue50) 90 | let probTakeValue25 = (probInf * probInfTakeValue25) + (probUnf * probUnfTakeValue25) 91 | let probTakeValueLo = (probInf * probInfTakeValueLo) + (probUnf * probUnfTakeValueLo) 92 | 93 | let probTake 94 | = (pHi * probTakeValueHi) 95 | + (p75 * probTakeValue75) 96 | + (p50 * probTakeValue50) 97 | + (p25 * probTakeValue25) 98 | + (pLo * probTakeValueLo) 99 | 100 | let pHi' = (pHi * probTakeValueHi) / probTake 101 | let p75' = (p75 * probTakeValue75) / probTake 102 | let p50' = (p50 * probTakeValue50) / probTake 103 | let p25' = (p25 * probTakeValue25) / probTake 104 | let pLo' = (pLo * probTakeValueLo) / probTake 105 | 106 | (pHi', p75', p50', p25', pLo') 107 | 108 | //------------------------------------------------------------------------------------------------- 109 | 110 | let private computeBid (pHi, p75, p50, p25, pLo) = 111 | 112 | let (pHi', p75', p50', p25', pLo') = computePosteriorSell (pHi, p75, p50, p25, pLo) 113 | 114 | let value 115 | = (valueHi * pHi') 116 | + (value75 * p75') 117 | + (value50 * p50') 118 | + (value25 * p25') 119 | + (valueLo * pLo') 120 | 121 | value 122 | 123 | let private computeAsk (pHi, p75, p50, p25, pLo) = 124 | 125 | let (pHi', p75', p50', p25', pLo') = computePosteriorTake (pHi, p75, p50, p25, pLo) 126 | 127 | let value 128 | = (valueHi * pHi') 129 | + (value75 * p75') 130 | + (value50 * p50') 131 | + (value25 * p25') 132 | + (valueLo * pLo') 133 | 134 | value 135 | 136 | //------------------------------------------------------------------------------------------------- 137 | 138 | let private executeSell (pHi, p75, p50, p25, pLo) = 139 | 140 | let (pHi', p75', p50', p25', pLo') = computePosteriorSell (pHi, p75, p50, p25, pLo) 141 | 142 | let bid = computeBid (pHi', p75', p50', p25', pLo') 143 | let ask = computeAsk (pHi', p75', p50', p25', pLo') 144 | 145 | (bid, ask, (pHi', p75', p50', p25', pLo')) 146 | 147 | let private executeTake (pHi, p75, p50, p25, pLo) = 148 | 149 | let (pHi', p75', p50', p25', pLo') = computePosteriorTake (pHi, p75, p50, p25, pLo) 150 | 151 | let bid = computeBid (pHi', p75', p50', p25', pLo') 152 | let ask = computeAsk (pHi', p75', p50', p25', pLo') 153 | 154 | (bid, ask, (pHi', p75', p50', p25', pLo')) 155 | 156 | let private executeNone (pHi, p75, p50, p25, pLo) = 157 | 158 | let pHi' = pHi 159 | let p75' = p75 160 | let p50' = p50 161 | let p25' = p25 162 | let pLo' = pLo 163 | 164 | let bid = computeBid (pHi', p75', p50', p25', pLo') 165 | let ask = computeAsk (pHi', p75', p50', p25', pLo') 166 | 167 | (bid, ask, (pHi', p75', p50', p25', pLo')) 168 | 169 | //------------------------------------------------------------------------------------------------- 170 | 171 | type ExecutionPolicy = 172 | | StochasticHi 173 | | Stochastic75 174 | | Stochastic50 175 | | Stochastic25 176 | | StochasticLo 177 | 178 | let private getValue = function 179 | | StochasticHi -> valueHi 180 | | Stochastic75 -> value75 181 | | Stochastic50 -> value50 182 | | Stochastic25 -> value25 183 | | StochasticLo -> valueLo 184 | 185 | let private getExecuteFunc random (value, bid, ask) = 186 | match Sample.continuousUniform 0.0 1.0 random with 187 | | sample when (sample < probInf) && (value > ask) -> executeTake 188 | | sample when (sample < probInf) && (value < bid) -> executeSell 189 | | sample when (sample < probInf) -> executeNone 190 | | sample when (sample < probInf + probUnf * 0.50) 191 | -> executeTake 192 | | _ -> executeSell 193 | 194 | let generateResults random executionPolicy = 195 | 196 | let pHi = probInitValueHi 197 | let p75 = probInitValue75 198 | let p50 = probInitValue50 199 | let p25 = probInitValue25 200 | let pLo = probInitValueLo 201 | let p = (pHi, p75, p50, p25, pLo) 202 | 203 | let bid = computeBid p 204 | let ask = computeAsk p 205 | 206 | let value = getValue executionPolicy 207 | 208 | let generator (bid, ask, p) = 209 | let execute = getExecuteFunc random (value, bid, ask) 210 | let (bid, ask, p) = execute p 211 | Some ((value, bid, ask, p), (bid, ask, p)) 212 | 213 | seq { 214 | yield (value, bid, ask, p) 215 | yield! Seq.unfold generator (bid, ask, p) 216 | } 217 | --------------------------------------------------------------------------------