Overall Statistics
Total Trades
1504
Average Win
0.09%
Average Loss
-0.10%
Annual Return
43.422%
Drawdown
1.000%
Expectancy
0.718
Net Profit
198.272%
Sharpe Ratio
6.972
Loss Rate
8%
Win Rate
92%
Profit-Loss Ratio
0.86
Alpha
0.242
Beta
-0.011
Annual Standard Deviation
0.034
Annual Variance
0.001
Information Ratio
0.488
Tracking Error
0.167
Treynor Ratio
-22.187
using System;
using System.Collections;
using System.Collections.Generic;
using QuantConnect.Securities;
using QuantConnect.Models;

namespace QuantConnect {

    public class SymbolData
    {
        private Hawkes i = new Hawkes(1, 1.2, 1.8);
        private Hawkes b = new Hawkes(1, 1.2, 1.8);
        private Hawkes s = new Hawkes(1, 1.2, 1.8);
        //private Hawkes s = new Hawkes(1, 1.2, 1.8);
        
        public double LastTradePrice { get; set; }
        public DateTime LastTradeTime { get; set; }
        public Hawkes Intensity { get { return i; }  }
        public Hawkes BuyIntensity { get { return b; } }
        public Hawkes SellIntensity { get { return s; } }
        public double TickSize { get; set; }
        public double PrevPrice { get; set; }
        public bool upTick { get; set; }
        public bool downTick { get; set; }
        public DateTime LastTick { get; set; }  
        public int Qty { get; set; }
    }
}
using System;
using System.Collections;
using System.Collections.Generic; 
using QuantConnect.Securities;
using QuantConnect.Models; 

namespace QuantConnect 
{
    public partial class BasicTemplateAlgorithm : QCAlgorithm, IAlgorithm 
    { 
        private readonly bool enableLogging = true;
        
        private Dictionary<string, SymbolData> symbols = new Dictionary<string, SymbolData>();

        //Initialize the data and resolution you require for your strategy:
        public override void Initialize() 
        {            
            //Initialize the start, end dates for simulation; cash and data required.
            SetStartDate(new DateTime(2010,01,01));
            SetEndDate(new DateTime(2014, 07,25));
            SetCash(25000); //Starting Cash in USD.
            
            symbols.Add("SPY", new SymbolData());
            symbols.Add("IWM", new SymbolData());
            symbols.Add("DIA", new SymbolData());

            foreach(var symbol in symbols.Keys)
            {
                symbols[symbol].TickSize = 0.01;
                AddSecurity(SecurityType.Equity, symbol, Resolution.Second);
                Securities[symbol].Model = new CustomTransactionModel();
            }
        }
        
       //Handle TradeBar Events: a TradeBar occurs on a time-interval (second or minute bars)
        public override void OnTradeBar(Dictionary<string, TradeBar> data) 
        {
            foreach(var symbol in symbols.Keys)
            {
                if (data.ContainsKey(symbol))
                {
                    Process(symbol, symbols[symbol], data[symbol]);
                }
            }            
        }
        
        public void Process(string symbol, SymbolData d, TradeBar t)
        {
            double mid = (double)t.Close;//(t.Price);
            
            if (d.PrevPrice == 0)
            {
                d.PrevPrice = mid;
                d.LastTick = t.Time;
                return;
            }
            
            if (t.Time.Date != d.LastTick.Date)
            {
                d.PrevPrice = mid;
                d.LastTick = t.Time;
                return;
            }
            
            double pips = Math.Abs(d.PrevPrice - mid)/d.TickSize;
            
            if (pips > 100) return;
            double buyintensity = 0;
            double sellintensity = 0;
            
            if (d.PrevPrice > mid)
            {
                buyintensity = d.BuyIntensity.Process(0, true);
                sellintensity = d.SellIntensity.Process(pips, !d.downTick);
            }
            else if (mid > d.PrevPrice)
            {
                buyintensity = d.BuyIntensity.Process(pips, !d.upTick);
                sellintensity = d.SellIntensity.Process(0, true);
            }
            else
            {
                buyintensity = d.BuyIntensity.Process(0, true);
                sellintensity = d.SellIntensity.Process(0, true);
            }
            
            if (Portfolio[symbol].HoldStock)
            {
                // Stay in the market until the asset is going the wrong direction, i.e. down or up depending on if we're long or short on the market.
                if ((t.Time - d.LastTradeTime).TotalSeconds > 60 && ((Portfolio[symbol].IsLong && mid < d.PrevPrice) || (Portfolio[symbol].IsShort && mid > d.PrevPrice)))
                {
                    LogExit(t.Time, symbol, Portfolio[symbol].UnrealizedProfit, (t.Time - d.LastTradeTime).TotalSeconds);
                    d.LastTradePrice = 0;
                    Liquidate(symbol);
                }
            }
            
            int qty = (int)Math.Round(Portfolio.Cash / 4 / (decimal)mid);
            
            if (buyintensity > 10 && buyintensity > sellintensity && !Portfolio[symbol].HoldStock)
            {
                LogEntry(t.Time, symbol, "SHORT", qty, Portfolio.Cash, mid);
                Order(symbol, -qty);
                d.Qty = 1;
                d.LastTradePrice = mid;
                d.LastTradeTime = t.Time;
            }
            else if (sellintensity > 10 && sellintensity > buyintensity && !Portfolio[symbol].HoldStock)
            {
                LogEntry(t.Time, symbol, "LONG", qty, Portfolio.Cash, mid);
                Order(symbol, qty);
                d.Qty = -1;
                d.LastTradePrice = mid;
                d.LastTradeTime = t.Time;
            }
            
            d.upTick = mid > d.PrevPrice;
            d.downTick = d.PrevPrice > mid;
            d.PrevPrice = mid;
            d.LastTick = t.Time;
        }
        
