| Overall Statistics |
|
Total Trades 1343 Average Win 1.56% Average Loss -1.53% Compounding Annual Return 16.128% Drawdown 23.700% Expectancy 0.178 Net Profit 418.813% Sharpe Ratio 0.85 Loss Rate 42% Win Rate 58% Profit-Loss Ratio 1.02 Alpha 0.123 Beta 0.163 Annual Standard Deviation 0.159 Annual Variance 0.025 Information Ratio 0.272 Tracking Error 0.218 Treynor Ratio 0.829 Total Fees $6487.18 |
//Copyright HardingSoftware.com, granted to the public domain.
//Use entirely at your own risk.
//This algorithm contains open source code from other sources,
//no claim is being made to such code.
//Do not remove this copyright notice.
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data.Market;
using QuantConnect.Data.UniverseSelection;
namespace QuantConnect.Algorithm.CSharp
{
public class UniverseTemplate : QCAlgorithm
{
SecurityChanges securityChanges = SecurityChanges.None;
List<StockData> highDollarVolumeStocks=new List<StockData>();
int totalHighDollarVolumeStocks=5;
int totalSortedStocks=1;
Resolution resolution=Resolution.Daily;
public override void Initialize()
{
UniverseSettings.Resolution = resolution;
SetStartDate(2006, 8, 30);
SetEndDate(2017, 8, 30);
SetCash(25000);
AddUniverse(coarse =>
{
return (from stock in coarse
//where stock.HasFundamentalData == false
orderby stock.DollarVolume descending
select stock.Symbol).Take(totalHighDollarVolumeStocks);
});
}
public void OnData(TradeBars data)
{
int period=3;
foreach (StockData stockData in highDollarVolumeStocks)
{
if (Securities.ContainsKey(stockData.Ticker))
{
TradeBar[] bars=History(stockData.Ticker,period,resolution).ToArray();
decimal[] closes=bars.Select(x=>x.Close).ToArray();
if (bars!=null && bars.Length==period)
{
stockData.Changes1=ChangesPercent(closes);
stockData.Changes2=Changes(stockData.Changes1);
stockData.Fitness=-stockData.Changes1.Last();
if (stockData.Changes2.Last()<0)
{
stockData.Fitness=-1000;
}
}
}
else
{
stockData.Fitness=-1000;
}
}
var sortedStocksEnumerable = from x in highDollarVolumeStocks
orderby x.Fitness descending
select x;
List<StockData> sortedStocks=sortedStocksEnumerable.Where(x=>x.Fitness>0m).Take(totalSortedStocks).ToList();
foreach (var security in Portfolio.Values)
{
if (Securities.ContainsKey(security.Symbol))
{
if (sortedStocks.Exists(x=>x.Ticker==security.Symbol)==false)
{
Liquidate(security.Symbol);
}
}
}
foreach (var security in sortedStocks)
{
if (Securities.ContainsKey(security.Ticker))
{
if (Portfolio[security.Ticker].Invested==false)
{
SetHoldings(security.Ticker,0.99m/(decimal)sortedStocks.Count);
}
}
}
}
public class StockData
{
public string Ticker;
public decimal[] Changes1;
public decimal[] Changes2;
public decimal Fitness;
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
securityChanges = changes;
foreach (var security in securityChanges.RemovedSecurities)
{
List<StockData> stockDatas=highDollarVolumeStocks.Where(x=>x.Ticker==security.Symbol).ToList();
if (stockDatas.Count>=1)
{
highDollarVolumeStocks.Remove(stockDatas.First());
}
}
foreach (var security in securityChanges.AddedSecurities)
{
StockData stockData=new StockData();
stockData.Ticker=security.Symbol;
highDollarVolumeStocks.Add(stockData);
}
securityChanges = SecurityChanges.None;
}
public static decimal[] Changes(decimal[] values)
{
List<decimal> lOut = new List<decimal>();
for (int i = 0; i < values.Length - 1; i++)
{
lOut.Add(values[i + 1] - values[i]);
}
return lOut.ToArray();
}
public static decimal[] ChangesPercent(decimal[] values)
{
List<decimal> lOut = new List<decimal>();
for (int i = 0; i < values.Length - 1; i++)
{
lOut.Add((values[i + 1] - values[i]) / values[i]);
}
return lOut.ToArray();
}
}
}