| Overall Statistics |
|
Total Trades 96 Average Win 7.23% Average Loss 0% Compounding Annual Return 38.289% Drawdown 48.100% Expectancy 0 Net Profit 4358.405% Sharpe Ratio 1.319 Probabilistic Sharpe Ratio 74.168% Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha 0.18 Beta 0.278 Annual Standard Deviation 0.212 Annual Variance 0.045 Information Ratio -0.22 Tracking Error 0.353 Treynor Ratio 1.006 Total Fees $199.28 Estimated Strategy Capacity $800000.00 Lowest Capacity Asset TMF UBTUG7D0B7TX |
namespace QuantConnect.Algorithm.CSharp
{
public class Hedgefundie : QCAlgorithm
{
private const string EquitySymbol = "UPRO";
private const string BondSymbol = "TMF";
private const decimal EquityPercent = 0.55m;
private const decimal BondPercent = 0.45m;
private DateTime NextRebalanceDate;
private bool IsRebalancingDay => this.Time.Year == this.NextRebalanceDate.Year &&
this.Time.Month == this.NextRebalanceDate.Month &&
this.Time.Day == this.NextRebalanceDate.Day;
private List<string> EndOfDayTickerData = new List<string>();
public override void Initialize()
{
SetStartDate(2010, 02, 10);
SetEndDate(DateTime.Now.AddDays(-1));
SetCash(10000);
SetBenchmark(EquitySymbol);
SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage);
AddEquity(EquitySymbol, Resolution.Minute);
AddEquity(BondSymbol, Resolution.Minute);
this.NextRebalanceDate = this.CalculateNextRebalanceDate();
this.Schedule.On(DateRules.EveryDay(), TimeRules.At(10, 0), () =>
{
if (this.IsRebalancingDay && !this.IsMarketOpen(EquitySymbol))
{
this.NextRebalanceDate = this.NextRebalanceDate.AddDays(1);
this.Log("Markets not open today. Checking again tomorrow.");
}
});
}
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// Slice object keyed by symbol containing the stock data
public override void OnData(Slice data)
{
}
public override void OnEndOfDay(string symbol)
{
EndOfDayTickerData.Add(symbol);
if (EndOfDayTickerData.Contains(EquitySymbol) &&
EndOfDayTickerData.Contains(BondSymbol))
{
if (!this.Portfolio.Invested || IsRebalancingDay)
{
Rebalance();
}
EndOfDayTickerData.Clear();
}
}
private DateTime CalculateNextRebalanceDate()
{
var rebalanceDates = new List<DateTime>
{
new DateTime(this.Time.Year, 4, 1),
new DateTime(this.Time.Year, 7, 1),
new DateTime(this.Time.Year, 10, 1),
new DateTime(this.Time.Year + 1, 1, 1),
}.OrderBy(d => d);
var thisDate = this.Time.AddDays(1);
var nextRebalanceDate = thisDate >= rebalanceDates.Last()
? rebalanceDates.Last()
: thisDate <= rebalanceDates.First()
? rebalanceDates.First()
: rebalanceDates.First(d => d >= thisDate);
while (nextRebalanceDate.DayOfWeek == DayOfWeek.Saturday || nextRebalanceDate.DayOfWeek == DayOfWeek.Sunday)
{
nextRebalanceDate = nextRebalanceDate.AddDays(1);
}
return nextRebalanceDate;
}
private void Rebalance()
{
this.SetHoldings(new List<PortfolioTarget>()
{
new PortfolioTarget(EquitySymbol, EquityPercent),
new PortfolioTarget(BondSymbol, BondPercent)
});
this.NextRebalanceDate = CalculateNextRebalanceDate();
this.Log($"Rebalanced portfolio. Next rebalance: {this.NextRebalanceDate:yyyy-MM-dd}");
}
}
}