Overall Statistics
Total Trades
49
Average Win
0%
Average Loss
20.41%
Compounding Annual Return
-100.000%
Drawdown
71.400%
Expectancy
-1
Net Profit
-71.308%
Sharpe Ratio
-10.08
Loss Rate
100%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
-15.294
Beta
7.052
Annual Standard Deviation
1.29
Annual Variance
1.663
Information Ratio
-10.512
Tracking Error
1.268
Treynor Ratio
-1.843
Total Fees
$71000.00
using System;
using System.Collections.Generic;
using QuantConnect.Data.Market;
using QuantConnect.Orders;
using QuantConnect.Orders.Fees;
using QuantConnect.Orders.Fills;
using QuantConnect.Orders.Slippage;
using QuantConnect.Securities;

namespace QuantConnect.Securities 
{
    public class CustomFillModel : ImmediateFillModel
    {
        private readonly QCAlgorithm _algorithm;
        private readonly Random _random = new Random(387510346); // seed it for reproducibility
        private readonly Dictionary<long, decimal> _absoluteRemainingByOrderId = new Dictionary<long, decimal>();

        public CustomFillModel(QCAlgorithm algorithm)
        {
            _algorithm = algorithm;
        }

        public override OrderEvent MarketFill(Security asset, MarketOrder order)
        {
            // this model randomly fills market orders

            decimal absoluteRemaining;
            if (!_absoluteRemainingByOrderId.TryGetValue(order.Id, out absoluteRemaining))
            {
                absoluteRemaining = order.AbsoluteQuantity;
                _absoluteRemainingByOrderId.Add(order.Id, order.AbsoluteQuantity);
            }

            var fill = base.MarketFill(asset, order);
            var absoluteFillQuantity = (int) (Math.Min(absoluteRemaining, _random.Next(0, 2*(int)order.AbsoluteQuantity)));
            fill.FillQuantity = Math.Sign(order.Quantity) * absoluteFillQuantity;

            if (absoluteRemaining == absoluteFillQuantity)
            {
                fill.Status = OrderStatus.Filled;
                _absoluteRemainingByOrderId.Remove(order.Id);
            }
            else
            {
                absoluteRemaining = absoluteRemaining - absoluteFillQuantity;
                _absoluteRemainingByOrderId[order.Id] = absoluteRemaining;
                fill.Status = OrderStatus.PartiallyFilled;
            }

            _algorithm.Log("CustomFillModel: " + fill);

            return fill;
        }
    }

	///Custom Fee Model:
    public class CustomFeeModel : IFeeModel
    {
        private readonly QCAlgorithm _algorithm;

        public CustomFeeModel(QCAlgorithm algorithm)
        {
            _algorithm = algorithm;
        }

        public decimal GetOrderFee(Security security, Order order)
        {
            // custom fee math
            var fee = Math.Max(1000, security.Price*order.AbsoluteQuantity*0.00001m);

            _algorithm.Log("CustomFeeModel: " + fee);
            return fee;
        }
    }

    public class CustomSlippageModel : ISlippageModel
    {
        private readonly QCAlgorithm _algorithm;

        public CustomSlippageModel(QCAlgorithm algorithm)
        {
            _algorithm = algorithm;
        }

        public decimal GetSlippageApproximation(Security asset, Order order)
        {
            // custom slippage math
            var slippage = asset.Price*0.0001m*(decimal) Math.Log10(2*(double) order.AbsoluteQuantity);

            _algorithm.Log("CustomSlippageModel: " + slippage);
            return slippage;
        }
    }

} // End QC Namespace                        
namespace QuantConnect 
{
    /*
    *   QuantConnect University: Overriding Transaction Models
    *
    *   Create your own fee models to better model your brokerage or market conditions. 
    *   With QuantConnect you can configure Slippage, Transaction Fees and Fill Models.
    */
    public class OverrideTransactionModelsAlgorithm : QCAlgorithm
    { 
        private Security _security;
        
        public override void Initialize()
        {
            SetStartDate(2012, 01, 01);
            SetEndDate(2012, 02, 01);
            AddSecurity(SecurityType.Equity, "SPY", Resolution.Hour);

            // set our models
            _security = Securities["SPY"];
            _security.FeeModel = new CustomFeeModel(this);
            _security.FillModel = new CustomFillModel(this);
            _security.SlippageModel = new CustomSlippageModel(this);
        }
        
        /// <summary>
        /// TradeBars Data Event Handler - all IBM data passed into the data object: data["IBM"].Close
        /// </summary>
        public void OnData(TradeBars data)
        {
            var openOrders = Transactions.GetOpenOrders("SPY");
            if (openOrders.Count != 0) return;

            if (Time.Day > 10 && _security.Holdings.Quantity <= 0)
            {
                var quantity = CalculateOrderQuantity("SPY", .5m);
                Log("MarketOrder: " + quantity);
                MarketOrder("SPY", quantity, asynchronous: true); // async needed for partial fill market orders
            }
            else if (Time.Day > 20 && _security.Holdings.Quantity >= 0)
            {
                var quantity = CalculateOrderQuantity("SPY", -.5m);
                Log("MarketOrder: " + quantity);
                MarketOrder("SPY", quantity, asynchronous: true); // async needed for partial fill market orders
            }
        }
    }
}