| 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