namespace QuantConnect.Algorithm.CSharp
{
/*
Test Forex algo that uses CCI to trigger trades. Future version will use fraction of ATI to determine StopLoss (if I can figure that out)
*/
public class CCIwithATRSL : QCAlgorithm
{
// define private variables
private string pair = "EURUSD";
private int startCash = 1000;
private int minPosition = 400;
private int lotBuy = 10000;
private int lotSell = -10000;
int rollingWinCCI = 10;
int rollingWinATR = 10;
int periodCCI = 20;
int periodATR = 14;
// define public variables. Unsure which to make private or public
public decimal price;
public decimal holding;
public decimal usd;
// define other variables
Resolution res = Resolution.Hour;
CommodityChannelIndex _cci;
AverageTrueRange _atr;
RollingWindow<IndicatorDataPoint> _cciWin;
RollingWindow<IndicatorDataPoint> _atrWin;
// INITIALIZE BLOCK
public override void Initialize()
{
SetTimeZone(TimeZones.Utc);
SetStartDate(2018, 1, 1); //Set Start Date
SetEndDate(2018, 7, 1); //Set End Date
SetCash(startCash); //Set Strategy Cash
// Identify currency pair and Market
AddForex(pair, res, Market.Oanda);
SetBrokerageModel(BrokerageName.OandaBrokerage);
// Initialize Indicators
_cci = CCI(pair, periodCCI, MovingAverageType.Exponential, res);
_atr = ATR(pair, periodATR, MovingAverageType.Exponential, res);
// Initialize and update RollingWindow
_cci.Updated += (sender, updated) => _cciWin.Add(updated);
_cciWin = new RollingWindow<IndicatorDataPoint>(rollingWinCCI);
}
public void OnData(QuoteBars data)
{
// price = data[pair].Price;
// usd = Portfolio.CashBook["USD"].Amount;
// holding = Portfolio[pair].Quantity;
if(!_cci.IsReady) {return;}
// When to close order
if(Portfolio.Invested); // && usd > minPosition)
{
// Liquidate if price crosses the CCI midpoint
if( _cciWin[1] >= 0 && _cciWin[0] < 0 || _cciWin[1] <= 0 && _cciWin[0] > 0)
{
Liquidate(pair, tag: "CLOSE: 0 Reached");
}
// Liquidate in case price doesn't reach the CCI midpoint
else if( _cciWin[1] > -100 && _cciWin[0] < -100)
{
Liquidate(pair, tag: "SELL CLOSE: -100 StopLoss");
}
// Liquidate in case price doesn't reach the CCI midpoint
else if( _cciWin[1] < 100 && _cciWin[0] > 100)
{
Liquidate(pair, tag: "BUY CLOSE: 100 StopLoss");
}
}
if(!Portfolio.Invested)
{
// Buy when the price crosses from below -100 to above -100
if( _cciWin[1] < -100 && _cciWin[0] > -100)
{
MarketOrder(pair, lotBuy, tag: "LONG ORDER: -100 Reversal");
}
// Sell when the priced crosses from above 100 to below 100
if( _cciWin[1] > 100 && _cciWin[0] < 100)
{
MarketOrder(pair, lotSell, tag: "SELL ORDER: 100 Reversal");
}
}
// Plot CCI to verify triggers are working
Plot("CCI", _cci);
}
// Unalbe to run during algo. Would like to move this to a different file and have it run as needed.
// public void OnData(DailyFx calendar)
// {
// // Trigger for order
// if(calendar.Importance != FxDailyImportance.High) // return;
// {
// if(Portfolio.Invested)
// {
// Liquidate(pair, tag: "Exonomic Event");
// }
// }
// }
}
}