Overall Statistics |
Total Trades 6 Average Win 19.50% Average Loss 0% Compounding Annual Return 14.272% Drawdown 17.900% Expectancy 0 Net Profit 70.452% Sharpe Ratio 0.886 Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha 0.121 Beta 1.31 Annual Standard Deviation 0.166 Annual Variance 0.027 Information Ratio 0.765 Tracking Error 0.166 Treynor Ratio 0.112 Total Fees $6.09 |
namespace QuantConnect.Algorithm.CSharp { /// <summary> /// Basic template algorithm simply initializes the date range and cash. This is a skeleton /// framework you can use for designing an algorithm. /// </summary> public class BasicTemplateAlgorithm : QCAlgorithm { private Symbol _symbol = QuantConnect.Symbol.Create("GOOGL", SecurityType.Equity, Market.USA); private decimal _price; private List<TradeBar> _TradeBar_window; private RollingWindow<TradeBar> RollWindow; private List<TradeBar> MyHistory; private int BackwardLookingPeriod = 7*50; SimpleMovingAverage _smaOnMyTimePeriod; private int minutesToExecute = 10; private int timeRoller = 0; private int ForwardLookingPeriod = 35; private Boolean maxCounter = false;//dont change this. private int WarmUpPeriod = 0; private decimal RelevantClose ; private decimal PurchaseClose ; private decimal FallFactor = 1m; private decimal RiseFactor = 0.7m; private decimal StopLossPct; private decimal StopLossPctAdjuster = 5m; private decimal maxPrice; private decimal deltaPCT; private int NumberOfMax; private int NumberOfMin; private OrderTicket CurrentOrder; private OrderTicket StopLoss; private OrderTicket ProfitTarget; private List <TradeBar> ListOfMax = new List<TradeBar>(); private List <TradeBar> ListOfMin = new List<TradeBar>(); decimal FallAmount; decimal RiseAmount; decimal AverageFallPct; decimal AverageRisePct; public override void Initialize() { SetStartDate(2014, 01, 01); //Set Start Date SetEndDate(2018, 01, 01); //Set End Date SetCash(100000); //Set Strategy Cash AddEquity(_symbol, Resolution.Daily); //INITIALISE THE HISTORICAL PERIOD// _TradeBar_window = new List<TradeBar>(BackwardLookingPeriod); IEnumerable<TradeBar> slices = History(_symbol, BackwardLookingPeriod); foreach (TradeBar bar in slices) { _TradeBar_window.Add(bar); } //SET WARMUP Debug("The last element in the initial history is: " + _TradeBar_window.Last().Time); SetWarmUp(WarmUpPeriod); Debug("Setting warm up"); //SCHEDULE THE ACTUAL CODE TO HAPPEN AND WHEN IT HAPPENS // Schedule.On( DateRules.EveryDay(_symbol), TimeRules.AfterMarketOpen(_symbol,minutesToExecute), //Execute the function at the start of the day // x minutes in.... EveryDayOnMarketOpen ); } //DEFINE THE FUNCTION THAT YOU CALL ON THE MARKET public void EveryDayOnMarketOpen(){ ListOfMax.Clear(); ListOfMin.Clear(); maxCounter = false; // Debug("Number of things at start of day is: " + ListOfMax.Count); //Debug("The time since start is: " + timeRoller); if(timeRoller ==527) {Debug("In period 527"); Debug("Tradebar window is of size: " + _TradeBar_window.Count); Debug("Number of things at start of day is: " + ListOfMax.Count); Debug("Number of things at start of day is: " + ListOfMin.Count); } timeRoller ++ ; //RollWindow = new RollingWindow<TradeBar>(BackwardLookingPeriod); var history = History(_symbol,1,Resolution.Daily); foreach (var i in history) { // RollWindow.Add(i);//The rolling window just runs for all the periods each time it is called with IENumerable _TradeBar_window.Add(i); }//END OF FOR EACH // Debug("Tradebar window is now size: "+ _TradeBar_window.Count); for ( var i = ForwardLookingPeriod ; i<_TradeBar_window.Count - ForwardLookingPeriod ; i++ ) { decimal currentClose = _TradeBar_window[i].Close; _price = currentClose; DateTime currentTime = _TradeBar_window[i].Time; decimal maxRoller; decimal minRoller; //if(timeRoller == 50 ) { // Debug("At time 50 the close is: " + currentClose); // Debug("At time 50 the close is: " + currentTime); //} THE DATE YOU GET DOES INCREASE AS I INCREASES List<TradeBar> subList = _TradeBar_window.ToList().GetRange( i - ForwardLookingPeriod,ForwardLookingPeriod*2); maxRoller = subList.Max(r => r.Close); minRoller = subList.Min(r => r.Close); //Debug( max is: "+ maxRoller); // Debug("The mins: "+ minRoller); //Debug("The current is: " + currentClose); if (currentClose == maxRoller && maxCounter == false) { ListOfMax.Add(_TradeBar_window[i]); maxCounter = true; //Debug("Max added"); }//End of If if (currentClose == minRoller && maxCounter == true) { ListOfMin.Add(_TradeBar_window[i]); maxCounter = false; //Debug("Min added"); }// End of If - can only be an odd number of min and max total if there is an extra max // if(i == _TradeBar_window.Count - ForwardLookingPeriod -1){ Debug("End of loop reached");} } // end of For Loop if ( ((ListOfMax.Count + ListOfMin.Count) % 2) == 0 ) { //I.e. it is even so you have as many //Mins as Max's.... // Debug("Equal min and max number"); FallAmount = ListOfMax.Average(r=>r.Close) - ListOfMin.Average(r=>r.Close); //It is a positive number //Calculate the average % fall List<decimal> PercentageList = new List<decimal>(); for (var i = 0; i < ListOfMax.Count; i ++){ decimal PctFall = 1 - (ListOfMin[i].Close/ListOfMax[i].Close); PercentageList.Add(PctFall); } AverageFallPct = PercentageList.Average(r=>r); //Positive % fall i.e. it is a positive number e.g. 10% RiseAmount = ((ListOfMax.Sum(r=>r.Close) - ListOfMax[1].Close) - (ListOfMin.Sum(r=>r.Close) - ListOfMin[ListOfMin.Count-1].Close))/ListOfMax.Count; List<decimal> PercentageListRise = new List<decimal>(); for (var i = 0; i < ListOfMax.Count -1 ; i ++) { decimal PctRise = (ListOfMax[i+1].Close / ListOfMin[i].Close) - 1; PercentageListRise.Add(PctRise); } AverageRisePct = PercentageListRise.Average(r=>r); } else { // Debug("Unequal min and max number"); decimal MaxTotals = ListOfMax.Sum(r=>r.Close) - ListOfMax[ListOfMax.Count-1].Close; decimal MinTotals = ListOfMin.Sum(r=>r.Close); FallAmount = ((MaxTotals - MinTotals) / ListOfMax.Count); List<decimal> PercentageList = new List<decimal>(); for (var i = 0; i < ListOfMax.Count -1; i ++){ decimal PctFall = 1 - (ListOfMin[i].Close/ListOfMax[i].Close); PercentageList.Add(PctFall); } AverageFallPct = PercentageList.Average(r=>r); RiseAmount = ((ListOfMax.Sum(r=>r.Close) - ListOfMax[1].Close) - (ListOfMin.Sum(r=>r.Close) ))/ListOfMax.Count; List<decimal> PercentageListRise = new List<decimal>(); for (var i = 0; i < ListOfMax.Count -1 ; i ++) { decimal PctRise = (ListOfMax[i+1].Close / ListOfMin[i].Close) - 1; PercentageListRise.Add(PctRise); } AverageRisePct = PercentageListRise.Average(r=>r); } // Debug("Finished calculating indicators"); // Debug("The first max is: " + ListOfMax.First().Close); // Debug("The first min is: " + ListOfMin.First().Close); //PRINT INDICATORS if(timeRoller == 100){ // Debug("The average fall %% is: " +AverageFallPct); // Debug("The average rise %% is: " +AverageRisePct); } if(timeRoller ==527){ Debug("The number of mins we have is: " + ListOfMin.Count); Debug("The number of max we have is: " + ListOfMax.Count); Debug("The delta PCT is: "+ deltaPCT ); if(deltaPCT == 0 ) { Debug("purchase close is: " + PurchaseClose); Debug("relevant close is: " + RelevantClose); }} //DEFINE THE PURCHASE BEHAVIOUR if(timeRoller == 97){ Debug("The last date is: " + _TradeBar_window.Last().Time); Debug("The first date is: " + _TradeBar_window.First().Time); Debug("The last price is: " + _TradeBar_window.Last().Close); Debug("The first price is: " + _TradeBar_window.First().Close); Debug("The purchase close is: " + PurchaseClose); } if ( !Portfolio.HoldStock) { List<TradeBar> subList2 = _TradeBar_window.ToList().GetRange( _TradeBar_window.Count - ForwardLookingPeriod,ForwardLookingPeriod); RelevantClose = subList2.Max(r => r.Close); PurchaseClose = _TradeBar_window.Last().Close; deltaPCT = 1-(PurchaseClose / RelevantClose) ; //A positive number //Debug ("The delta PCt is: " + deltaPCT); if (deltaPCT > AverageFallPct*FallFactor) { //If you are at a min, then purchase // Debug("Purchasing at price " + PurchaseClose + "Reference price of" + RelevantClose + " and delta pct of " + deltaPCT); var quantity = (int)Math.Floor(Portfolio.Cash / PurchaseClose); CurrentOrder = Order(_symbol, quantity); ProfitTarget = LimitOrder(_symbol,-quantity, PurchaseClose*(1+ AverageRisePct*RiseFactor)); StopLossPct = AverageFallPct*StopLossPctAdjuster; } } else { ProfitTarget.Update( new UpdateOrderFields { LimitPrice = PurchaseClose*(1+AverageRisePct*RiseFactor) } ); // StopLossPct = AverageFallPct*StopLossPctAdjuster; // StopLoss.Update( new UpdateOrderFields { // StopPrice = PurchaseClose*(1-StopLossPct) // // } ); }; }//END OF FUNCTION DEFINITION //Define the plotting of indicators public override void OnEndOfDay(){ Plot("BB", "AvgFallPct", AverageFallPct); Plot("BB", "AvgRisePct", AverageRisePct); Plot("BB", "deltaPct", deltaPCT); Plot("MaxAndMin","max",ListOfMax.Count); Plot("MaxAndMin","Min",ListOfMin.Count); Plot("Time","time",timeRoller); Plot("Purchase Prices","Purchase Price", PurchaseClose); Plot("Purchase Prices","Last TradeBar", _TradeBar_window.Last().Close); } }//END OF BASIC TEMPLATE ALGORITHM }// END OF NAMESPACE