Skip to content

Commit

Permalink
format
Browse files Browse the repository at this point in the history
  • Loading branch information
Shikhor Shams Wahed committed Apr 24, 2019
1 parent 900bac6 commit f897001
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 77 deletions.
9 changes: 6 additions & 3 deletions command.ml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ let parse str =
| [] -> []
| h::t -> t end
in (Set obj) else raise Malformed
| "inventory" -> if List.length filtered = 1 then Inventory else raise Malformed
| "history" -> if List.length filtered = 1 then History else raise Malformed
| "quit" -> if List.length filtered = 1 then Quit else raise Malformed
| "inventory" -> if List.length filtered = 1 then Inventory
else raise Malformed
| "history" -> if List.length filtered = 1 then History
else raise Malformed
| "quit" -> if List.length filtered = 1 then Quit
else raise Malformed
| "tutorial" -> Tutorial
| "help" -> Help
| "cheat" -> Cheat
Expand Down
91 changes: 56 additions & 35 deletions main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,26 @@ let init_trader_players (rolls:int list) : trader_players =
}


(**[parse_user_input state] parses the user's input and returns a Command variant
classifying the response. If the user does not input anything or inputs a malformed
input, it will reprompt the user to answer until the user has provided correct input. *)
(**[parse_user_input state] parses the user's input and returns a Command
variant classifying the response. If the user does not input anything or
inputs a malformed input, it will reprompt the user to answer until the user
has provided correct input. *)
let rec parse_user_input state =
print_endline "\n \n Make a market: \n";
print_string "> ";
match read_line() with
| exception End_of_file -> print_endline "Try again . . ."; parse_user_input state
| exception End_of_file -> print_endline "Try again . . .";
parse_user_input state
| user_response -> begin
try Command.parse user_response with
| Command.Empty -> parse_user_input state
| Command.Malformed -> print_endline "Error in command."; parse_user_input state
| Command.Malformed -> print_endline "Error in command.";
parse_user_input state
end

(** [cycle_traders bstate] returns unit and is used to print out the hidden numbers of
traders and the sum (intrinsic value). This is only used in debug mode. *)
(**[cycle_traders bstate] returns unit and is used to print out the hidden
numbers of traders and the sum (intrinsic value). This is only used in
debug mode. *)
let cycle_traders (bstate:big_state) : unit =
let tr = bstate.traders in
print_endline "hidden numbers; ";
Expand All @@ -63,11 +67,12 @@ let cycle_traders (bstate:big_state) : unit =
print_endline (string_of_int bstate.dice.sum_rolls)


(**[fsm fermi state] is the looping fsm that keeps the game playing based on the
commands put in by the user. It takes in [state] and then returns a new state
according to a transaction that occurs. In the case that no transaction occurs,
it increments the timestep and returns the old state.
It will throw errors with descriptions if unintended behavior occurs (for debug mode).
(**[fsm fermi state] is the looping fsm that keeps the game playing based on
the commands put in by the user. It takes in [state] and then returns a
new state according to a transaction that occurs. In the case that no
transaction occurs, it increments the timestep and returns the old state.
It will throw errors with descriptions if unintended behavior occurs
(for debug mode).
*)
let fsm fermi (state: big_state) =
let user_command = parse_user_input state in
Expand All @@ -78,7 +83,8 @@ let fsm fermi (state: big_state) =
match user_command with
| Command.Quit -> print_endline "QUIT"; exit 0
| Command.Inventory -> (Marketmaker.display_data state.mmstate); state
| Command.History -> (Marketmaker.stringify_bidask_history state.mmstate); state
| Command.History -> (Marketmaker.stringify_bidask_history state.mmstate);
state
| Command.Help -> Gui.display_help (); state
| Command.Tutorial -> Gui.tutorial_preamble "start"; state
| Command.Cheat ->
Expand All @@ -93,8 +99,10 @@ let fsm fermi (state: big_state) =
| Command.Set phr ->
let bid = int_of_string (List.nth phr 0) in
let ask = int_of_string (List.nth phr 1) in
let trade_transaction = Trader.make_transaction (Marketmaker.get_timestamp state.mmstate) bid ask "blank" in
let trader_response = Trader.contention_for_trade state.traders trade_transaction in
let trade_transaction = Trader.make_transaction
(Marketmaker.get_timestamp state.mmstate) bid ask "blank" in
let trader_response = Trader.contention_for_trade state.traders
trade_transaction in

begin
match trader_response with
Expand All @@ -105,7 +113,8 @@ let fsm fermi (state: big_state) =
}
| Some (new_trader_state, response) ->
let new_MM_state = Marketmaker.transaction
(Marketmaker.generate_receive_transaction (Marketmaker.get_timestamp state.mmstate)
(Marketmaker.generate_receive_transaction
(Marketmaker.get_timestamp state.mmstate)
response bid ask) state.mmstate in

let new_state = begin
Expand Down Expand Up @@ -139,42 +148,51 @@ let fsm fermi (state: big_state) =
in
match response with
| "lift" -> print_endline ("Trader " ^ new_trader_state.id ^
" bought a CamlCoin (lifted your offer)"); new_state
" bought a CamlCoin (lifted your offer)");
new_state
| "hit" -> print_endline ("Trader " ^ new_trader_state.id ^
" sold a CamlCoin (hit your bid)"); new_state
" sold a CamlCoin (hit your bid)");
new_state
| _ -> print_endline "error in trader's make trade"; exit 2
end



