Market Strategy Engine: F# Market/Agent Simulator
Unfortunately my broadband has been out for the last two days at home
which has slowed the blogging – maybe that’s a good thing
Anyway, the lack of broadband has mean that I’ve spent less time on emails, and more time tinkering. Here’s some code that offers an initial stab at a Market/Agent simulator
open System.Collections.Generic;
type CallPutFlag =
| Call = 0
| Put = 1
type Message = {
Id : int;
Instrument : string;
CallPut : CallPutFlag;
Price : double;
Volume : int;
}
type AgentMessages = Trade of Message | StopAgent
type MarketMessages = Order of Message * MailboxProcessor<AgentMessages> | StopMarket
type Market() =
let callOrderBook = new Dictionary<(string * int) , Message>();
let putOrderBook = new Dictionary<(string * int) , Message>();
let market = MailboxProcessor<MarketMessages>.Start(fun inbox ->
let rec loop() =
async {
let! msg = inbox.Receive()
match msg with
| Order(order, outbox) ->
printfn "Market:Received Order %i" order.Id
match order.CallPut with
| CallPutFlag.Call ->
let key = (order.Instrument, order.Volume);
let matched = putOrderBook.TryGetValue(key);
match matched with
| (true, _) ->
printfn "Matched";
putOrderBook.Remove(key);
outbox.Post(Trade(order))
| (false, _) ->
printfn "No Match";
callOrderBook.Add(key, order);
| CallPutFlag.Put ->
putOrderBook.Add((order.Instrument, order.Volume), order);
return! loop()
| StopMarket ->
printfn "Stop"; return ()}
loop())
member a.SubmitOrder(msg) = market.Post(msg)
type Agent (outbox : Market) =
let agent = MailboxProcessor<AgentMessages>.Start(fun inbox ->
let rec loop() =
async {
let! msg = inbox.Receive()
match msg with
| Trade(m) ->
printfn "Agent: Market Matched and sent us a Trade %i" m.Id; return! loop()
| StopAgent ->
printfn "Stop"; return ()}
loop())
let messageCreator = fun (order:Message) ->
match order.CallPut with
| CallPutFlag.Call ->
{Id = order.Id; Instrument = ""; Price=0.0; CallPut=CallPutFlag.Put; Volume=order.Volume;}
| CallPutFlag.Put ->
{Id = order.Id; Instrument = ""; Price=0.0; CallPut=CallPutFlag.Call; Volume=order.Volume;}
let rec addOrders (order:Message) =
let msg = messageCreator order
do outbox.SubmitOrder( Order(msg, agent) )
printfn "Order %i submitted" order.Id
let marketDepth = async {
let rec addOrders (order:Message) =
let msg = messageCreator order
do outbox.SubmitOrder(Order(msg, agent) )
printfn "Agent:Order %i %s submitted" msg.Id (msg.CallPut.ToString())
addOrders {msg with Id=order.Id+1};
addOrders {Id = 1; Instrument=""; Volume=100; Price=0.0; CallPut=CallPutFlag.Call;}
}
let run = Async.Start (marketDepth)
let market = Market()
let agent = Agent(market)
Sidebar: LAgent
Advertisement
