Overall Statistics
Total Trades
227
Average Win
2.13%
Average Loss
-1.07%
Compounding Annual Return
15.806%
Drawdown
11.100%
Expectancy
0.504
Net Profit
77.127%
Sharpe Ratio
1.072
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
1.98
Alpha
0.105
Beta
0.031
Annual Standard Deviation
0.1
Annual Variance
0.01
Information Ratio
0.289
Tracking Error
0.14
Treynor Ratio
3.455
Total Fees
$0.00
namespace QuantConnect.Algorithm.CSharp
{
    public class MyFirstAlgorithm : QCAlgorithm
    {
        // string _clSymbol = "APPL";
        string _clSymbol = "XAUUSD";
        // string _clSymbol = "EURUSD";
        int _quantity = 0;
        
        BollingerBands _bbStrict;
        SimpleMovingAverage _sma;
        RelativeStrengthIndex _rsi, _prevRsi, _orderRsi;

        decimal _price;
        decimal _openPrice;
        decimal _highPrice;
        decimal _highestPrice;
        decimal _lowPrice;
        decimal _lowestPrice;
		decimal _lastPricePrevDay;
		decimal _lastOpenPricePrevDay;
		decimal _highestPricePrevDay;
		decimal _loewestPricePrevDay;
		OrderTicket _limitOrder;
		bool _newDay;
		bool _newOrder = false;

		decimal _awayUp25FromMiddleBand;
		decimal _awayUp75FromMiddleBand;
		decimal _awayDown25FromMiddleBand;
		decimal _awayDown75FromMiddleBand;
		decimal _entryPrice;
		decimal _tpPriceLong;
		decimal _slPriceLong;
		decimal _tpPriceShort;
		decimal _slPriceShort;
		bool _ignoreStartDay = true;
		bool _tryAgainstTrend = false;
		bool _onlyAgainstTrend = false;
		bool _entryPriceUpdated;
		
        public override void Initialize()
        {
			// Code Automatically Generated  
			

			// Add Security to trade
			AddCfd(_clSymbol, Resolution.Minute, Market.Oanda);
			// AddForex(_clSymbol, Resolution.Second);
			// AddSecurity(SecurityType.Equity, _clSymbol, Resolution.Second);

            SetStartDate(2014, 01, 01);  // Set Start Date
            SetEndDate(2017, 11, 21);    // Set End Date
            SetCash(100000);              // Set Strategy Cash
            // SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin);
            
            decimal _kBBStrict = Convert.ToDecimal(2); // standard deviations
            
            //Set up Indicators:
            _bbStrict = BB(_clSymbol, 3, _kBBStrict, MovingAverageType.Simple, Resolution.Daily);
            _sma = SMA(_clSymbol, 7, Resolution.Minute);
            /* retrieve:
             _bb.StandardDeviation, _bb.IsReady,
             _bb.MiddleBand, _bb.UpUpperBand, _bb.LowerBand
             */
            
            _rsi = RSI(_clSymbol, 7,  MovingAverageType.Simple, Resolution.Daily);

        }
       
