| Overall Statistics |
|
Total Trades 1061 Average Win 0.26% Average Loss -0.18% Compounding Annual Return 13.428% Drawdown 12.800% Expectancy 0.099 Net Profit 8.750% Sharpe Ratio 0.979 Loss Rate 55% Win Rate 45% Profit-Loss Ratio 1.45 Alpha 0.123 Beta -0.094 Annual Standard Deviation 0.112 Annual Variance 0.012 Information Ratio -0.229 Tracking Error 0.163 Treynor Ratio -1.159 Total Fees $1159.28 |
using MathNet.Numerics.Distributions;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Indicators;
using QuantConnect.Orders;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace QuantConnect.Algorithm.CSharp
{
public class BasicTemplateAlgorithm : QCAlgorithm
{
//Count the number of days that pass, so that the algo only executes every 2 weeks
int countDay = 0;
//Create a Dictionary to store each security and a rolling window of their closing price for the past 20 trading days
Dictionary<Symbol, RollingWindow<decimal>> _storage = new Dictionary<Symbol, RollingWindow<decimal>>();
//Create a list to capture the stocks that are entered into the universe
List<Symbol> top10Gainers = new List<Symbol>();
List<Symbol> top10Losers = new List<Symbol>();
//Create list to record the positive and negative price movers each iteration of the algo
List<Symbol> recordPositiveChanges = new List<Symbol>();
List<Symbol> recordNegativeChanges = new List<Symbol>();
public override void Initialize()
{
SetStartDate(2012, 9, 01);
SetEndDate(2013, 5, 01);
SetCash(50000);
UniverseSettings.Resolution = Resolution.Daily;
AddUniverse(CoarseSelectionFunction);
}
public IEnumerable<Symbol> CoarseSelectionFunction(IEnumerable<CoarseFundamental> coarse)
{
///Add each security in the coarse library to the dictionary, along with the price for that day to its rolling window
///if the security already exists in the Dictionary, just add that day's price to that security's
///Rolling window.
foreach (var coarseItem in coarse)
{
if (!_storage.ContainsKey(coarseItem.Symbol))
{
_storage.Add(coarseItem.Symbol, new RollingWindow<decimal>(20));
}
_storage[coarseItem.Symbol].Add(coarseItem.Price);
}
//Create a list of the top 100 stocks by dollar volume and store by their symbol
var findTop100 = (from coarseItem in coarse
where _storage[coarseItem.Symbol].Count == 20
orderby coarseItem.DollarVolume descending
select coarseItem.Symbol).Take(100);
//Count how many days have passed
countDay++;
//Return empty / nothing until 20 days pass
//Then, only return the universe if 1 week has passed yet
if (!(countDay >= 20))
return new List<Symbol>();
else if (Time.DayOfWeek == DayOfWeek.Thursday)
{
//If 1 week has passed, then return a new universe
//Clear out the universe list so it can be updated
top10Gainers.Clear();
top10Losers.Clear();
//Create a list to contain the top 10 stocks with the highest positive price change
top10Gainers = (from symbol in findTop100
let start = _storage[symbol][19]
let end = _storage[symbol][0]
let delta = (end - start) / start
orderby delta descending
select symbol).Take(10).ToList();
//Create a list to contain the top 10 stocks with the highest negative price change
top10Losers = (from symbol in findTop100
let start = _storage[symbol][19]
let end = _storage[symbol][0]
let delta = (end - start) / start
orderby delta ascending
select symbol).Take(10).ToList();
//Create a universe which will be returned to include all stocks that need to be analyzed
var universe = new List<Symbol>();
universe.AddRange(top10Gainers);
universe.AddRange(top10Losers);
return universe;
}
else return new List<Symbol>();
}
public void OnData(TradeBars data)
{
// schedule an event to fire on certain days of the week
if (Time.DayOfWeek == DayOfWeek.Friday)
{
Liquidate();
//Short stocks that are doing well, and long stocks that have not done well in the past 2 weeks
//Then add the respective stocks to a list to be used the next iteration of the algo
foreach (var security in top10Gainers)
{
//Order(security, -10);
SetHoldings(security, -.07m);
}
foreach (var security in top10Losers)
{
//Order(security, 10);
SetHoldings(security, .07m);
}
}
//Console.WriteLine(Portfolio.Cash);
}
}
}