(**[cli fermi big_state] will pretty-print the market maker's state as it appears in
[big_state] as well as print information from the [fermi] json file that is relevant
to the game. [cli] is recursive in nature and is hardcoded to stop the game after
ten increments. This number can be varied without affect other parts of the game. *)
(**[cli fermi big_state] will pretty-print the market maker's state as it
appears in [big_state] as well as print information from the [fermi] json
file that is relevant to the game. [cli] is recursive in nature and is
hardcoded to stop the game after ten increments. This number can be varied
without affect other parts of the game. *)
let rec cli fermi big_state =
ANSITerminal.(print_string [blue]
"------------------- Statistics ------------------- \n");
(* cycle_traders big_state; *)
print_string ("\nTimestamp ");
print_string ( string_of_int (Marketmaker.get_timestamp big_state.mmstate + 1));
print_string ( string_of_int
(Marketmaker.get_timestamp big_state.mmstate + 1));
print_string (" | Prev. bid/ask: ");
print_string (Marketmaker.stringify_bid_ask big_state.mmstate);
print_string (" | CamlCoins Accumulated: " );
print_string (string_of_int (Marketmaker.get_outstandingshares big_state.mmstate));
print_string (string_of_int (Marketmaker.get_outstandingshares
big_state.mmstate));
match (Marketmaker.get_timestamp big_state.mmstate) with
| 10 -> print_endline ("\n GAME OVER \n \n ");
(Marketmaker.display_data big_state.mmstate);
ANSITerminal.print_string [ANSITerminal.blue] " Cashing in for true value: ";
print_endline ("1 CamlCoin = $" ^ (string_of_int big_state.dice.sum_rolls) ^ ".");
let final_mm_state = (Marketmaker.exchange_mm_excess big_state.mmstate big_state.dice.sum_rolls) in
ANSITerminal.print_string [ANSITerminal.blue]
" Cashing in for true value: ";
print_endline
("1 CamlCoin = $" ^ (string_of_int big_state.dice.sum_rolls) ^ ".");
let final_mm_state = (Marketmaker.exchange_mm_excess big_state.mmstate
big_state.dice.sum_rolls) in
(Marketmaker.display_data final_mm_state);
exit 0
| _ -> cli fermi (fsm fermi big_state )


(**[init_big_state true_value] returns an initial big_state with all record fields
initialized, where [num_opponents] denotes the number of opposing traders. While
this is not used in computation, it is included for debug help. *)
(**[init_big_state true_value] returns an initial big_state with all record
fields initialized, where [num_opponents] denotes the number of opposing
traders. While this is not used in computation, it is included for debug
help. *)
let init_big_state num_opponents =
let dice_state = Stats.mega_roll opponents in
{
Expand All @@ -184,8 +202,9 @@ let init_big_state num_opponents =
}


(** [play_game f] initiates the start of the game described by json file [f]. It outputs
a description of the starting game state as well as a nice visual for the dice roll. *)
(** [play_game f] initiates the start of the game described by json file [f].
It outputs a description of the starting game state as well as a nice
visual for the dice roll. *)
let play_game f =
let obtained_json = Yojson.Basic.from_file f in
let fermi = Parse.from_json obtained_json in
Expand All @@ -199,11 +218,13 @@ let play_game f =
(Parse.show_dice (Stats.get_player_roll big_state.dice));
print_endline ("Other traders : ");
ANSITerminal.print_string [ANSITerminal.red] ((Parse.show_dice 0));
print_endline ("\n \n Let us begin... make your market on the sum of all dice: ");
print_endline
("\n \n Let us begin... make your market on the sum of all dice: ");
cli fermi big_state

