| Overall Statistics |
|
Total Trades 1 Average Win 0% Average Loss 0% Compounding Annual Return 1.970% Drawdown 11.400% Expectancy 0 Net Profit 10.604% Sharpe Ratio 0.301 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0.105 Beta -4.129 Annual Standard Deviation 0.074 Annual Variance 0.005 Information Ratio 0.03 Tracking Error 0.074 Treynor Ratio -0.005 Total Fees $1.00 |
namespace QuantConnect.Algorithm.CSharp
{
public class buythedip : QCAlgorithm
{
//Member variables
private static Symbol _google = QuantConnect.Symbol.Create("GOOGL", SecurityType.Equity, Market.USA);
private int ForwardLookingPeriod = 25;
private int BackwardLookingPeriod = 2*365;
private int minutesToExecute = 10;
private RollingWindow<TradeBar> _TradeBar_window;
private Boolean maxCounter = false;
private List <TradeBar> ListOfMax = new List<TradeBar>();
private List <TradeBar> ListOfMin = new List<TradeBar>();
public Boolean cash;
public Boolean buyTrigger;
public Boolean sellTrigger;
private decimal RelevantClose;
private decimal PurchaseClose;
private OrderTicket CurrentOrder;
private OrderTicket StopLoss;
private OrderTicket ProfitTarget;
private decimal PurchasePrice;
public override void Initialize()
{
SetStartDate(2014,1,1); //Set Start Date
SetEndDate(DateTime.Now.Date.AddDays(-1));
SetCash(30000);
AddEquity(_google, Resolution.Daily);
//START----------------------------------------------------------
//END -----------------------------------------------------------------------------
SetWarmUp(365);
Debug("Set warm up");
Schedule.On( DateRules.EveryDay(_google),
TimeRules.AfterMarketOpen(_google,minutesToExecute), //Execute the function at the start of the day
// x minutes in....
EveryDayOnMarketOpen );
}
public void EveryDayOnMarketOpen(){ //Define the bad boy
if (IsWarmingUp) {return;}
//Sanity Check; are there open orders?
//Initialise the different components of your indicator
_TradeBar_window = new RollingWindow<TradeBar>(BackwardLookingPeriod);
//Generates an array of data which you can add to each period.
IEnumerable<TradeBar> slices = History(_google, BackwardLookingPeriod);
//Generates what is essentially an iterator, where if it is called, you can
//iterate over all the slices inside it (in this case Trade Bars)
Debug("S1");
// foreach (TradeBar bar in slices) {
// _close_window.Add(bar.Close);}
foreach (TradeBar bar in slices) {
_TradeBar_window.Add(bar);
}
for ( var i = ForwardLookingPeriod ; i<_TradeBar_window.Size - ForwardLookingPeriod ; i++ ) {
decimal currentClose = _TradeBar_window[i].Close;
decimal maxRoller;
decimal minRoller;
List<TradeBar> subList = _TradeBar_window.ToList().GetRange( i - ForwardLookingPeriod,ForwardLookingPeriod*2);
maxRoller = subList.Max(r => r.Close);
minRoller = subList.Min(r => r.Close);
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.Size - ForwardLookingPeriod -1){ Debug("End of loop reached");}
} // end of For Loop
//CALCULATE INDICATORS FROM LIST OF MAX AND LIST OF MIN
//1. Average Fall amount
//2. Average fall time - not for now
//3. Average Rise Amount
//4. Average Rise time - not for now
decimal FallAmount;
decimal RiseAmount;
decimal AverageFallPct;
decimal AverageRisePct;
// foreach (var item in ListOfMax) {
// Debug(item.ToString());
// }
// foreach (var item in ListOfMin) {
// Debug(item.ToString());
// }
// Debug(ListOfMax.Count + ListOfMin.Count);
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("Calculations of indicators complete. Indicators are as follows:");
// Debug("Average Rise amount: " + RiseAmount);
// Debug("Average Fall amount: " + FallAmount);
// Debug("Average Rise %: " + AverageRisePct);
// Debug("Average Fall %: " + AverageFallPct);
//Code to execute orders
//Update orders
//GetPrice from relevant period ago
if ( !Portfolio.HoldStock) {
//Calculate if we should buy
RelevantClose = _TradeBar_window[ForwardLookingPeriod].Close;
PurchaseClose = _TradeBar_window.First().Close;
var deltaPCT = 1-(PurchaseClose / RelevantClose) ; //A positive number
if (deltaPCT > AverageFallPct) { //If you are at a min, then purchase
var quantity = (int)Math.Floor(Portfolio.Cash / PurchaseClose);
CurrentOrder = Order(_google, quantity);
ProfitTarget = LimitOrder(_google,-quantity, PurchaseClose*(1+ AverageRisePct));
}
} else {
ProfitTarget.Update( new UpdateOrderFields {
LimitPrice = PurchaseClose*(1+AverageRisePct)
} );
};
}//End of Function being called
}//End of BuyTheDip
}// End of NameSpace