        private void LogEntry(DateTime time, string symbol, string tradeAction, int qty, decimal cash, double price)
        {
            if(enableLogging)
                Debug(string.Format("{0} {1} [{2}]. Qty: {3}, Value: {4}, Cash: {5}", time.ToString("yyyyMMdd HH:mm:ss.fff"), symbol, tradeAction, qty, Math.Round(price * qty, 2), cash));
        }
        
        private void LogExit(DateTime time, string symbol, decimal profit, double seconds)
        {
            if(enableLogging)
                Debug(string.Format("{0} {1} [EXIT]. Profit: {2}, Seconds: {3}", time.ToString("yyyyMMdd HH:mm:ss.fff"), symbol, Math.Round(profit, 2), seconds));
        }        
    }
}
// QuantConnect Simulator C# File, Created on 3-6-2014 by Satyapravin Bezwada
using System;
using System.Collections;
using System.Collections.Generic;

namespace QuantConnect {
    public class Hawkes
    {
        double mu_ = 0, alpha_ = 0, beta_ = 0, bfactor_ = 0;

        public Hawkes(double mu, double alpha, double beta)
        {
            mu_ = mu;
            alpha_ = alpha;
            beta_ = beta;
        }

        public double Process( double count, bool decay)
        {
            double exp = Math.Exp(-beta_);
            
            if (decay) bfactor_ *= exp;
            bfactor_ += exp * count;
            return mu_ + alpha_ * bfactor_;
        }
    }
}
/*
* QUANTCONNECT.COM - Equity Transaction Model
* Default Equities Transaction Model
*/