(** [main] initiates the [play_game] function and prints a preamble introdution describing the game.
It pulls data from the "fermi.json" file before it calls [play_game]. *)
(** [main] initiates the [play_game] function and prints a preamble introdution
describing the game. It pulls data from the "fermi.json" file before it
calls [play_game]. *)
let main () =
Gui.preamble ();
play_game "fermi.json"
Expand Down
37 changes: 24 additions & 13 deletions marketmaker.ml
Original file line number Diff line number Diff line change
Expand Up @@ -81,27 +81,33 @@ type result = Legal of t | Illegal
- # Coins accumulated
*)
let display_data (state : t) =
ANSITerminal.(print_string [red]
"\n\n ------------------- Market Maker Statistics ------------------- \n");
ANSITerminal.(print_string
[red]
"\n\n ------------------- Market Maker
Statistics ------------------- \n");
print_string ("Current Bid/Ask : ");
print_string (" | Bid: " ^ (string_of_int state.currbidask.bid));
print_string (" | Ask: " ^ (string_of_int state.currbidask.ask));
print_endline ("| Spread: " ^ (string_of_int state.currbidask.spread));
print_string (" Time Stamp: " ^ (string_of_int state.timestamp));
print_endline (" | Current Profit: " ^ (string_of_int state.curr_profit));
print_endline ("# Coins Accumulated: " ^ (string_of_int state.orderbook.outstanding_shares));
ANSITerminal.(print_string [green] "\n \n ---------------------------------------------------------\n " )
print_endline ("# Coins Accumulated: " ^
(string_of_int state.orderbook.outstanding_shares));
ANSITerminal.(print_string
[green]
"\n \n --------------------------
-------------------------------\n " )


(**[readjust_spread transaction market] is a market with the updated spread for the
marketmaker after a bidask change. It has the new bid-offer pair after the
marketmaker has finished a trade for the security at a certain price. The
(**[readjust_spread transaction market] is a market with the updated spread for
the marketmaker after a bidask change. It has the new bid-offer pair after
the marketmaker has finished a trade for the security at a certain price. The
goal of readjustment is to prevent hacks and hopefully be above scratch. It
takes in a new [bid] and [ask] price set by the player and the current
[market] of type t.
For now, we are not implementing this as we have included this functionality in a
different function for cleaner code.
For now, we are not implementing this as we have included this functionality
in a different function for cleaner code.
*)
let readjust_spread (transaction:receive_transaction) (market:t) : t =
failwith "Unimplemented"
Expand All @@ -124,15 +130,20 @@ let transaction (transaction:receive_transaction) (market:t) =
bid_ask_history = market.bid_ask_history @ [new_curr_bid_ask];
timestamp = transaction.timestamp + 1;
curr_profit = market.curr_profit + (if transaction.trade_type = "lift"
then transaction.transaction.ask else -1*transaction.transaction.bid); (* TODO *)
then transaction.transaction.ask
else -1*transaction.transaction.bid);
(* TODO *)
orderbook = {
outstanding_shares = market.orderbook.outstanding_shares
+ (if transaction.trade_type = "hit" then 1 else -1 );
+
(if transaction.trade_type = "hit" then 1 else -1 );
}
}

(** [exchange_mm_excess market sum_dice] will return a new market.t object with excess/deficient shares of camlcoin
swapped for cash in accordance with the true market value, [sum_dice]. The final excess coins will be 0 (invariant). *)
(** [exchange_mm_excess market sum_dice] will return a new market.t object
with excess/deficient shares of camlcoin swapped for cash in accordance
with the true market value, [sum_dice]. The final excess coins will be 0
(invariant). *)
let exchange_mm_excess (market : t) (sum_dice : int) =
let excess = market.orderbook.outstanding_shares in
{
Expand Down
3 changes: 2 additions & 1 deletion marketmaker.mli
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ type receive_transaction = {
val init_market : string -> t
val get_timestamp : t -> int
val transaction : receive_transaction -> t -> t
val generate_receive_transaction : int -> string -> int -> int -> receive_transaction
val generate_receive_transaction : int -> string -> int -> int ->
receive_transaction
val stringify_bid_ask : t -> string
val get_outstandingshares : t -> int
val increment_timestep : t -> t
Expand Down
24 changes: 14 additions & 10 deletions parse.ml
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,25 @@ type t = {
ascii : string
}
(* This is for testing purposes BEGIN *)
let fermi_json : t = {id = "1";
fermi = [{question = "What is the volume of air that I breathe in one day?"; answer = "2800"};
{question = "How many people in the world are talking on their cell phones in any given minute? (in millions)"; answer = "125"}];
situations = [{event = "Flash Crash, all stocks are down"; effect = "-10%"};
{event = "Interest rates decrease"; effect = "+2%"}];
ascii =
"
let fermi_json : t =
{id = "1";
fermi = [{question = "What is the volume of air that I breathe in one day?";
answer = "2800"};
{question = "How many people in the world are talking on their cell
phones in any given minute? (in millions)"; answer = "125"}];
situations = [{event = "Flash Crash, all stocks are down"; effect = "-10%"};
{event = "Interest rates decrease"; effect = "+2%"}];
ascii =
"
WW WW EEEEEEE LL CCCCC OOOOO MM MM EEEEEEE TTTTTTT RRRRRR AAA DDDDD EEEEEEE RRRRRR !!!
WW WW EE LL CC C OO OO MMM MMM EE TTT RR RR AAAAA DD DD EE RR RR !!!
WW W WW EEEEE LL CC OO OO MM MM MM EEEEE TTT RRRRRR AA AA DD DD EEEEE RRRRRR !!!
WW WWW WW EE LL CC C OO OO MM MM EE TTT RR RR AAAAAAA DD DD EE RR RR
WW WW EEEEEEE LLLLLLL CCCCC OOOO0 MM MM EEEEEEE TTT RR RR AA AA DDDDDD EEEEEEE RR RR !!!
" }

let oth_situation = {event = "Flash Crash, all stocks are down"; effect = "-10%"}
let oth_situation =
{event = "Flash Crash, all stocks are down"; effect = "-10%"}
let first_situation = {event = "Interest rates decrease"; effect = "+2%"}
(* END *)

Expand Down Expand Up @@ -95,8 +99,8 @@ let get_nth_situation (index: int ) (data : t) =
let get_event_from_situation (sit : situation) =
sit.event

(* [get_effect_from_situation sit] is the effect from a situation. It's an option indicating
if it it causes the price to rise or to fall *)
(* [get_effect_from_situation sit] is the effect from a situation. It's an
option indicating if it it causes the price to rise or to fall *)
let get_effect_from_situation (sit: situation) =
let s = (String.get sit.effect 0) in
let rest = (String.sub sit.effect 1 (String.length sit.effect - 1)) in
Expand Down
2 changes: 1 addition & 1 deletion parse.mli
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ val fermi_json : t
val oth_situation : situation
val first_situation : situation
(* END *)
val from_json : Yojson.Basic.t -> t
val from_json : Yojson.Basic.json -> t
val get_question : t -> string
val get_answer : t -> string
val get_nth_situation : int -> t -> situation
Expand Down
19 changes: 12 additions & 7 deletions stats.ml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ let mega_roll (num_opp:int) : dice_data =
{
player_roll = playroll;
other_rolls = other_list;
sum_rolls = (playroll + (List.fold_left (fun acc h -> acc + h) 0 other_list) );
sum_rolls = (playroll + (List.fold_left (fun acc h -> acc + h) 0 other_list)
);
}

(* END DICE *)
Expand Down Expand Up @@ -182,18 +183,22 @@ let linear_reg_cheat (market : Marketmaker.t ) =
-1.0 else
abs_float (125.0 -. (last_three_lsr
((List.nth ask_list
(List.length ask_list - 3))::(List.nth ask_list
(List.length ask_list - 2))::(List.nth ask_list
(List.length ask_list - 1))::[]) ))
(List.length ask_list - 3))
::(List.nth ask_list
(List.length ask_list - 2))
::(List.nth ask_list
(List.length ask_list - 1))::[]) ))
else
(* Linear regression for bids*)
if List.length bid_list < 3 then
-1.0 else
abs_float (125.0 -. (last_three_lsr
((List.nth bid_list
(List.length ask_list - 3))::(List.nth bid_list
(List.length ask_list - 2))::(List.nth bid_list
(List.length ask_list - 1))::[]) ))
(List.length ask_list - 3))
::(List.nth bid_list
(List.length ask_list - 2))
::(List.nth bid_list
(List.length ask_list - 1))::[]) ))

(**[count lst str acc] is the frequency of occurrence of [str] in [lst]. *)
let rec count lst str acc =
Expand Down
4 changes: 3 additions & 1 deletion stats.mli
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
type graph_data = {bid_data : int list; ask_data : int list; trade_data : string list; time_data : int list; hidden_number : int}
type graph_data = {bid_data : int list; ask_data : int list;
trade_data : string list; time_data : int list;
hidden_number : int}

type dice_data = {
player_roll : int;
Expand Down
Loading

0 comments on commit f897001

Please sign in to comment.