Skip to content

Commit 064d3d9

Browse files
committed
Initial commit
0 parents  commit 064d3d9

File tree

17 files changed

+340
-0
lines changed

17 files changed

+340
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
_build/
2+
_opam/
3+
lib/model/tradeioml.code-workspace

bin/dune

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
(executable
2+
(public_name tradeioml)
3+
(name main)
4+
(libraries model repository))

bin/main.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
let () = print_endline "Hello, World!"

dune-project

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
(lang dune 3.11)
2+
3+
(name tradeioml)
4+
5+
(generate_opam_files true)
6+
7+
(source
8+
(github username/reponame))
9+
10+
(authors "Author Name")
11+
12+
(maintainers "Maintainer Name")
13+
14+
(license LICENSE)
15+
16+
(documentation https://url/to/documentation)
17+
18+
(package
19+
(name tradeioml)
20+
(synopsis "A short synopsis")
21+
(description "A longer description")
22+
(depends ocaml dune)
23+
(tags
24+
(topics "to describe" your project)))
25+
26+
; See the complete stanza docs at https://dune.readthedocs.io/en/stable/dune-files.html#dune-project

lib/model/account.ml

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
open Base
2+
open CalendarLib
3+
open Calendar
4+
open Accountid
5+
open Account_sig
6+
open Common
7+
8+
module Account : Account_sig = struct
9+
(* implementation of an account *)
10+
11+
(* hidden implementation for the base parts of an account *)
12+
type account_base = {
13+
no: Accountno.t;
14+
name: Accountname.t;
15+
date_of_open: CalendarLib.Calendar.t;
16+
date_of_close: CalendarLib.Calendar.t option;
17+
}
18+
19+
(* the abstract representation of the account *)
20+
type t = {
21+
base: account_base;
22+
account_type: Common.account_type;
23+
}
24+
25+
(* the concrete representations of account no and account name *)
26+
(* hidden as part of the account representation *)
27+
type account_no = Accountno.t
28+
type account_name = Accountname.t
29+
30+
let build_account_base no name date_of_open date_of_close =
31+
{
32+
no;
33+
name;
34+
date_of_open;
35+
date_of_close
36+
}
37+
38+
let validator_account_open_date =
39+
let open Tvalidator in
40+
TradingValidator.date_in_future "Cannot be in future"
41+
42+
let validate_base ~no ~name ~account_open_date ~account_close_date =
43+
let open Validator in
44+
let valid = build build_account_base
45+
|> keep no
46+
|> keep name
47+
|> validate account_open_date validator_account_open_date
48+
|> keep account_close_date in
49+
match valid with
50+
| Ok base -> Ok base
51+
| Error e -> Error e
52+
53+
let create_trading_account ~no ~name ~trading_currency ~account_open_date =
54+
let valid = validate_base ~no ~name ~account_open_date ~account_close_date:None in
55+
match valid with
56+
| Ok base -> Ok { base; account_type = Trading trading_currency }
57+
| Error e -> Error e
58+
59+
let create_settlement_account ~no ~name ~settlement_currency ~account_open_date =
60+
let valid = validate_base ~no ~name ~account_open_date ~account_close_date:None in
61+
match valid with
62+
| Ok base -> Ok { base; account_type = Settlement settlement_currency }
63+
| Error e -> Error e
64+
65+
let create_both_account ~no ~name ~trading_currency ~settlement_currency ~account_open_date =
66+
let valid = validate_base ~no ~name ~account_open_date ~account_close_date:None in
67+
match valid with
68+
| Ok base -> Ok { base; account_type = Both (trading_currency, settlement_currency) }
69+
| Error e -> Error e
70+
71+
let validate_close ~account: t ~date_of_close = match t.base.date_of_close with
72+
| Some _ -> Error "Account is already closed"
73+
| None -> match compare t.base.date_of_open date_of_close with
74+
| 0 -> Error "Account open and close date cannot be the same"
75+
| 1 -> Error "Account open date cannot be after close date"
76+
| _ -> Ok t
77+
78+
let close ~account: t ~date_of_close =
79+
let open Result in
80+
validate_close ~account: t ~date_of_close >>= fun _ ->
81+
Ok {
82+
t with base = {
83+
t.base with date_of_close = Some date_of_close
84+
}
85+
}
86+
87+
let get_account_type t = t.account_type
88+
89+
let get_account_no t = t.base.no
90+
91+
let get_account_name t = t.base.name
92+
93+
let get_trading_and_settlement_currency = function
94+
| { base = _ ; account_type = Trading trading_currency } -> (Some trading_currency, None)
95+
| { base = _ ; account_type = Settlement settlement_currency } -> (None, Some settlement_currency)
96+
| { base = _ ; account_type = Both (trading_currency, settlement_currency) } -> (Some trading_currency, Some settlement_currency)
97+
end

lib/model/account_sig.ml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
open Common
2+
open Validator
3+
4+
module type Account_sig = sig
5+
(* abstract types *)
6+
type t
7+
type account_no
8+
type account_name
9+
10+
(* smart constructor to create a validated trading account *)
11+
val create_trading_account:
12+
no: account_no -> name: account_name -> trading_currency: currency -> account_open_date: CalendarLib.Calendar.t -> (t, string) validator_result
13+
14+
(* smart constructor to create a validated settlement account *)
15+
val create_settlement_account:
16+
no: account_no -> name: account_name -> settlement_currency: currency -> account_open_date: CalendarLib.Calendar.t -> (t, string) validator_result
17+
18+
(* smart constructor to create a validated trading and settlement account *)
19+
val create_both_account:
20+
no: account_no -> name: account_name -> trading_currency: currency -> settlement_currency: currency -> account_open_date: CalendarLib.Calendar.t -> (t, string) validator_result
21+
22+
(* close an account *)
23+
val close: account: t -> date_of_close: CalendarLib.Calendar.t -> (t, string) Result.t
24+
25+
(* get the account type *)
26+
val get_account_type: t -> Common.account_type
27+
28+
(* get the trading and settlement currency *)
29+
val get_trading_and_settlement_currency: t -> currency option * currency option
30+
31+
(* get the account number *)
32+
val get_account_no: t -> account_no
33+
34+
(* get the account name *)
35+
val get_account_name: t -> account_name
36+
end

lib/model/accountid.ml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
open Base
2+
open Id
3+
4+
(* Implementing newtypes for accounts *)
5+
(* Use [of_string] constructor to construct a validated account no *)
6+
7+
(* account number and validation *)
8+
module Accountno = struct
9+
include String_id
10+
11+
let validate =
12+
let open Validator in
13+
(string_has_max_length 12 "Too long")
14+
|> compose
15+
(string_has_min_length 3 "Too short")
16+
17+
let of_string x = validate x
18+
19+
end
20+
21+
(* account name and validation *)
22+
module Accountname = struct
23+
include String_id
24+
25+
let validate =
26+
let open Validator in
27+
string_is_not_empty "Empty"
28+
29+
let of_string x = validate x
30+
31+
end

lib/model/common.ml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
(* some sample currencies for the time being *)
2+
type currency = USD | JPY | INR | GBP
3+
4+
(* account_type will be trading, settlement or both *)
5+
type account_type =
6+
| Trading of currency (* with trading currency *)
7+
| Settlement of currency (* with settlement currency *)
8+
| Both of currency * currency (* with trading and settlement currency *)

lib/model/dune

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(library
2+
(name model)
3+
(libraries base calendar unix str validator))

lib/model/id.ml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module type ID = sig
2+
type t
3+
4+
val to_string : t -> string
5+
val of_string : string -> t
6+
val ( = ) : t -> t -> bool
7+
8+
end
9+
10+
module String_id : ID = struct
11+
type t = string
12+
13+
let to_string x = x
14+
let of_string x = x
15+
let ( = ) = String.equal
16+
17+
end

0 commit comments

Comments
 (0)