| Overall Statistics |
|
Total Trades 1 Average Win 0% Average Loss 0% Compounding Annual Return 0.916% Drawdown 2.300% Expectancy 0 Net Profit 0.916% Sharpe Ratio 0.371 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha -0.01 Beta 0.99 Annual Standard Deviation 0.024 Annual Variance 0.001 Information Ratio -0.416 Tracking Error 0.024 Treynor Ratio 0.009 Total Fees $2.44 |
namespace QuantConnect.Rotation
{
public class GlobalRotation : QCAlgorithm
{
/* Should we include Money market fund in rotation for growth? If money market
has highest momentum it would rotate into it?*/
// these are the growth symbols we'll rotate through
List<string> GrowthSymbols = new List<string>
{
"BSJJ", // US S&P mid cap 400
"HYD", // iShares S&P europe 350
"SRLN", // iShares S&P latin america
"VMBS", // iShares S&P latin america
};
// these are the safety symbols we go to when things are looking bad for growth
List<string> SafetySymbols = new List<string>
{
// "CASHX", // Vangaurd TSY 25yr+
// "SHY" // Barclays Low Duration TSY
};
// we'll hold some computed data in these guys
public override void Initialize()
{
List<string> allSymbols = GrowthSymbols.Union(SafetySymbols).ToList();
Dictionary<string, SymbolData> allSymbolData = new Dictionary<string, SymbolData>();
SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage);
// Portfolio.MarginCallModel = MarginCallModel.Null;
double leverage = 1.0;
SetCash(25000);
SetStartDate(2018, 1, 1);
SetEndDate(2019, 1, 1);
foreach (var symbol in allSymbols) {
AddSecurity(SecurityType.Equity, symbol, Resolution.Daily);
var oneMonthPerformance = MOMP(symbol, 21, Resolution.Daily);
var threeMonthPerformance = MOMP(symbol, 42, Resolution.Daily);
allSymbolData.Add(symbol, new SymbolData
{
Symbol = symbol,
oneMonthPerformanceMOMP = oneMonthPerformance,
threeMonthPerformanceMOMP = threeMonthPerformance
});
}
Schedule.On(DateRules.Every(DayOfWeek.Monday), TimeRules.At(9, 29), () =>
{
IEnumerable<SymbolData> oneMonthOrderedByMOMP =
allSymbolData
.OrderByDescending(x => x.Value.oneMonthPerformanceMOMP)
.Select(x => x.Value)
.AsEnumerable();
// assign it's one month rank to the original object in allSymbolData
int oneMonthCounter = 0;
foreach(var item in oneMonthOrderedByMOMP) {
oneMonthCounter++;
allSymbolData[item.Symbol].oneMonthRank = oneMonthCounter;
};
// get the order based on three month
IEnumerable<SymbolData> threeMonthOrderedByMOMP =
allSymbolData
.OrderByDescending(x => x.Value.threeMonthPerformanceMOMP)
.Select(x => x.Value)
.AsEnumerable();
// assign it's three month rank to the original object in allSymbolData
int threeMonthCounter = 0;
foreach(var item in threeMonthOrderedByMOMP) {
threeMonthCounter++;
allSymbolData[item.Symbol].threeMonthRank = threeMonthCounter;
};
// get the new order based on the allSymbolData object's with their shiny new one/threemonth calculated score
Dictionary<string, SymbolData> orderedSymbols = allSymbolData.OrderByDescending(x => x.Value.calculateTotalScore()).ToDictionary();
// bank
var bestGrowth = orderedSymbols.First().Value;
if (bestGrowth.calculateTotalScore() > 0)
{
if (Portfolio[bestGrowth.Symbol].Quantity == 0)
{
Log("PREBUY>>LIQUIDATE>>");
Liquidate();
}
Log(">>BUY>>" + bestGrowth.Symbol + "@" + (100 * bestGrowth.calculateOneMonthPerformance()).ToString("00.00"));
SetHoldings(bestGrowth.Symbol, leverage);
}
else
{
// if no one has a good objective score then let's hold cash this month to be safe
Log(">>LIQUIDATE>>CASH");
Liquidate();
}
});
}
public void OnData(TradeBars data)
{
}
}
class SymbolData {
public string Symbol = "";
public decimal oneMonthWeight = 51;
public decimal threeMonthWeight = 49;
public decimal oneMonthPerformanceMOMP = 0.0M;
public decimal threeMonthPerformanceMOMP = 0.0M;
public int oneMonthRank = 0;
public int threeMonthRank = 0;
public decimal calculateOneMonthPerformance() {
return (oneMonthWeight * oneMonthRank / oneMonthWeight);
}
public decimal calculateThreeMonthPerformance() {
return (threeMonthWeight * threeMonthRank / threeMonthWeight);
}
public decimal calculateTotalScore() {
return calculateOneMonthPerformance() + calculateThreeMonthPerformance();
}
}
}