Overall Statistics
//This code will demo these:
//1) Event handling in f-sharp
//2) basic structure of f-sharp class
//3) how to use QuantConnect.Data.Consolidators in f-sharp
//4) Magic sprintf function
namespace QuantConnect.Algorithm.FSharp//.Custom

open System
open System.Collections.Generic
open QuantConnect//#4
open QuantConnect.Securities
open QuantConnect.Data.Market
open QuantConnect.Algorithm//#3
open QuantConnect.Indicators
open QuantConnect.Orders
open QuantConnect.Data.Consolidators

type RenkoConsolidatorFSharp() = //() is the constructor of RenkoConsolidatorFSharp class
    //#3, reference
    inherit QCAlgorithm() // () is the constructor of QCAlgorithm
    

    override this.Initialize() = 
        //when you type this, the intellisence shows list of available properties, method of this class and base class
        this.SetStartDate(2012,01,01)
        this.SetEndDate(2013,01,01)

        // AddSecurity return object "QuantConnect.Securities.Security"
        // use "|> ignore " to omit non-used return
        this.AddSecurity(SecurityType.Equity,"SPY") |> ignore

        let _spy = this.Symbol("SPY")

        //type "Renko", and press "Ctrl" + "Space", VS will do auto-complete for you
        let renkoClose = new RenkoConsolidator(2.5m)
       
            
        renkoClose.DataConsolidated <- new EventHandler<RenkoBar>(
                fun (a: obj) (bar :RenkoBar) -> this.HandleRenkoClose(bar)
            )
            
        this.SubscriptionManager.AddConsolidator(_spy,renkoClose)

        // break SPY into (2*o + h + l + 3*c)/7
        let renko7bar = 
                new RenkoConsolidator<TradeBar>(
                    barSize = 2.5m,
                    selector = (fun x -> (2m * x.Open + x.High + x.Low + 3m *x.Close)/7m),
                    volumeSelector = (fun(y) -> y.Volume))
        
        renko7bar.DataConsolidated <- new EventHandler<RenkoBar>(
                fun (a: obj) (bar :RenkoBar) -> this.HandleRenko7Bar(bar)
            )
  
      
        // register the consolidator for updates
        this.SubscriptionManager.AddConsolidator(_spy,renko7bar);

    
    /// We're doing our analysis in the OnRenkoBar method, but the framework verifies that this method exists, so we define it.
    member this.OnData(data: TradeBars) =
        this.Log("On Data Triggered")
        

    /// This function is called by our renkoClose consolidator defined in Initialize()
    member this.HandleRenkoClose(data : RenkoBar) =
            
        this.Log("RenkoClose Triggered")
    
        if not this.Portfolio.Invested then
            this.SetHoldings(data.Symbol,1.0)
    
        //magic string format function "sprintf"
        //https://msdn.microsoft.com/en-us/library/ee370560.aspx
        let result = sprintf "CLOSE - %O - %f %f" data.Time data.Open data.Close
        this.Log(result)
            
    member this.HandleRenko7Bar(data : RenkoBar) = 
        this.Log("HandleRenko7Bar Triggered")
        //another way to pipe backward
        this.Log <| sprintf "CLOSE - %O - %f %f" data.Time data.Open data.Close