Overall Statistics |
Total Trades 30 Average Win 5.64% Average Loss -8.01% Compounding Annual Return 5.066% Drawdown 15.700% Expectancy -0.148 Net Profit 161.360% Sharpe Ratio 0.625 Loss Rate 50% Win Rate 50% Profit-Loss Ratio 0.70 Alpha -0.055 Beta 5.403 Annual Standard Deviation 0.085 Annual Variance 0.007 Information Ratio 0.39 Tracking Error 0.085 Treynor Ratio 0.01 Total Fees $2674.49 |
namespace QuantConnect { public class BasicTemplateAlgorithm : QCAlgorithm { public string[] Symbols = {"XLY","XLP","XLE","XLF","XLV","XLI","XLB","XLK","XLU"}; private Dictionary<string, double> Elo = new Dictionary<string, double>(); private Dictionary<string, RollingWindow<decimal>> Return = new Dictionary<string, RollingWindow<decimal>>(); private Dictionary<string, decimal> Price = new Dictionary<string, decimal>(); public Dictionary<string, double> StandardDevation = new Dictionary<string, double>(); public override void Initialize() { SetStartDate(2000, 1, 1); SetEndDate(DateTime.Now); SetCash(1000000); SetWarmup(250); foreach (var symbol in Symbols) { AddSecurity(SecurityType.Equity,symbol,Resolution.Daily); Elo[symbol] = 1500; Return[symbol] = new RollingWindow<decimal>(50); Price[symbol] = 0; StandardDevation[symbol] = 0.0; Securities[symbol].SetLeverage(10); } } public void OnData(TradeBars data) { foreach (var symbol in Symbols) { if (!data.ContainsKey(symbol)) continue; if (Time.DayOfWeek == DayOfWeek.Thursday) { var K = 2; int C = 200; if (Price[symbol] != 0) { Return[symbol].Add(data[symbol].Close / Price[symbol]); } Price[symbol] = data[symbol].Close; foreach (var sector in Symbols) { if (!Return[symbol].IsReady) continue; if (!Return[sector].IsReady) continue; StandardDevation[symbol] = Math.Sqrt(Return[symbol].Sum(d => Math.Pow(Convert.ToDouble(d - Return[symbol].Average()), 2)))/(Return[symbol].Count()-1); if (((double)(Return[symbol][0])/StandardDevation[symbol]) > ((double)(Return[sector][0])/StandardDevation[sector])) { Elo[symbol] = Elo[symbol] + ((K/2)*(1 + (Elo[sector] - Elo[symbol])/(C*2))); } if (((double)(Return[symbol][0])/StandardDevation[symbol]) < ((double)(Return[sector][0])/StandardDevation[sector])) { Elo[symbol] = Elo[symbol] + ((K/2)*(-1 + (Elo[sector] - Elo[symbol])/(C*2))); } } } } string max = Elo.Aggregate((l, r) => l.Value > r.Value ? l : r).Key; string min = Elo.Aggregate((l, r) => l.Value < r.Value ? l : r).Key; if (Time.DayOfWeek == DayOfWeek.Thursday) { foreach (var symbol in Symbols) { if (Portfolio[symbol].IsLong && symbol != max) { SetHoldings(symbol, 0, false); } if (Portfolio[symbol].IsShort && symbol != min) { SetHoldings(symbol, 0, false); } Plot("Elo's ", "Elo " + symbol, Elo[symbol]); } var Ea = 1/(1 + Math.Pow(10,(Elo[min]-Elo[max])/400)); var Eb = 1 - Ea; var weight = (double)((Ea-Eb)); var Ratio = (StandardDevation[max]/StandardDevation[min])+1; var maxweight = (weight/Ratio); if (Elo[max] != 1500 && Elo[min] != 1500 && Elo[max] != Elo[min] && !Portfolio[max].IsLong) { SetHoldings(max, (float)maxweight, false, "Long " + max + " Elo is " + Math.Round(Elo[max],2) + " Odds are " + Math.Round(Ea,2)); } if (Elo[max] != 1500 && Elo[min] != 1500 && Elo[max] != Elo[min] && !Portfolio[min].IsShort) { SetHoldings(min, (float)-(weight-maxweight), false, "Short " + min + " Elo is " + Math.Round(Elo[min],2)); } } } } }