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