/**********************************************************
* USING NAMESPACES
**********************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace QuantConnect.Securities {

    /******************************************************** 
    * QUANTCONNECT PROJECT LIBRARIES
    *********************************************************/
    using QuantConnect.Models;


    /******************************************************** 
    * CLASS DEFINITIONS
    *********************************************************/
    /// <summary>
    /// Default Transaction Model for Equity Security Orders
    /// </summary>
    public class CustomTransactionModel : ISecurityTransactionModel {

        /******************************************************** 
        * CLASS PRIVATE VARIABLES
        *********************************************************/


        /******************************************************** 
        * CLASS PUBLIC VARIABLES
        *********************************************************/



        /******************************************************** 
        * CLASS CONSTRUCTOR
        *********************************************************/
        /// <summary>
        /// Initialise the Algorithm Transaction Class
        /// </summary>
        public CustomTransactionModel() {

        }

        /******************************************************** 
        * CLASS PROPERTIES
        *********************************************************/





        /******************************************************** 
        * CLASS METHODS
        *********************************************************/
        /// <summary>
        /// Perform neccessary check to see if the model has been filled, appoximate the best we can.
        /// </summary>
        /// <param name="vehicle">Asset we're working with</param>
        /// <param name="order">Order class to check if filled.</param>
        public virtual void Fill(Security vehicle, ref Order order) {
            try {
                switch (order.Type) {
                    case OrderType.Limit:
                        LimitFill(vehicle, ref order);
                        break;
                    case OrderType.Stop:
                        StopFill(vehicle, ref order);
                        break;
                    case OrderType.Market:
                        MarketFill(vehicle, ref order);
                        break;
                }
            } catch (Exception) {
                
            }
        }



        /// <summary>
        /// Get the Slippage approximation for this order:
        /// </summary>
        public virtual decimal GetSlippageApproximation(Security security, Order order) {
            return 0.15m;
        }



        /// <summary>
        /// Model the slippage on a market order: fixed percentage of order price
        /// </summary>
        /// <param name="security">Asset we're working with</param>
        /// <param name="order">Order to update</param>
        public virtual void MarketFill(Security security, ref Order order) {

            try {
                //Calculate the model slippage: e.g. 0.01c
                decimal slip = GetSlippageApproximation(security, order);

                switch (order.Direction)
                {
                    case OrderDirection.Buy:
                        order.Price = security.Price;
                        order.Price += slip;
                        break;
                    case OrderDirection.Sell:
                        order.Price = security.Price;
                        order.Price -= slip;
                        break;
                }

                //Market orders fill instantly.
                order.Status = OrderStatus.Filled;

                //Round off:
                order.Price = Math.Round(order.Price, 2);

            } catch (Exception) {
                
            }
        }




        /// <summary>
        /// Check if the model has stopped out our position yet:
        /// </summary>
        /// <param name="security">Asset we're working with</param>
        /// <param name="order">Stop Order to Check, return filled if true</param>
        public virtual void StopFill(Security security, ref Order order) {
            try {
                //If its cancelled don't need anymore checks:
                if (order.Status == OrderStatus.Canceled) return;

                //Calculate the model slippage: e.g. 0.01c
                decimal slip = GetSlippageApproximation(security, order);

                //Check if the Stop Order was filled: opposite to a limit order
                switch (order.Direction)
                {
                    case OrderDirection.Sell:
                        //-> 1.1 Sell Stop: If Price below setpoint, Sell:
                        if (security.Price < order.Price) {
                            order.Status = OrderStatus.Filled;
                            order.Price = security.Price;
                            order.Price -= slip;
                        }
                        break;
                    case OrderDirection.Buy:
                        //-> 1.2 Buy Stop: If Price Above Setpoint, Buy:
                        if (security.Price > order.Price) {
                            order.Status = OrderStatus.Filled;
                            order.Price = security.Price;
                            order.Price += slip;
                        }
                        break;
                }

                //Round off:
                order.Price = Math.Round(order.Price, 2);

            } catch (Exception) {
                
            }
        }



        /// <summary>
        /// Check if the price MarketDataed to our limit price yet:
        /// </summary>
        /// <param name="security">Asset we're working with</param>
        /// <param name="order">Limit order in market</param>
        public virtual void LimitFill(Security security, ref Order order) {

            //Initialise;
            decimal marketDataMinPrice = 0;
            decimal marketDataMaxPrice = 0;

            try {
                //If its cancelled don't need anymore checks:
                if (order.Status == OrderStatus.Canceled) return;

                //Calculate the model slippage: e.g. 0.01c
                decimal slip = GetSlippageApproximation(security, order);

                //Depending on the resolution, return different data types:
                BaseData marketData = security.GetLastData();

                marketDataMinPrice = marketData.Value;
                marketDataMaxPrice = marketData.Value;
                

                //-> Valid Live/Model Order: 
                switch (order.Direction)
                {
                    case OrderDirection.Buy:
                        //Buy limit seeks lowest price
                        if (marketDataMinPrice < order.Price) {
                            order.Status = OrderStatus.Filled;
                            order.Price = security.Price;
                            order.Price += slip;
                        }
                        break;
                    case OrderDirection.Sell:
                        //Sell limit seeks highest price possible
                        if (marketDataMaxPrice > order.Price) {
                            order.Status = OrderStatus.Filled;
                            order.Price = security.Price;
                            order.Price -= slip;
                        }
                        break;
                }

                //Round off:
                order.Price = Math.Round(order.Price, 2);

            } catch (Exception) {
                
            }
        }



        /// <summary>
        /// Get the fees from one order, interactive brokers model.
        /// </summary>
        /// <param name="quantity"></param>
        /// <param name="price"></param>
        public virtual decimal GetOrderFee(decimal quantity, decimal price) {
            decimal tradeFee = 0;
            quantity = Math.Abs(quantity);
            decimal tradeValue = (price * quantity);

            //Per share fees
            if (quantity < 500) {
                tradeFee = quantity * 0.013m;
            } else {
                tradeFee = quantity * 0.008m;
            }

            //Maximum Per Order: 0.5%
            //Minimum per order. $1.0
            if (tradeFee < 1) {
                tradeFee = 1;
            } else if (tradeFee > (0.005m * tradeValue)) {
                tradeFee = 0.005m * tradeValue;
            }

            //Always return a positive fee.
            return Math.Abs(tradeFee);
        }

    } // End Algorithm Transaction Filling Classes

} // End QC Namespace