Source

opycaml / examples / matplotlib / finance_demo.ml

open Opycaml.Api

let debug = Object.debug
let (%) o = Dict.getItemString (Dict.coerce o)
let call o = Object.call (Callable.coerce o)
let (!:>) = Object.obj

let dict_of_alist kvs =
  let d = Dict.new_ () in
  List.iter (fun (k,v) -> Dict.setItem d k v) kvs;
  d

let kwd_call o lst = 
  let kwd = lst |> List.map (fun (s,o) -> Py.String.fromString s, o) |> dict_of_alist in
  Object.call (Callable.coerce o) ~kwd []

let import_module name = Module.getDict (Import.importModule name)

let main () =
  (* from pylab import * *)
  let pylab = import_module "pylab" in

  (* from matplotlib.dates import  DateFormatter, WeekdayLocator, HourLocator, \
     DayLocator, MONDAY, timezone *)
  let dates = import_module "matplotlib.dates" in

  (* from matplotlib.finance import quotes_historical_yahoo, candlestick,\
     plot_day_summary, candlestick2 *)
  let finance = import_module "matplotlib.finance" in

  (* import datetime *)
  let datetime = import_module "datetime" in

  let date = call (datetime % "date") in

  (* date1 = datetime.date( 2004, 2, 1) *)
  let date1 = date [ Int.fromLong 2004; Int.fromLong 2; Int.fromLong 1 ] in
  debug date1 "date1";

  let date2 = date [ Int.fromLong 2004; Int.fromLong 4; Int.fromLong 12 ] in
  debug date2 "date2";

  begin
    try 
      (* Intentionally calls date function w/o arguments *)
      let date0 = date [] in
      debug date0 "date0";
      assert false
    with
    | Error (ty,detail) -> 
        prerr_endline "Expected type error!";
        debug ty "type";
        debug detail "detail";
  end;

  let monday = dates % "MONDAY" in
  debug monday "monday";

  let dayLocator = dates % "DayLocator" in
  debug dayLocator "DayLocator";

  (* Class can be called as a function for New *)
  let dayLocator_f = call (dates % "DayLocator") in

  let alldays = dayLocator_f [] in
  debug alldays "alldays";

  let weekdayLocator = call (dates % "WeekdayLocator") in

  let mondays = weekdayLocator [ monday ] in

  let dateFormatter = call (dates % "DateFormatter") in

  let weekFormatter = dateFormatter [ Py.String.fromString "%b %d" ] in
  debug weekFormatter "weekFormatter";

  let dayFormatter = dateFormatter [ Py.String.fromString "%d" ] in
  debug dayFormatter "dayFormatter";

  let quotes_historical_yahoo = call (finance % "quotes_historical_yahoo") in
  debug (finance % "quotes_historical_yahoo") "quotes_historical_yahoo";
 
  let quotes = 
    try
      quotes_historical_yahoo [ !:> (Py.String.fromString "INTC");
                                date1;
                                date2 ]
    with
    | Opycaml.Api.Error (ty,detail) -> 
        Format.eprintf "%s: %s@." (Object.str_string ty) (Object.str_string detail); raise Exit
  in

  debug quotes "quotes";

  let fig = call (pylab % "figure") [] in
  debug fig "fig";

  (* CR jfuruse: warnings for unit cases. lousy... *)
  kwd_call (fig % "subplots_adjust") [ "bottom", Py.Float.fromDouble 0.2];
  let ax = call (fig % "add_subplot") [ Int.fromLong 111 ] in
  debug ax "ax";

  call (ax % "xaxis" % "set_major_locator") [ mondays ];
  call (ax % "xaxis" % "set_minor_locator") [ alldays ];
  call (ax % "xaxis" % "set_major_formatter") [ weekFormatter ];
  (* call (ax % "xaxis" % "set_minor_formatter") [ dayFormatter ]; *)

  (* #plot_day_summary(ax, quotes, ticksize=3) *)
  kwd_call (finance % "candlestick") [ "", ax; "", quotes; "width", !:> (Py.Float.fromDouble 0.6) ];

  call (ax % "xaxis_date") [];
  call (ax % "autoscale_view") [];
  
  kwd_call (pylab % "setp")
    [ "", call (call (pylab % "gca") [] % "get_xticklabels") []; 
      "rotation", !:> (Int.fromLong 45); 
      "horizontalalignment", !:> (Py.String.fromString "right") ];

  call (pylab % "show") [];

  ()

let () = 
  try main () with
  | Opycaml.Api.Error(ty, detail) -> 
      prerr_endline "Expected type error!";
      debug ty "type";
      debug detail "detail";