        public void OnData(QuoteBars data)
        {
        	if (_ignoreStartDay) return;
        	
        	if (_newDay){
	        	_lastOpenPricePrevDay = _openPrice;
        		_newDay = false;
        	}
        	
            _price = data[_clSymbol].Close;
            _openPrice = data[_clSymbol].Open;
            _highPrice = data[_clSymbol].High;
            _lowPrice = data[_clSymbol].Low;
            
        	if (_lowPrice<_lowestPrice) { _lowestPrice = _lowPrice; }
        	if (_highPrice>_highestPrice) { _highestPrice = _highPrice; }
        	
            if (!_bbStrict.IsReady || _bbStrict.MiddleBand<=_price*80/100) return;

			_awayUp25FromMiddleBand = _bbStrict.MiddleBand+((_bbStrict.UpperBand-_bbStrict.MiddleBand)/10);
			_awayUp75FromMiddleBand = _bbStrict.MiddleBand+((_bbStrict.UpperBand-_bbStrict.MiddleBand)/4*3);
			_awayDown25FromMiddleBand = _bbStrict.MiddleBand-((_bbStrict.MiddleBand-_bbStrict.LowerBand)/10);
			_awayDown75FromMiddleBand = _bbStrict.MiddleBand-((_bbStrict.MiddleBand-_bbStrict.LowerBand)/4*3);
			
            if (!_newOrder && !Portfolio.Invested)
            {
				_quantity = (int)Math.Floor(Portfolio.Cash/_price);
            	
            	if (_rsi>60 && _sma<_bbStrict.MiddleBand) {
             	
	            	if (!_onlyAgainstTrend && _price <= _bbStrict.MiddleBand &&  _price > _awayDown25FromMiddleBand) {
		                _limitOrder = LimitOrder(_clSymbol, _quantity, _price);
		            	_newOrder = true;
		            	_orderRsi = _rsi;
		            	
		            	_entryPrice = _price;
		            	_entryPriceUpdated  =false;
		             	_tpPriceLong = _awayUp75FromMiddleBand;
		            	_slPriceLong = _bbStrict.LowerBand;
	            	} else if ((_onlyAgainstTrend || _tryAgainstTrend) && _price >= _bbStrict.UpperBand){
		                _limitOrder = StopMarketOrder(_clSymbol, -_quantity, _price);
		            	_newOrder = true;
		            	_orderRsi = _rsi;

		            	_entryPrice = _price;
		            	_entryPriceUpdated  =false;
		             	_tpPriceShort = _awayUp25FromMiddleBand;
		            	_slPriceShort = _bbStrict.UpperBand + ((_bbStrict.UpperBand-_awayUp25FromMiddleBand)/2);
	            	}
	            	
            	} else if (_rsi<45 && _sma>_bbStrict.MiddleBand){
             	
	            	if (!_onlyAgainstTrend && _price >= _bbStrict.MiddleBand &&  _price < _awayUp25FromMiddleBand) {
		                _limitOrder = StopMarketOrder(_clSymbol, -_quantity, _price);
		            	_newOrder = true;
		            	_orderRsi = _rsi;

		            	_entryPrice = _price;
		            	_entryPriceUpdated  =false;
		             	_tpPriceShort = _awayDown75FromMiddleBand;
		            	_slPriceShort = _bbStrict.UpperBand;
	            	} else if ((_onlyAgainstTrend || _tryAgainstTrend) && _price <= _bbStrict.LowerBand){
		                _limitOrder = LimitOrder(_clSymbol, _quantity, _price);
		            	_newOrder = true;
		            	_orderRsi = _rsi;

		            	_entryPrice = _price;
		            	_entryPriceUpdated  =false;
		             	_tpPriceLong = _awayDown25FromMiddleBand;
		            	_slPriceLong = _bbStrict.LowerBand - ((_awayDown25FromMiddleBand - _bbStrict.LowerBand)/2);
	            	}
            		
            	}
            }
            
            bool chgDirectionCond = (_rsi<50 && _orderRsi>50) || (_rsi>50  && _orderRsi<50);
            // || _price >= _tpPriceLong || _price <= _slPriceLong
            bool conditionLong = (chgDirectionCond || (_entryPriceUpdated && _price <= _entryPrice));
            //  || _price <= _tpPriceShort || _price >= _slPriceShort
            bool conditionShort = (chgDirectionCond || (_entryPriceUpdated && _price >= _entryPrice));

            if (Portfolio[_clSymbol].IsLong){
            	// we update entry price when 1% increase is made to lock profits in case of price back drop
            	if (_price > Decimal.Multiply(_entryPrice, Convert.ToDecimal(1.02))){
            		_entryPrice = _price;
            		// _entryPriceUpdated = true;
            	}
            	
            	if (conditionLong) {
	            Liquidate(_clSymbol);
	            // _newOrder = false;
            	}
            } else if (Portfolio[_clSymbol].IsShort){
            	// we update entry price when 1% decrease is made to lock profits in case of price changes chgDirectionCond
            	if (_price < Decimal.Multiply(_entryPrice, Convert.ToDecimal(0.98))){
            		_entryPrice = _price;
            		// _entryPriceUpdated = true;
            	}

            	if (conditionShort) {
	            Liquidate(_clSymbol);
	            // _newOrder = false;
            	}
            }
            
           
        }
        

        // Fire plotting events once per day:
        public override void OnEndOfDay() 
        {
        	
            if (Portfolio[_clSymbol].IsLong && _orderRsi<50){
	            Liquidate(_clSymbol);
	            _newOrder = false;
            } else if (Portfolio[_clSymbol].IsShort && _orderRsi>50){
	            Liquidate(_clSymbol);
	            _newOrder = false;
            }
         	
			if (!Portfolio[_clSymbol].Invested){
				Liquidate(_clSymbol);
				_newOrder = false;
			}  
		            	
        	_lastPricePrevDay = _price;
        	
        	_highestPricePrevDay = _highestPrice;
        	_loewestPricePrevDay = _lowestPrice;

        	_prevRsi = _rsi;
        	
        	_newDay = true;
        	
        	if (_ignoreStartDay) { _ignoreStartDay=false; return; }

            Plot("BB", "Price", _price);
            Plot("BB", _bbStrict.UpperBand, _bbStrict.MiddleBand, _bbStrict.LowerBand);
            Plot("RSI", _rsi);
        }
    }
}