| Overall Statistics |
|
Total Trades 20 Average Win 0.64% Average Loss -0.26% Compounding Annual Return 16.621% Drawdown 2.00% Expectancy 0.743 Net Profit 3.85% Sharpe Ratio 3.133 Loss Rate 50% Win Rate 50% Profit-Loss Ratio 2.49 Alpha 0.16 Beta 0.061 Annual Standard Deviation 0.049 Annual Variance 0.002 Information Ratio 2.15 Tracking Error 0.108 Treynor Ratio 2.53 Total Fees $200.00 |
using System;
using System.Collections;
using System.Collections.Generic;
using QuantConnect.Securities;
using QuantConnect.Models;
using QuantConnect.Orders;
namespace QuantConnect {
public partial class SP500Backtest : QCAlgorithm, IAlgorithm {
//Algorithm Variables -list of all stocks. To be used to initialize algorithm
private string[] stockListInit = {"A","AA","AAPL","ABC","ADBE","ADM","ADSK","AES","AET","AGN","AIG",
"AIV","AKAM","AKS","ALTR","ALXN","AMAT","AMD","AMGN","AMP","AMZN","AN",
"ANF","ANR","APA","APC","APH","APOL","ARG","AVP","AZO","BAC","BAX",
"BBBY","BBT","BBY","BEAM","BF.B","BHI","BIG","BIIB","BK","BLL","BMS",
"BRCM","BRK.B","BSX","BTU","C","CA","CAG","CBE","CBG","CELG","CF",
"CHK","CHRW","CI","CLF","CMCSA","CME","CMI","CNX","COG","COH","CPWR",
"CRM","CSC","CSCO","CSX","CTAS","CTL","CTSH","CTXS","CVC","CVH","DD",
"DE","DELL","DF","DGX","DHI","DNB","DNR","DO","DOW","DRI","DTV",
"DUK","DV","DVA","DVN","EA","EBAY","EFX","EL","EMN","EOG","EQT",
"ESRX","ESV","ETFC","ETN","EW","EXC","EXPE","F","FCX","FDO","FE",
"FFIV","FHN","FII","FIS","FITB","FLR","FOSL","FRX","FTI","GAS","GCI",
"GGP","GILD","GLW","GMCR","GME","GNW","GOOGL","GPS","GS","GT","HAL",
"HAR","HBAN","HCBK","HCN","HCP","HD","HES","HIG","HNZ","HOG","HP",
"HPQ","HRS","HSP","HUM","ICE","IGT","INTC","INTU","IPG","IRM","ISRG",
"ITT","JBL","JCP","JDSU","JEC","JNPR","JNS","JOY","JPM","KEY","KIM",
"KLAC","KMX","KSS","KSU","L","LB","LEG","LEN","LH","LIFE","LLY",
"LM","LNC","LO","LRCX","LSI","LUK","LUV","LXK","M","MAR","MAS",
"MCK","MCO","MDT","MHFI","MLM","MNST","MO","MOLX","MON","MOS","MRO",
"MS","MSI","MTB","MUR","MWW","MYL","NBL","NE","NEE","NEM","NFLX",
"NFX","NKE","NOV","NRG","NSC","NTAP","NUE","NVDA","NVLS","NWL","NYT",
"NYX","ODP","OI","OKE","ORCL","ORLY","PBI","PCLN","PCP","PCS","PDCO",
"PEG","PETM","PFG","PHM","PKI","PLL","PNR","POM","PPG","PPL","PVH",
"PXD","R","RCL","RDC","REGN","RF","RHI","RHT","RIG","RL","ROST",
"RRC","RSH","S","SBUX","SCHW","SEE","SHLD","SIAL","SLB","SLM","SNDK",
"SPG","SPLS","SRCL","SRE","STI","STJ","STX","STZ","SVU","SWK",
"SWKS","SWN","SWY","SYMC","TE","TEG","TER","TGT","THC","TIE","TIF",
"TLAB","TSCO","TSN","TSO","TWX","TXT","UNH","URBN","URI","VAR","VLO",
"VMC","VRSN","VRTX","WAG","WAT","WDC","WFM","WFR","WHR","WIN","WLP",
"WMB","WMT","WY","WYNN","X","XL","XLNX","YHOO","YUM","ZION","ZMH"};
string [,] stockListGainers = new string [125,5] {
{"HUM", "VLO", "AAPL", "TIE", "CLF"},
{"CHK", "CTSH", "NVDA", "TIE", "VLO"},
{"ESRX", "TIF", "JCP", "CELG", "SHLD"},
{"LLY", "SWY", "DV", "GLW", "CELG"},
{"TIE", "BTU", "ADSK", "BIG", "LSI"},
{"BBY", "DNR", "LM", "TIE", "CME"},
{"AMGN", "RHI", "AKS", "SNDK", "BTU"},
{"HAR", "NOV", "A", "ADSK", "VLO"},
{"AMD", "CLF", "SNDK", "WFR", "JDSU"},
{"DV", "SNDK", "ESRX", "JNS", "BTU"},
{"AKS", "WFR", "JDSU", "X", "TIE"},
{"NEM", "AMD", "HUM", "SCHW", "SNDK"},
{"SLB", "JDSU", "AMD", "AKS", "BRCM"},
{"WFR", "MWW", "SBUX", "TLAB", "MYL"},
{"NVDA", "NUE", "LSI", "AKS", "JDSU"},
{"R", "BHI", "CMCSA", "BTU", "TIE"},
{"HUM", "ADM", "BIG", "HSP", "LXK"},
{"GOOGL", "CELG", "NYX", "CTSH", "CHRW"},
{"STJ", "BAX", "RSH", "AAPL", "FRX"},
{"AMD", "WFR", "SNDK", "NVDA", "THC"},
{"ADBE", "CTXS", "JNPR", "DRI", "NYX"},
{"LSI", "CBG", "HAR", "AKS", "CELG"},
{"HES", "JNPR", "VRSN", "JDSU", "NYX"},
{"BK", "SWY", "C", "WAG", "GT"},
{"NUE", "AKS", "CHRW", "RSH", "WFR"},
{"PEG", "RSH", "VMC", "WY", "NOV"},
{"CLF", "WFR", "SNDK", "GT", "BIG"},
{"HAR", "CMI", "AKS", "SLM", "AMZN"},
{"RSH", "FCX", "AAPL", "MRO", "CLF"},
{"NOV", "SNDK", "F", "NVDA", "APOL"},
{"PCP", "AMZN", "NOV", "CMI", "JNPR"},
{"DE", "NVDA", "KIM", "BIG", "HCBK"},
{"CLF", "CNX", "FCX", "MON", "GS"},
{"DNR", "APOL", "TSO", "AKAM", "DV"},
{"DE", "UNH", "SCHW", "VRSN", "THC"},
{"MUR", "CNX", "X", "ADM", "HES"},
{"FHN", "CELG", "DHI", "ETFC", "PHM"},
{"DVN", "CHK", "DNR", "JDSU", "EOG"},
{"CSX", "X", "THC", "GME", "BIG"},
{"CMI", "BRCM", "CLF", "DV", "F"},
{"DELL", "A", "TE", "CLF", "CPWR"},
{"CLF", "CNX", "HP", "CHK", "JBL"},
{"AMGN", "RSH", "BAC", "FITB", "APOL"},
{"LB", "JCP", "TIE", "RL", "AMD"},
{"BBT", "MTB", "ICE", "ZION", "SNDK"},
{"DV", "AMP", "APOL", "SWN", "FHN"},
{"JEC", "AN", "NEM", "F", "ADM"},
{"ODP", "DRI", "PFG", "GNW", "HIG"},
{"SVU", "MS", "SLM", "TSO", "S"},
{"FCX", "ANF", "AKAM", "S", "DHI"},
{"GNW", "C", "XL", "BAC", "AIG"},
{"THC", "PFG", "ODP", "F", "GGP"},
{"THC", "FITB", "LNC", "ODP", "GNW"},
{"CBG", "LM", "STI", "AKS", "SLM"},
{"NYT", "MAS", "WYNN", "GT", "GCI"},
{"RF", "HIG", "GNW", "C", "AIG"},
{"CLF", "ODP", "AMD", "WYNN", "GCI"},
{"EL", "AKAM", "MCO", "LXK", "AMZN"},
{"S", "AKS", "X", "JDSU", "AMD"},
{"BTU", "NVDA", "NYT", "SNDK", "GCI"},
{"LEN", "FITB", "KEY", "HBAN", "ZION"},
{"WFM", "LXK", "JDSU", "CLF", "ARG"},
{"WFR", "PFG", "GME", "ANF", "TIE"},
{"VMC", "AKAM", "HBAN", "WHR", "ZION"},
{"MCK", "NTAP", "TIE", "SNDK", "S"},
{"HSP", "SRCL", "NEM", "BRK.B", "BHI"},
{"TIE", "PCLN", "IPG", "CTXS", "APC"},
{"ANR", "DVA", "ADM", "AKAM", "PCLN"},
{"JDSU", "ODP", "JCP", "KMX", "JBL"},
{"NOV", "EBAY", "WYNN", "MON", "MWW"},
{"URBN", "MWW", "GGP", "TSO", "HAR"},
{"RF", "JBL", "BTU", "AIG", "THC"},
{"MRO", "NFLX", "ISRG", "BTU", "NVDA"},
{"IPG", "TSO", "RDC", "BIG", "JDSU"},
{"NFLX", "MSI", "LO", "IRM", "WDC"},
{"GT", "ANF", "SVU", "LB", "BIIB"},
{"FFIV", "NFLX", "M", "EA", "DF"},
{"DV", "HOG", "KMX", "COG", "BIIB"},
{"CHK", "AAPL", "RRC", "GOOGL", "EQT"},
{"AN", "HCP", "AZO", "ORLY", "NEM"},
{"DUK", "KSS", "RHT", "SNDK", "GGP"},
{"JOY", "JNPR", "GT", "FFIV", "HAR"},
{"PXD", "EOG", "FTI", "EL", "PHM"},
{"PCS", "CTAS", "NVLS", "VMC", "GCI"},
{"EMN", "CA", "SHLD", "TXT", "NFLX"},
{"CSC", "CRM", "GPS", "WHR", "SHLD"},
{"FDO", "JPM", "BAC", "RHT", "PNR"},
{"RRC", "ORLY", "AMZN", "EXPE", "EW"},
{"WMT", "EXPE", "CBE", "GGP", "DF"},
{"EW", "COG", "SHLD", "S", "STZ"},
{"EXPE", "WAG", "WDC", "S", "DUK"},
{"LXK", "CVH", "CSC", "DF", "TSO"},
{"SWK", "GCI", "DV", "THC", "VMC"},
{"R", "CNX", "WHR", "KMX", "NFLX"},
{"THC", "CSC", "JDSU", "TIE", "ANF"},
{"STX", "GNW", "WDC", "CLF", "NYX"},
{"LIFE", "PBI", "BBY", "BTU", "NFLX"},
{"SEE", "HNZ", "HPQ", "SWY", "STZ"},
{"DTV", "GNW", "HPQ", "THC", "BBY"},
{"BBY", "MNST", "COH", "AKAM", "GME"},
{"HPQ", "GT", "BSX", "EA", "AMD"},
{"CVC", "CME", "MNST", "GCI", "GME"},
{"GT", "CELG", "ALXN", "FFIV", "OKE"},
{"GT", "CRM", "NFLX", "BBY", "WIN"},
{"ETFC", "YHOO", "SWY", "REGN", "MOLX"},
{"VLO", "X", "MCK", "HAR", "CLF"},
{"TXT", "MYL", "BIIB", "TSO", "JCP"},
{"DOW", "STX", "WYNN", "RHT", "LSI"},
{"JNPR", "FFIV", "ALXN", "BEAM", "HAR"},
{"SWY", "MYL", "EXPE", "AKAM", "FRX"},
{"HP", "TSN", "NFX", "X", "GNW"},
{"EQT", "COG", "APC", "POM", "AGN"},
{"SNDK", "GMCR", "EA", "NFLX", "GS"},
{"BTU", "TEG", "WMB", "IGT", "VRTX"},
{"THC", "FDO", "PETM", "TWX", "X"},
{"HD", "THC", "ROST", "GILD", "MNST"},
{"DRI", "DD", "NKE", "VRTX", "SIAL"},
{"MYL", "EW", "WHR", "TSCO", "KMX"},
{"WMT", "BBY", "TGT", "LUV", "WFM"},
{"RHT", "BMS", "KMX", "DO", "SPLS"},
{"BIIB", "EA", "HAR", "NFLX", "NEM"},
{"PCLN", "KSS", "FCX", "MLM", "HSP"},
{"RHT", "ABC", "CBG", "ALTR", "URBN"},
{"RRC", "DO", "RIG", "ESV", "NFLX"},
{"SWKS", "CVC", "PLL", "BRCM", "HUM"}};
string [,] stockListLosers = new string [125,5] {
{ "VRSN", "ADSK", "AMD", "EBAY", "JDSU"},
{ "JDSU", "MOLX", "RSH", "JNPR", "BIIB"},
{ "EA", "HAR", "WAT", "AKS", "NEE"},
{ "CLF", "F", "TER", "ADM", "AKS"},
{ "AES", "BSX", "PDCO", "DV", "MHFI"},
{ "CTXS", "NUE", "X", "EBAY", "AKS"},
{ "NTAP", "VRSN", "FIS", "MYL", "AVP"},
{ "JCP", "AKS", "VRSN", "ANF", "FDO"},
{ "PETM", "APOL", "ZMH", "LEG", "AVP"},
{ "TER", "CNX", "WFR", "THC", "LXK"},
{ "IPG", "SNDK", "CSC", "PDCO", "SYMC"},
{ "BBY", "DV", "APOL", "BBBY", "BTU"},
{ "YHOO", "INTC", "TSN", "JNPR", "EFX"},
{ "CLF", "EOG", "FCX", "EOG", "CELG"},
{ "STJ", "NVLS", "SCHW", "ANF", "AMD"},
{ "JNS", "NYX", "CI", "HAR", "AET"},
{ "NVDA", "BTU", "EA", "ADBE", "L"},
{ "JDSU", "AMD", "JBL", "MAR", "M"},
{ "BTU", "VRSN", "RHI", "AMZN", "TLAB"},
{ "HES", "S", "CELG", "VLO", "HSP"},
{ "CNX", "HAL", "YHOO", "BSX", "NEM"},
{ "JDSU", "BTU", "CTXS", "DGX", "APOL"},
{ "GPS", "INTU", "ANF", "CA", "WFM"},
{ "JNPR", "CNX", "JBL", "CHK", "LSI"},
{ "LXK", "STZ", "SYMC", "NVDA", "AMD"},
{ "SBUX", "CBG", "DHI", "PHM", "NYX"},
{ "DHI", "AMD", "LEN", "WY", "JBL"},
{ "NYX", "VAR", "MWW", "LSI", "DF"},
{ "AMGN", "CTSH", "NTAP", "SCHW", "JDSU"},
{ "DHI", "ODP", "PHM", "KIM", "LEN"},
{ "SHLD", "THC", "LXK", "CPWR", "RSH"},
{ "RL", "ETFC", "CBG", "MHFI", "THC"},
{ "ETFC", "TSN", "PHM", "LEN", "HAR"},
{ "MDT", "ALTR", "BIG", "SNDK", "COH"},
{ "AMD", "CTSH", "PHM", "LEN", "ETFC"},
{ "BIIB", "AMD", "CELG", "DRI", "SLM"},
{ "EXPE", "NVDA", "MSI", "AAPL", "HAR"},
{ "DF", "ODP", "APOL", "ADSK", "S"},
{ "APOL", "TIE", "HUM", "WLP", "MO"},
{ "FII", "WHR", "HBAN", "TSO", "FHN"},
{ "F", "KEY", "RF", "AIG", "LIFE"},
{ "AN", "RF", "XL", "KEY", "FITB"},
{ "CNX", "COG", "ODP", "NVDA", "FIS"},
{ "AKS", "WFM", "X", "HAR", "AIG"},
{ "MS", "CLF", "GNW", "AKS", "AIG"},
{ "AIV", "CVH", "LNC", "GGP", "HIG"},
{ "JDSU", "XL", "GGP", "GNW", "THC"},
{ "PKI", "ZION", "F", "NWL", "S"},
{ "BAC", "RF", "STI", "HBAN", "FITB"},
{ "ODP", "C", "HIG", "SLM", "AIG"},
{ "POM", "HRS", "MCK", "LNC", "GCI"},
{ "NEM", "APOL", "BLL", "INTU", "KEY"},
{ "LXK", "KEY", "PHM", "HOG", "DHI"},
{ "THC", "GCI", "VLO", "TSO", "AIG"},
{ "SLM", "AKAM", "S", "AIG", "AZO"},
{ "SWN", "PPL", "DF", "EA", "BHI"},
{ "FDO", "PHM", "DHI", "MCO", "MHFI"},
{ "BSX", "APOL", "GT", "S", "WFR"},
{ "JCP", "JEC", "AIG", "THC", "WFM"},
{ "ANF", "NEM", "STI", "HOG", "C"},
{ "X", "MSI", "AA", "KLAC", "AMD"},
{ "MWW", "DNB", "GME", "NYT", "DF"},
{ "RRC", "COG", "SPLS", "CHK", "CNX"},
{ "WFR", "MCO", "BAX", "AKS", "SBUX"},
{ "BHI", "JNS", "SHLD", "PCLN", "DF"},
{ "PHM", "HOG", "SHLD", "TLAB", "ODP"},
{ "NVDA", "WDC", "ETN", "LSI", "WY"},
{ "BHI", "SNDK", "AMD", "DV", "JBL"},
{ "CF", "ADBE", "ETN", "MON", "GGP"},
{ "RF", "SCHW", "LXK", "JDSU", "APOL"},
{ "RF", "CSCO", "SVU", "PHM", "DF"},
{ "CRM", "EXPE", "LB", "AKAM", "BBY"},
{ "RSH", "TLAB", "SVU", "MWW", "AIG"},
{ "WDC", "CSCO", "PHM", "EXPE", "AKAM"},
{ "NKE", "HCBK", "JDSU", "NVDA", "URBN"},
{ "AIG", "X", "HOG", "LXK", "NVLS"},
{ "SHLD", "BIG", "SPLS", "CSC", "BTU"},
{ "BTU", "WFR", "AMD", "OI", "NVDA"},
{ "IPG", "S", "AKAM", "AKS", "JNPR"},
{ "AKS", "TXT", "DV", "CBG", "PHM"},
{ "HP", "HAL", "FCX", "CLF", "NFLX"},
{ "HSP", "BTU", "S", "NFLX", "ITT"},
{ "NFLX", "CSC", "SHLD", "WFR", "ANF"},
{ "RHT", "NFX", "JOY", "ORCL", "SHLD"},
{ "GOOGL", "S", "EA", "SVU", "COG"},
{ "EW", "X", "EA", "CLF", "APOL"},
{ "GT", "SVU", "NEM", "JOY", "BHI"},
{ "SHLD", "CHK", "SNDK", "GNW", "NFLX"},
{ "DELL", "JCP", "X", "ANF", "FOSL"},
{ "ORLY", "BBBY", "BTU", "R", "NKE"},
{ "APOL", "AMD", "IGT", "LXK", "DV"},
{ "CLF", "FE", "SPLS", "BIG", "BF.B"},
{ "AMD", "INTC", "LSI", "NSC", "JBL"},
{ "JDSU", "FFIV", "VRSN", "APOL", "AMD"},
{ "KSS", "CVC", "CLF", "PBI", "JCP"},
{ "LB", "AAPL", "FDO", "FCX", "DRI"},
{ "MNST", "FDO", "X", "AAPL", "SPG"},
{ "CTL", "APOL", "MHFI", "NFX", "CLF"},
{ "ISRG", "PVH", "JCP", "BTU", "CLF"},
{ "FLR", "SWY", "CTSH", "EW", "NEM"},
{ "CLF", "EXC", "FE", "DF", "NBL"},
{ "VLO", "TSO", "LUK", "CNX", "IRM"},
{ "JCP", "BRCM", "EXPE", "ISRG", "MOS"},
{ "AVP", "SPLS", "JCP", "TSO", "ANF"},
{ "MNST", "CAG", "NEM", "URBN", "JCP"},
{ "AKAM", "AVP", "JCP", "CTXS", "PPG"},
{ "PXD", "HCN", "FE", "EA", "BTU"},
{ "LH", "APC", "DGX", "NFX", "JBL"},
{ "IGT", "BBBY", "CLF", "GME", "BBY"},
{ "DNB", "CHRW", "CAG", "KSU", "COG"},
{ "CELG", "ALXN", "GILD", "SPLS", "NFLX"},
{ "BAC", "VRSN", "CLF", "XLNX", "ISRG"},
{ "ETFC", "SPLS", "X", "PETM", "WFM"},
{ "REGN", "VLO", "PVH", "TSN", "COH"},
{ "YUM", "DHI", "CNX", "NRG", "GNW"},
{ "CTSH", "TWX", "NE", "WYNN", "WAG"},
{ "RIG", "ESV", "NE", "DO", "APH"},
{ "AVP", "APA", "DNR", "BHI", "NEM"},
{ "HAL", "PXD", "RIG", "DNR", "GNW"},
{ "SWN", "EQT", "WYNN", "RRC", "SRE"},
{ "TIF", "FTI", "URI", "SNDK", "FCX"},
{ "GAS", "FE", "ESV", "CHK", "RL"},
{ "STX", "CHK", "WDC", "LRCX", "NEM"},
{ "URBN", "AMAT", "WHR", "PHM", "RCL"},
{ "CNX", "FCX", "FOSL", "AVP", "GMCR"}};
}
}using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QuantConnect;
using QuantConnect.Models;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Orders;
using QuantConnect.Securities.Interfaces;
namespace QuantConnect.Securities
{
/********************************************************
* CLASS DEFINITIONS
*********************************************************/
/// <summary>
/// Custom Transaction Model Example
/// </summary>
public class sp500BacktestSecurityModel : SecurityTransactionModel, ISecurityTransactionModel
{
/********************************************************
* CLASS CONSTRUCTOR
*********************************************************/
/// <summary>
/// Custom transaction model class.
/// </summary>
public sp500BacktestSecurityModel()
{ }
public override OrderEvent StopMarketFill(Security asset, StopMarketOrder order)
{
//Default order event to return.
var fill = new OrderEvent(order);
// make sure the exchange is open before filling
var currentBar = asset.GetLastData();
if (!asset.Exchange.IsOpenDuringBar(currentBar.Time, currentBar.EndTime, false)) return fill;
try
{
//If its cancelled don't need anymore checks:
if (order.Status == OrderStatus.Canceled) return fill;
//Get the range of prices in the last bar:
decimal minimumPrice;
decimal maximumPrice;
DataMinMaxPrices(asset, out minimumPrice, out maximumPrice);
//Calculate the model slippage: e.g. 0.01c
var slip = GetSlippageApproximation(asset, 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 (minimumPrice < order.StopPrice)
{
order.Status = OrderStatus.Filled;
Console.WriteLine(minimumPrice + " " + order.StopPrice);
// Assuming worse case scenario fill - fill at lowest of the stop & asset price.
order.Price = Math.Min(order.StopPrice, asset.Price - slip);
}
break;
case OrderDirection.Buy:
//-> 1.2 Buy Stop: If Price Above Setpoint, Buy:
if (maximumPrice > order.StopPrice)
{
order.Status = OrderStatus.Filled;
// Assuming worse case scenario fill - fill at highest of the stop & asset price.
order.Price = Math.Max(order.StopPrice, asset.Price + slip);
}
break;
}
if (order.Status == OrderStatus.Filled || order.Status == OrderStatus.PartiallyFilled)
{
fill.FillQuantity = order.Quantity;
fill.FillPrice = order.Price; //we picked the correct fill price above, just respect it here
fill.Status = order.Status;
}
}
catch (Exception err)
{
Console.WriteLine("SecurityTransactionModel.StopMarketFill(): " + err.Message);
}
return fill;
}
/// <summary>
/// Example Override of Fee Model - $10 Per Trade Fee
/// </summary>
public override decimal GetOrderFee(decimal quantity, decimal price)
{
return 5;
}
} // End Algorithm Transaction Filling Classes
}using System;
using System.Collections;
using System.Collections.Generic;
using QuantConnect.Securities;
using QuantConnect.Models;
using QuantConnect.Orders;
namespace QuantConnect {
public partial class SP500Backtest : QCAlgorithm, IAlgorithm {
public class Stock : IComparable<Stock> {
public string name { get; set; }
public decimal start { get; set; }
public decimal end { get; set; }
public decimal gain { get; set; }
public int CompareTo(Stock obj) {
return gain.CompareTo(obj.gain);
}
}
public class PortfolioStock {
public string name { get; set; }
public decimal entryPrice { get; set; }
}
public List<Stock> getStockListMonthStart(TradeBars data, string[] stockNames) {
List<Stock> stockList = new List<Stock>();
foreach (string name in stockNames) {
Stock s = new Stock();
s.name=name;
s.start = data[name].Price;
stockList.Add(s);
Securities[name].TransactionModel = new sp500BacktestSecurityModel();
}
return stockList;
}
public string[] getStockListMonth(int year, int month, string[,] sList) {
string[] stockListMonth = new string[sList.GetLength(1)];
int dt = (year-2005)*12+(month-2);
for (int i=0; i<sList.GetLength(1); i++) {
stockListMonth[i]=sList[dt,i];
}
return stockListMonth;
}
public List<Stock> getStockListMonthEnd(TradeBars data, List<Stock> stockList) {
for (int i=0; i < stockList.Count(); i++ ) {
stockList[i].end = data[stockList[i].name].Price;
stockList[i].gain = (stockList[i].end - stockList[i].start)/stockList[i].start;
}
return stockList;
}
public int getFirstTradingDayInMonth(int year, int month) {
DateTime time = new DateTime(year, month, 1);
//check if new years day
if (month==1) {
if (time.ToString("ddd") == "Fri") {
return 4;
}
else {
return 2;
}
}
if (time.ToString("ddd") == "Sat" && time.Day==1) {
return 3;
}
if (time.ToString("ddd") == "Sun" && time.Day==1) {
return 2;
}
return 1;
}
public int getLastTradingDayInMonth(DateTime time) {
int numDays = System.DateTime.DaysInMonth(time.Year, time.Month);
DateTime lastDay = new DateTime(time.Year, time.Month, numDays);
if (time.Month==11 && lastDay.ToString("ddd")=="Sun") {
return 28;
}
if (lastDay.ToString("ddd") == "Sat") {
return numDays-1;
}
else if (time.ToString("ddd") == "Sun") {
return numDays-2;
}
else {
return numDays;
}
}
public decimal getQuantity(Double cash, Double price) {
Double maxCashForEquity = cash*.05; //position cannot exceed 5% of overall portfolio
return Convert.ToDecimal(Math.Abs(maxCashForEquity/price));
}
}
}using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using QuantConnect.Securities;
using QuantConnect.Models;
namespace QuantConnect
{
public partial class SP500Backtest : QCAlgorithm, IAlgorithm {
private decimal cash = 100000;
List<Stock> sg = new List<Stock>();
List<Stock> sl = new List<Stock>();
int lastDay;
string[] stockListMonthGainers;
string[] stockListMonthLosers;
//Initialize the Strategy
public override void Initialize() {
SetCash(cash);
SetStartDate(2005,1, 1);
SetEndDate(2005, 3, 31);
foreach (string symbol in stockListInit) {
AddSecurity(SecurityType.Equity, symbol, Resolution.Minute);
}
}
//Handle the data events:
public void OnData(TradeBars data) {
lastDay = getLastTradingDayInMonth(Time);
if (Time.Day == getFirstTradingDayInMonth(Time.Year, Time.Month) && Time.ToString("HH")=="10" && Time.ToString("mm")=="00") {
stockListMonthGainers = getStockListMonth(Time.Year, Time.Month, stockListGainers);
stockListMonthLosers = getStockListMonth(Time.Year, Time.Month, stockListLosers);
//get the stock list for the month
sg = getStockListMonthStart(data, stockListMonthGainers);
sl = getStockListMonthStart(data, stockListMonthLosers);
if (sg.Count()!= 0 && sl.Count()!= 0 && !Portfolio.HoldStock) {
//go long on top 5 performing stocks from last month
for (int i=0; i<sg.Count(); i++) {
int quantity = (int)getQuantity(Convert.ToDouble(Portfolio.Cash), Convert.ToDouble(data[sg[i].name].Price));
Order(sg[i].name, quantity);
StopMarketOrder(sg[i].name, -quantity, data[sg[i].name].Price*(decimal).75);
}
//go short on 5 worst performing stocks from last month
for (int i=0; i<sl.Count(); i++ ) {
int quantity = (int)getQuantity(Convert.ToDouble(Portfolio.Cash), Convert.ToDouble(data[sl[i].name].Price));
Order(sl[i].name, -quantity);
StopMarketOrder(sl[i].name, quantity, data[sl[i].name].Price*(decimal)1.25);
}
}
}
//liquidate at the end of the month
if (Time.Day == lastDay) {
if (Time.ToString("HH")=="15" && Time.ToString("mm")=="59") {
Liquidate();
}
}
}
}
}