Overall Statistics
```using System;
using System.Collections;
using System.Collections.Generic;
using MathNet.Numerics.Statistics;
using MathNet.Numerics;
using System.Linq;

namespace QuantConnect {
//Returns the channel end values based on previous Trade bar
public class PolynomialRegression
{
private int _period;
public int period	{get{return _period;}}

private double _deviation;
private int _power;
private int _samples;

private decimal _oneStdDev;
public decimal oneStdDev	{get{return _oneStdDev;}}

private decimal _lastPredictedValue;
public decimal lastPredictedValue	{get{return _lastPredictedValue;}}

private decimal _slope;
public decimal slope	{get{return _slope;}}

private double[] _slopeCoefficients;
public double[] slopeCoefficients	{get{return _slopeCoefficients;}}

private decimal _upBand;
public decimal upBand {get{return _upBand;}}

private decimal _lowBand;
public decimal lowBand	{get{return _lowBand;}}

//Will check if the value from the indicator should be used or not

private List<double> _yBuffer;
public  List<double> yBuffer {get{return _yBuffer;}}

private List<double> _xBuffer;
public  List<double> xBuffer {get{return _xBuffer;}}

public PolynomialRegression (int period, double deviation, int power)
{
this._period = period;
this._deviation = deviation;
this._power = power;
this._samples = 0;
this._yBuffer = new List<double>();
this._xBuffer = new List<double>();
}

{
if (_samples<_period)
{
_slope = 1m;
_upBand = price;
_lowBand =price;
_samples++;
return;
}
else
{
_slopeCoefficients = Fit.Polynomial(_xBuffer.ToArray(), _yBuffer.ToArray(), _power);

double[] _errors = new double[_xBuffer.Count()];
double[] _modelledValues = new double[_yBuffer.Count()];
for (int _curCount = 0;_curCount<_xBuffer.Count();_curCount++)
{
//_modelledValues[_curCount] = Evaluate.Polynomial(_xBuffer[_curCount], _slopeCoefficients);
_modelledValues [_curCount] = _slopeCoefficients[0] + _slopeCoefficients[1]*_xBuffer[_curCount];
_errors[_curCount] = _modelledValues[_curCount] - _yBuffer[_curCount];
}

_oneStdDev = (decimal)ArrayStatistics.PopulationStandardDeviation(_errors);         				  //Standard Devation of errors  - Population uses N
_lastPredictedValue = (decimal)(_slopeCoefficients[0] + _slopeCoefficients[1]*_xBuffer.Last());        //Getting the last calculated value
_slope = (decimal)_slopeCoefficients[1];
_upBand = _lastPredictedValue + _oneStdDev*(decimal)_deviation;
_lowBand = _lastPredictedValue - _oneStdDev*(decimal)_deviation;

_yBuffer.Add((double)price);		//Preparing for next band value
_yBuffer.RemoveAt(0);
}
}

}

//public class Indicator
//{
//  ...or you can define whole new classes independent of the QuantConnect Context
//}

}```
```namespace QuantConnect {

//
//	Make sure to change "BasicTemplateAlgorithm" to your algorithm class name, and that all
//	files use "public partial class" if you want to split up your algorithm namespace into multiple files.
//

//public partial class BasicTemplateAlgorithm : QCAlgorithm, IAlgorithm
//{
//  Extension functions can go here...(ones that need access to QCAlgorithm functions e.g. Debug, Log etc.)
//}

//public class Indicator
//{
//  ...or you can define whole new classes independent of the QuantConnect Context
//}

class Utility{

/// <summary>
/// Returns the business date (EventDate  + post days) after accouning for weekends;  will not take into other exchange holidays
/// </summary>
/// <param name="EventDate"></param>
/// <param name="postDays"></param>
/// <returns></returns>
public static DateTime getPostBusinessDate(DateTime EventDate, int postDays)
{
DateTime applicableDate = EventDate;
//Checking if the event itself occurs on a weekend
if (postDays == 0)
while (applicableDate.DayOfWeek == DayOfWeek.Saturday || applicableDate.DayOfWeek == DayOfWeek.Sunday)

for (int tempCount = 0; tempCount < Math.Abs(postDays); tempCount++)
{
while (applicableDate.DayOfWeek == DayOfWeek.Saturday || applicableDate.DayOfWeek == DayOfWeek.Sunday)
}
return applicableDate;
}

public static List<DateTime> getDaysAroundEvent(List<DateTime> eventDates, int NbPreDays, int NbPostDays)
{
List<DateTime> _finalDates = new List<DateTime>();
foreach(DateTime eventDate in eventDates)
{
int count = -NbPreDays;
while(count<=NbPostDays)
{
count++;
}
}
return _finalDates;
}

}

}```
```using System;

namespace QuantConnect
{
// Create 2 channels, operate only during Europe time, Mean Reversion only

public partial class PolynomialRegressionDemo : QCAlgorithm
{

//string symbol = "EURUSD";
//	string symbol = "USDJPY";
//	string symbol = "AUDUSD";
string symbol = "EURCHF";
//	string symbol = "EURSEK";
//int europeStartHours = 3;	//NY Time
//int usStartHours =  6;
//int usEndHours = 15;

DateTime[] ECBDays = new DateTime[] { new DateTime(2015,1,22),new DateTime(2015,3,5),new DateTime(2015,4,15),new DateTime(2015,6,3),new DateTime(2015,7,16),new DateTime(2015,9,3),new DateTime(2015,10,22),new DateTime(2015,12,3),new DateTime(2016,1,21),new DateTime(2016,3,10),new DateTime(2016,4,21)};
DateTime[] FedDays = new DateTime[]{ new DateTime(2015,1,28),new DateTime(2015,3,18),new DateTime(2015,4,29),new DateTime(2015,6,17),new DateTime(2015,7,29),new DateTime(2015,9,17),new DateTime(2015,10,28),new DateTime(2015,12,16),new DateTime(2016,1,27),new DateTime(2016,3,16),new DateTime(2016,4,27)};
DateTime[] NFPDays = new DateTime[]{ new DateTime(2015,1,9),new DateTime(2015,2,6),new DateTime(2015,3,6),new DateTime(2015,4,3),new DateTime(2015,5,8),new DateTime(2015,6,5),new DateTime(2015,7,2),new DateTime(2015,8,7),new DateTime(2015,9,4),new DateTime(2015,10,2),new DateTime(2015,11,6),new DateTime(2015,12,4),new DateTime(2016,1,8),new DateTime(2016,2,5),new DateTime(2016,3,4),new DateTime(2016,4,1),new DateTime(2016,5,6),new DateTime(2016,6,3)};

bool _excludeNFP = true;
int _NbNFPPreDays = 4;
int _NbNFPPostDays = 1;

bool _excludeECB = true;
int _NbECBPreDays =2;
int _NbECBPostDays =1;

bool _excludeFed = true;
int _NbFEDPreDays = 0;
int _NbFEDPostDays = 1;

List <DateTime> _excludeDates;
DateTime _latestEventDate;

int _fastPeriod = 300;			//Period in minutes
int _slowPeriod = 1200;			//Period in minutes
double _fastNbDevBands = 2.0;	//Number of deviations (bands)
double _slowNbDevBands = 2;		//Number of deviations (band

int _notional = 100000;
double _leverage = 1;

private OrderTicket _orderCurrentOrder;
private OrderTicket _orderStopLoss;
private OrderTicket _orderProfitTarget;

decimal _fastHiBandPrev1, _fastLowBandPrev1;
decimal _prevClose, _entryPrice, _exitPrice;
decimal _stopPrice,_tpPrice;
decimal _NAV;

DateTime  _entryTime, _exitTime;		//Assumes only 1 trade at a time

//int NbData;
//int _NbOpenOrders = 0;

PolynomialRegression prSlow;
PolynomialRegression prFast;

//Initialize the data and resolution you require for your strategy:
public override void Initialize()
{
SetTimeZone("America/New_York");
SetStartDate(2016,1, 1);
SetEndDate(2016,5, 31);

_excludeDates = new List<DateTime>();
if(_excludeFed==true)
if(_excludeNFP==true)
if(_excludeECB==true)

if(_excludeDates.Count()==0)

_excludeDates = _excludeDates.Distinct().ToList();
_excludeDates.Sort();				//Contains list of all sorted events which are to be avoided

_latestEventDate = _excludeDates.ElementAt(0);

//prUpper time should be greater than prFast by at least 1 period
prSlow = new PolynomialRegression(_slowPeriod,_slowNbDevBands,1);
prFast = new PolynomialRegression(_fastPeriod,_fastNbDevBands,1);
//previous value of Fast channel
_fastHiBandPrev1=0;
_fastLowBandPrev1=0;
_prevClose=0;
//Cash allocation
SetCash(_notional/_leverage);					//_leverage = 1 =>No Leverage;
//NbData=0;

var history = History(symbol, _slowPeriod + 10);	//Buffer of 10 for the slow channel
{

}
}

//Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol.
{
decimal price = data[symbol].Close;
var holdings  = Portfolio[symbol].Quantity;

{
return;
}

//if (!Portfolio.HoldStock)
//Time Filters
/*if(Time.Hour>=europeStartHours && Time.Hour<usStartHours)
else

if(Time.Date> _latestEventDate && _latestEventDate == _excludeDates.Last())
else
{
if(Time.Date> _latestEventDate)
{	_latestEventDate = _excludeDates.ElementAt(_excludeDates.IndexOf(_latestEventDate)+1);
if(Time.Date == _latestEventDate)				//event dates move in days while data comes in minutes
}
else if(Time.Date == _latestEventDate)
else if(Time.Date < _latestEventDate)
}

if(Time.DayOfWeek == DayOfWeek.Sunday)

else

if(holdings==0)								//No position
{
//	if(price<prFast.lowBand  & _prevClose>_fastLowBandPrev1 & prFast.slope>0  & prSlow.slope>0 & isTradeTime==true)						//Fast channel line of Fast band is greater than price - buy
if(price<prFast.lowBand  & _prevClose>_fastLowBandPrev1 & prFast.slope>0   & isTradeTime==true)
{
_stopPrice = price - prFast.oneStdDev * 2.0m;
_tpPrice = price + prFast.oneStdDev *3.0m;
//	Debug("Placing Buy Mkt Order now..");
_orderCurrentOrder = Order(symbol, _notional);
//Debug("Purchased " +  symbol + " on " + Time.ToString() + " at Price: " + price.ToString("0.0000") + " SL: " + _stopPrice.ToString("0.0000") + " TP: " + _tpPrice.ToString("0.0000") );
_orderStopLoss = StopMarketOrder(symbol, -_notional, _stopPrice);
_orderProfitTarget = LimitOrder(symbol,-_notional, _tpPrice);
}
//	else if(price>prFast.upBand & _prevClose<_fastHiBandPrev1 & prFast.slope<0  & prSlow.slope<0 & isTradeTime==true)							//higher channel of Fast band is less than price - sell
else if(price>prFast.upBand & _prevClose<_fastHiBandPrev1 & prFast.slope<0   & isTradeTime==true)								//higher channel of Fast band is less than price - sell
{
_stopPrice = price + prFast.oneStdDev*2.0m;
_tpPrice = price - prFast.oneStdDev*3.0m;
_buyorsell = 'S'; _entryTime = Time; _entryPrice = price;			//Recording Trade data
//	Debug("Placing Sell Mkt Order now..");
_orderCurrentOrder = Order(symbol, -_notional);
//Debug("Sold " +  symbol + " on " + Time.ToString() + " at Price: " + price.ToString("0.0000") + " SL: " + _stopPrice.ToString("0.0000") + " TP: " + _tpPrice.ToString("0.0000"));
_orderStopLoss = StopMarketOrder(symbol, +_notional, _stopPrice);
_orderProfitTarget = LimitOrder(symbol,+_notional, _tpPrice);
}
}

_fastLowBandPrev1 = prFast.lowBand;
_fastHiBandPrev1 = prFast.upBand;
_prevClose = price;

//	Debug(i.ToString() + " Time " + Time.ToString() + "Price = " + price +  " loBand = " + prFast.lowBand + " upBand = " + prFast.upBand);
// Debug ("Last =" + PolynomialRegression._yBuffer.Last().ToString());
//Debug("Time = " + Time.ToString() + "Price = " + price.ToString("0.0000"));

/*	Plot("Custom","prUpper_upBand", prSlow.upBand);
Plot("Custom","prFast_upBand", prFast.upBand);
Plot("Custom","prFast_lowBand", prFast.lowBand);
Plot("Custom","prUpper_lowBand", prSlow.lowBand);
Plot("Custom",symbol, data[symbol].Close);
*/

}

// If the StopLoss or ProfitTarget is filled, cancel the other
// If you don't do this, then  the ProfitTarget or StopLoss order will remain outstanding
public override void OnOrderEvent(OrderEvent orderEvent)
{
// Ignore OrderEvents that are not closed
if (!orderEvent.Status.IsClosed())	{ return; }

// Defensive check
if (_orderProfitTarget == null || _orderStopLoss == null) {	return;}

//This is getting called recursively if an order is canceled
if(orderEvent.Status == OrderStatus.Canceled )
{
//	Debug("Canceled outstanding order");
return;
}

var filledOrderId = orderEvent.OrderId;

//	Debug("current order ID " +_orderCurrentOrder.OrderId + "Filled Order ID  = " + filledOrderId );
if(_orderCurrentOrder.OrderId +3 == filledOrderId)
{
//Debug("Market Order checked");
return;
}

// If the ProfitTarget order was filled, close the StopLoss order
if (_orderProfitTarget.OrderId == filledOrderId)
{
//	Debug("TP Order hit");
if(_orderStopLoss.Status != OrderStatus.Filled)
_orderStopLoss.Cancel();
else Liquidate();
}

// If the StopLoss order was filled, close the ProfitTarget
if (_orderStopLoss.OrderId == filledOrderId)
{
//	Debug("SL Order hit");
if(_orderProfitTarget.Status != OrderStatus.Filled)
_orderProfitTarget.Cancel();
else Liquidate();
}

_exitPrice = orderEvent.FillPrice; _exitTime = Time;
_NAV = Portfolio.TotalPortfolioValue;