| 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 Namespaceusing 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; }
}
}