| Overall Statistics |
|
Total Trades 76 Average Win 1.79% Average Loss -0.29% Compounding Annual Return 3.559% Drawdown 2.600% Expectancy 0.305 Net Profit 3.282% Sharpe Ratio 0.592 Loss Rate 82% Win Rate 18% Profit-Loss Ratio 6.09 Alpha 0.03 Beta -0.038 Annual Standard Deviation 0.042 Annual Variance 0.002 Information Ratio -1.412 Tracking Error 0.073 Treynor Ratio -0.669 Total Fees $0.00 |
namespace QuantConnect
{
public class BasicTemplateAlgorithm : QCAlgorithm
{
//Update identifying logic, 50 instead of 20? Make sure its pulling a leg start level from before the extreme
//Possibly switch from fractal to short DCH channel
public string symbol = "EURUSD";
RollingWindow<decimal> High;
RollingWindow<decimal> Low;
RollingWindow<decimal> SLost;
RollingWindow<decimal> RGained;
RollingWindow<decimal> LSUp;
RollingWindow<decimal> LSDn;
DateTime LUT;
DateTime LDT;
public decimal LongLevel;
public decimal ShortLevel;
RollingWindow<decimal>Price;
RollingWindow<decimal>EntryPrice;
public decimal DownLvl;
public decimal UpLvl;
public decimal EnterPrice;
public decimal LongStop;
public decimal LongStop1;
public decimal ShortStop;
DonchianChannel Extremum;
public bool Entered;
public bool Triggered;
OrderTicket limitOrderTicket;
OrderTicket targetOrderTicket;
OrderTicket stopOrderTicket;
QuoteBar Hourly;
public decimal RR;
public override void Initialize()
{
SetStartDate(2017, 1, 1);
SetEndDate(DateTime.Now);
SetCash(10000);
AddForex(symbol, Resolution.Minute);
High = new RollingWindow<decimal>(20);
Low = new RollingWindow<decimal>(20);
SLost = new RollingWindow<decimal>(5);
RGained = new RollingWindow<decimal>(5);
LSUp = new RollingWindow<decimal>(5);
LSDn = new RollingWindow<decimal>(5);
Price = new RollingWindow<decimal>(5);
EntryPrice = new RollingWindow<decimal>(5);
Extremum = DCH(symbol, 20, Resolution.Hour);
Entered = false;
var hourlyConsolidator = new QuoteBarConsolidator(TimeSpan.FromMinutes(60));
hourlyConsolidator.DataConsolidated += OnDataDaily;
SubscriptionManager.AddConsolidator(symbol, hourlyConsolidator);
}
private void OnDataDaily(object sender, QuoteBar consolidated)
{
Hourly = consolidated;
High.Add(Hourly.High);
Low.Add(Hourly.Low);
Price.Add(Hourly.Price);
if(!(High.IsReady || Low.IsReady || Price.IsReady)) return;
var BWFH = High[0] < High[1] && High[1] < High[2] && High[2] > High[3] && High[3] > High[4];
var BWFL = Low[0] > Low[1] && Low[1] > Low[2] && Low[2] < Low[3] && Low[3] < Low[4];
if (BWFH)
{
SLost.Add(High[2]);
}
if (BWFL)
{
RGained.Add(Low[2]);
}
if(!(SLost.IsReady || RGained.IsReady)) return;
var lu = Low[10]==Extremum.LowerBand && Price[0]>RGained[1];
var ld = High[10]==Extremum.UpperBand && Price[0]<SLost[1];
if (lu)
{
if (RGained[0]==Low[10])
{
LSUp.Add(RGained[1]);
}
if (RGained[0]!=Low[10])
{
LSUp.Add(RGained[0]);
}
LUT = Time;
LongStop1 = Extremum.LowerBand;
}
if (!LSUp.IsReady) return;
if (ld)
{
if (SLost[0]==High[10])
{
LSDn.Add(SLost[1]);
}
if (SLost[0]!=High[10])
{
LSDn.Add(SLost[0]);
}
LDT = Time;
ShortStop = Extremum.UpperBand;
}
if (!LSDn.IsReady) return;
if (LDT-LUT > TimeSpan.FromMinutes(0))
{
LongLevel = LSUp[0];
}
if (LUT-LDT > TimeSpan.FromMinutes(0))
{
ShortLevel = LSDn[0];
}
var TargetDistance = ShortLevel-LongLevel;
var StopDistance = LongLevel-LongStop1;
RR = TargetDistance/StopDistance;
}
public void OnData(QuoteBars data)
{
if(!(High.IsReady || Low.IsReady || Price.IsReady)) return;
if(!(SLost.IsReady || RGained.IsReady)) return;
if (!LSUp.IsReady) return;
if (!LSDn.IsReady) return;
var qty = 30000;
if (!Portfolio[symbol].IsLong && Entered==false && RR>1)
{
EntryPrice.Add(LongLevel);
if (!EntryPrice.IsReady) return;
if (!(EntryPrice[1]>0)) return;
if (EntryPrice[0]!=EntryPrice[1])
{
limitOrderTicket = LimitOrder(symbol, qty, LongLevel, "Long");
DownLvl = ShortLevel;
LongStop = LongStop1;
Entered = true;
Triggered = false;
EnterPrice = LongLevel;
}
}
if (EnterPrice!=LongLevel && !Portfolio[symbol].IsLong)
{
if (Entered==true)
{
limitOrderTicket.Cancel();
Entered = false;
}
}
if (Portfolio[symbol].IsLong && Triggered==false)
{
targetOrderTicket = LimitOrder(symbol, -Portfolio[symbol].Quantity, DownLvl, "Hit Leg Start Down at " + DownLvl);
stopOrderTicket = StopMarketOrder(symbol, -Portfolio[symbol].Quantity, LongStop,"Stop Out Long at " + LongStop);
Triggered = true;
}
if (!Portfolio[symbol].IsLong && Triggered==true)
{
if (targetOrderTicket.Status.IsOpen())
{
targetOrderTicket.Cancel();
}
Entered = false;
}
if (Portfolio[symbol].IsShort)
{
SetHoldings(symbol, 0, true, "Imbalance");
}
}
}
}