Overall Statistics |
Total Trades 13 Average Win 0.89% Average Loss -1.28% Annual Return -1.585% Drawdown 6.800% Expectancy -0.216 Net Profit -3.717% Sharpe Ratio -0.475 Loss Rate 54% Win Rate 46% Profit-Loss Ratio 0.70 Alpha -0.01 Beta -0.02 Annual Standard Deviation 0.027 Annual Variance 0.001 Information Ratio -1.244 Tracking Error 0.111 Treynor Ratio 0.643 |
using System; using System.Collections; using System.Collections.Generic; using QuantConnect.Securities; using QuantConnect.Models; namespace QuantConnect { /*************************************************************************** TRANSACTION MODELS: CUSTOM FEES & SLIPPAGE Transaction Models allow you to set custom fee and transaction-fill predictions. The fees default to the Interative Brokers rates - 1c per share. THIS IS AN EXAMPLE ALGORITHM FROM THE QUANTCONNECT'S API DOCUMENTATION ***************************************************************************/ public partial class TransactionModelExample : QCAlgorithm { //Initialize the data and resolution you require for your strategy: public override void Initialize() { AddSecurity(SecurityType.Forex, "EURUSD", Resolution.Minute); SetCash(50000); SetStartDate(2012, 4, 1); SetEndDate(DateTime.Now.Date.AddDays(-1)); //Your custom fee models; overwriting the default class. //Securities["EURUSD"].Model = new FlatFeeModel(); Securities["EURUSD"].Model = new ZeroFeeModel(); } public void OnData(TradeBars securityData) { if (Time.Day % 29 == 0 && !Portfolio.HoldStock) { SetHoldings("EURUSD", 0.7); } if (Time.Day % 31 == 0 && Portfolio.HoldStock) { Liquidate(); } } } }
using System; using System.Collections; using System.Collections.Generic; using QuantConnect.Securities; using QuantConnect.Models; namespace QuantConnect { public class ZeroFeeModel : ForexTransactionModel { public override decimal GetOrderFee(decimal quantity, decimal price) { //Modelled order fee to return 0; } } // End Algorithm Transaction Filling Classes }
using System; using System.Collections; using System.Collections.Generic; using QuantConnect.Securities; using QuantConnect.Models; namespace QuantConnect { public class FlatFeeModel : ISecurityTransactionModel { /******************************************************** * CLASS PRIVATE VARIABLES *********************************************************/ private decimal _fee = 1000; /******************************************************** * CLASS CONSTRUCTOR *********************************************************/ /// <summary> /// Initialise the Algorithm Transaction Class /// </summary> public FlatFeeModel(decimal fee) { this._fee = fee; } public FlatFeeModel() { this._fee = 1000; } /******************************************************** * CLASS METHODS *********************************************************/ /// <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) { //Modelled order fee to return _fee; } /// <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) { 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; } } /// <summary> /// Get the Slippage approximation for this order: /// </summary> public virtual decimal GetSlippageApproximation(Security security, Order order) { //Return 0 by default decimal slippage = 0; //For FOREX, the slippage is the Bid/Ask Spread for Tick, and an approximation for the switch (security.Resolution) { case Resolution.Minute: case Resolution.Second: //Get the last data packet: TradeBar lastBar = (TradeBar) security.GetLastData(); //Assume slippage is 1/10,000th of the price slippage = lastBar.Value*0.0001m; break; case Resolution.Tick: Tick lastTick = (Tick) security.GetLastData(); switch (order.Direction) { case OrderDirection.Buy: //We're buying, assume slip to Asking Price. slippage = Math.Abs(order.Price - lastTick.AskPrice); break; case OrderDirection.Sell: //We're selling, assume slip to the bid price. slippage = Math.Abs(order.Price - lastTick.BidPrice); break; } break; } return slippage; } /// <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) { //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; } /// <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) { //If its cancelled don't need anymore checks: if (order.Status == OrderStatus.Canceled) return; //Check if the Stop Order was filled: opposite to a limit order if (order.Direction == OrderDirection.Sell) { //-> 1.1 Sell Stop: If Price below setpoint, Sell: if (security.Price < order.Price) { order.Status = OrderStatus.Filled; } } else if (order.Direction == OrderDirection.Buy) { //-> 1.2 Buy Stop: If Price Above Setpoint, Buy: if (security.Price > order.Price) { order.Status = OrderStatus.Filled; } } } /// <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; //If its cancelled don't need anymore checks: if (order.Status == OrderStatus.Canceled) return; //Depending on the resolution, return different data types: BaseData marketData = security.GetLastData(); if (marketData.DataType == MarketDataType.TradeBar) { marketDataMinPrice = ((TradeBar)marketData).Low; marketDataMaxPrice = ((TradeBar)marketData).High; } else { marketDataMinPrice = marketData.Value; marketDataMaxPrice = marketData.Value; } //-> Valid Live/Model Order: if (order.Direction == OrderDirection.Buy) { //Buy limit seeks lowest price if (marketDataMinPrice < order.Price) { order.Status = OrderStatus.Filled; } } else if (order.Direction == OrderDirection.Sell) { //Sell limit seeks highest price possible if (marketDataMaxPrice > order.Price) { order.Status = OrderStatus.Filled; } } } } // End Algorithm Transaction Filling Classes }