Overall Statistics
using QuantConnect.Securities.Crypto;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
namespace QuantConnect.Algorithm.CSharp
{
    public class VentralTransdimensionalChamber : QCAlgorithm
    {
    	private Dictionary<Symbol, SymbolData> _dataBySymbol;

        // VARIABELEN DECLAREREN

        private decimal _weight = .0065m;			///Percentage van portfolio dat je wilt investeren // % of portfolio for every trade.
        private decimal _startingCash = 1.0m;
        
        private decimal _targetPercent = .01m;   //1% winst dan verkopen // Sell when 1% profit
        private decimal _stopPercent = .10m;     //verkopen bij de 10% verlies / Sell when loss is 10%

        
        decimal _maxPosition = .05m;                  // Max USD invested
        decimal _minPosition = .07m;                  // min USD needed to invest.
        public decimal _btc;
        public string valuta = "BTC";
        
        public decimal _holding; 
       
    	Resolution res = Resolution.Minute;

        //MACD variabelen
        public int RollingWindow = 5;

        RollingWindow<IndicatorDataPoint> _macdWin;
        MovingAverageConvergenceDivergence _macd;
        
        public int fast = 12;		
        public int slow = 26;		
        public int sig = 9;	
        decimal macd_change;

        //INITIALIZE BLOCK
        public override void Initialize()
        {
            SetStartDate(2017, 1, 1); 
            SetEndDate(2018, 1, 1);
			SetAccountCurrency(valuta);
            SetCash(valuta, _startingCash);
			//SetCash("BTC", 1.0m);
            SetBrokerageModel(BrokerageName.Bitfinex, AccountType.Cash);

    		_dataBySymbol = new Dictionary<Symbol, SymbolData>();
    		
            foreach (var ticker in new [] {"ETHBTC", "XRPBTC","NEOBTC", "OMGBTC","XMRBTC"})  //"XRPBTC","ETHBTC","DSHBTC", "VETBTC", "NEOBTC", "OMGBTC"
            {																		
            																		
            
            	var crypto = AddCrypto(ticker, res);
            	_dataBySymbol.Add(crypto.Symbol, new SymbolData(this, crypto));
            }
            SetWarmUp(3 * SymbolData.MinutesOfTrading, res);
            //SetWarmUp(SymbolData.MinutesOfTrading, Resolution.Minute);
        }
        
        // ON DATA BLOCK (waar bestanden/data binnenkomt in het programma)
        public override void OnData(Slice data)
        {
        	if (IsWarmingUp) return;
        	
        	foreach (var kvp in _dataBySymbol)
        	{
        		var symbolData = kvp.Value;
        		if (!symbolData.IsReady)
        		{
        		continue;
        		}

        		var symbol = kvp.Key;
        		if (!data.Bars.ContainsKey(symbol))
        		{
        			continue;
        		}
        		
        		var price = data[symbol].Price;
        		
        		var invested = Portfolio[symbol].Invested;
            	_btc = Portfolio.CashBook[valuta].Amount;

        		if (!invested && _btc > _minPosition)
        		{

        			if (symbolData.MacdChange >= 0)
        			{
        				//JUST TAKE 1% PROFIT OR 10% LOSS
						
						var qnty = CalculateOrderQuantity(symbol, Portfolio.CashBook["BTC"].ValueInAccountCurrency/ _weight);
        				//Placing order.
        				MarketOrder(symbol, qnty); 
        				
        				Debug($"Aankoop: {symbol} {data[symbol].Price}");   // Als het order gemaakt is word dit bevestigd door de debug
                    	//Log($"prijs {price} - Aankoopbedrag {btcusd}");
            			Notify.Email("david.wittevronghel@gmail.com", "TradeAlert",$"Gekocht {symbol} op {data[symbol].Price}");
            			
						symbolData.TargetPrice = price * (1 + _targetPercent);   //Bepalen welke verkoopprijs bij winst (huidige prijs + 1%) // determine wich selling price at profit
						symbolData.StopPrice = price * (1 - _stopPercent);       //bepalen welke verkoopprijs bij verlies (huidige -10 %)     // determine wich selling price at loss.

        			}
        		}

                if (invested)
                {
                	
                	if (price >= symbolData.TargetPrice)
                	{
                    	MarketOrder(symbol, symbolData.Holding);
                    	Log($"1. Winst 1% verkoopprijs {symbol}{price}");
                    	Notify.Email("david.wittevronghel@gmail.com", "TradeAlert",$"+1% WINST VERKOCHT {symbol} op {data[symbol].Price}");
                	}

                	if (price < symbolData.StopPrice)
                	{
                    	MarketOrder(symbol, symbolData.Holding);
                    	Log($"2. Verlies 10% verkoopprijs {symbol}{price}");
                    	Notify.Email("david.wittevronghel@gmail.com", "TradeAlert",$"-10% VERLIES VERKOCHT {symbol} op {data[symbol].Price}");
                	}	
                }
        	}
        }
    }

    public class SymbolData
    {
    	private Cash _cash;
    	
		public static int MinutesOfTrading = 1140;
		
		public decimal StopPrice;
		public decimal TargetPrice;
        
        public int fast = 12;		
        public int slow = 26;		
        public int sig = 9;	
		public decimal Holding => _cash.Amount;
		
		
		public MovingAverageConvergenceDivergence _macd {get; private set;}
		public RollingWindow<IndicatorDataPoint> _macdWin {get; private set;}
		
		
		public bool IsReady => _macdWin.IsReady && _macd.IsReady;
		
		public decimal MacdChange =>(_macdWin[0] - _macdWin[_macdWin.Count - 1]);
	   	public SymbolData(QCAlgorithm algorithm, Crypto crypto)
    	{
    		Resolution res = Resolution.Minute;
    		_cash = algorithm.Portfolio.CashBook[crypto.BaseCurrencySymbol];
            _macd = algorithm.MACD(crypto.Symbol, fast, slow, sig, MovingAverageType.Exponential,res);
			_macdWin = new RollingWindow<IndicatorDataPoint>(5);
    		_macd.Signal.Updated +=(sender, updated) => _macdWin.Add(updated);

    	}
    }
}