Overall Statistics |
Total Trades 4 Average Win 0.12% Average Loss 0.00% Annual Return 138.553% Drawdown 0% Expectancy 0.000 Net Profit 0.482% Sharpe Ratio 27.531 Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha 0.855 Beta -4.438 Annual Standard Deviation 0.022 Annual Variance 0 Information Ratio 20.404 Tracking Error 0.027 Treynor Ratio -0.137 |
using System; using System.Collections; using System.Collections.Generic; namespace QuantConnect { using QuantConnect.Securities; using QuantConnect.Models; public partial class BasicTemplateAlgorithm : QCAlgorithm, IAlgorithm { string SPY = "SPY"; Dictionary<string, SymbolData> symbols = new Dictionary<string, SymbolData>(); //int sizeToTake = 5; //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(2013,07,02)); //2010,01,01 SetEndDate(new DateTime(2013, 07,03)); //2014,07,25 SetCash(25000); //Starting Cash in USD. symbols.Add(SPY, new SymbolData()); symbols.Add("IWM", new SymbolData()); symbols.Add("DIA", new SymbolData()); symbols["IWM"].TickSize = 0.01; symbols["DIA"].TickSize = 0.01; symbols[SPY].TickSize = 0.01; AddSecurity(SecurityType.Equity, SPY, Resolution.Second); //Minute, Second or Tick AddSecurity(SecurityType.Equity, "IWM", Resolution.Second); AddSecurity(SecurityType.Equity, "DIA", Resolution.Second); Securities[SPY].Model = new CustomTransactionModel(); Securities[SPY].Model = new CustomTransactionModel(); Securities["IWM"].Model = new CustomTransactionModel(); Securities["DIA"].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]); } } } //Handle Tick Events - Only when you're requesting tick data public override void OnTick(Dictionary<string, List<Tick>> ticks) { foreach(var symbol in symbols.Keys) { if (ticks.ContainsKey(symbol) && ticks[symbol].Count > 0) { //Process(symbol, symbols[symbol], ticks[symbol][ticks[symbol].Count - 1]); } } } 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; } //if (t.AskPrice - t.BidPrice > (decimal)(3 * d.TickSize)) 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) { if ((t.Time - d.LastTradeTime).TotalSeconds > 60) { d.LastTradePrice = 0; Liquidate(symbol); } } { if (buyintensity > 10 && buyintensity > sellintensity && !Portfolio[symbol].HoldStock) { Order(symbol, -100); d.Qty = 1; d.LastTradePrice = mid; d.LastTradeTime = t.Time; //Debug(t.Time.ToString("yyyyMMdd HH:mm:ss.fff")); } else if (sellintensity > 10 && sellintensity > buyintensity && !Portfolio[symbol].HoldStock) { Order(symbol, 100); d.Qty = -1; d.LastTradePrice = mid; d.LastTradeTime = t.Time; //Debug(t.Time.ToString("yyyyMMdd HH:mm:ss.fff")); } } d.upTick = mid > d.PrevPrice; d.downTick = d.PrevPrice > mid; d.PrevPrice = mid; d.LastTick = t.Time; } } }
// 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
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); 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; } } }