Overall Statistics |
Total Trades 380 Average Win 2.48% Average Loss -3.40% Compounding Annual Return -95.244% Drawdown 78.700% Expectancy -0.207 Net Profit -78.100% Sharpe Ratio -3.068 Loss Rate 54% Win Rate 46% Profit-Loss Ratio 0.73 Alpha -4.36 Beta 137.698 Annual Standard Deviation 0.703 Annual Variance 0.495 Information Ratio -3.09 Tracking Error 0.703 Treynor Ratio -0.016 Total Fees $0.00 |
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"); // } // } // } } }