Overall Statistics
Total Trades
302
Average Win
1.12%
Average Loss
-0.04%
Compounding Annual Return
33.038%
Drawdown
0.300%
Expectancy
26.974
Net Profit
358.464%
Sharpe Ratio
0.459
Probabilistic Sharpe Ratio
0.017%
Loss Rate
7%
Win Rate
93%
Profit-Loss Ratio
28.96
Alpha
0.545
Beta
0.049
Annual Standard Deviation
1.186
Annual Variance
1.407
Information Ratio
0.457
Tracking Error
1.188
Treynor Ratio
11.082
Total Fees
â‚¿0.08
Estimated Strategy Capacity
â‚¿0
Lowest Capacity Asset
LTCBTC E3
#region imports
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Globalization;
    using System.Drawing;
    using QuantConnect;
    using QuantConnect.Algorithm.Framework;
    using QuantConnect.Algorithm.Framework.Selection;
    using QuantConnect.Algorithm.Framework.Alphas;
    using QuantConnect.Algorithm.Framework.Portfolio;
    using QuantConnect.Algorithm.Framework.Execution;
    using QuantConnect.Algorithm.Framework.Risk;
    using QuantConnect.Parameters;
    using QuantConnect.Benchmarks;
    using QuantConnect.Brokerages;
    using QuantConnect.Util;
    using QuantConnect.Interfaces;
    using QuantConnect.Algorithm;
    using QuantConnect.Indicators;
    using QuantConnect.Data;
    using QuantConnect.Data.Consolidators;
    using QuantConnect.Data.Custom;
    using QuantConnect.DataSource;
    using QuantConnect.Data.Fundamental;
    using QuantConnect.Data.Market;
    using QuantConnect.Data.UniverseSelection;
    using QuantConnect.Notifications;
    using QuantConnect.Orders;
    using QuantConnect.Orders.Fees;
    using QuantConnect.Orders.Fills;
    using QuantConnect.Orders.Slippage;
    using QuantConnect.Scheduling;
    using QuantConnect.Securities;
    using QuantConnect.Securities.Equity;
    using QuantConnect.Securities.Future;
    using QuantConnect.Securities.Option;
    using QuantConnect.Securities.Forex;
	using QuantConnect.Securities.Crypto;
    using QuantConnect.Securities.Interfaces;
    using QuantConnect.Storage;
    using QuantConnect.Data.Custom.AlphaStreams;
    using QCAlgorithmFramework = QuantConnect.Algorithm.QCAlgorithm;
    using QCAlgorithmFrameworkBridge = QuantConnect.Algorithm.QCAlgorithm;
#endregion





namespace QuantConnect.Algorithm.CSharp
{
    public class VentralTransdimensionalChamber : QCAlgorithm
    {
    	 
    	//	Trading bot that trades with the highest and lowest exchange rate of the last 24 hours.
    	//	Buying determined bacause the factor, MACD and the current price.
    	
      
    	private Dictionary<Symbol, SymbolData> _dataBySymbol;

        // VARIABELEN DECLAREREN
			


        //private decimal _targetPercent = .008m;
        private decimal _targetPercent = .01m;							//Sell when 1% profit
        private decimal _stopPercent = .10m;    						//Sell when loss is 10%

		//TrailPercentage
        //private decimal _trailPercent = .07m;

        decimal _minPosition = .05m;                					// min BTC needed to invest.
        public decimal _btc;
        public string valuta = "BTC";
        
        public decimal _holding; 
        
        //ORDERSIZE
		private decimal usdAmount = 500.0m;								//size in USD we want to invest.
		private Symbol btcusd;
		
        private decimal _btcStijging = 0.5m;
      
    	Resolution res = Resolution.Minute;

        //MACD VARIABLES
        public int RollingWindow = 5;

        RollingWindow<IndicatorDataPoint> _macdWin;
        MovingAverageConvergenceDivergence _macd;
        MomentumPercent _momentumPercent;
        
		private decimal pipProfit;
        
        decimal macd_change;

		public decimal _VolumeMinimum = 1000000;

		//RSI Variabelen
		RelativeStrengthIndex _rsi;

		
		        
        //INITIALIZE BLOCK
        public override void Initialize()
        {
            SetStartDate(2017, 1, 1); 
            SetEndDate(2022, 5, 1);
            
			SetAccountCurrency(valuta);
            SetCash("BTC", 1);
            
            SetBrokerageModel(BrokerageName.Bitfinex, AccountType.Cash);
	        
	        btcusd = AddCrypto("BTCUSD", Resolution.Minute).Symbol;

            int MomentumPercentPeriod = 1440;	//1dag  = 1440, 2dagen = 2880, 3dagen = 4320, 4dagen = 5760, 5dagen = 7200, 6dagen = 8640, 7dagen = 10080, 8dagen = 11520, 9dagen = 12960, 10dagen = 14400
            _momentumPercent = MOMP("BTCUSD", MomentumPercentPeriod, Resolution.Minute);
            SetWarmUp(MomentumPercentPeriod, Resolution.Minute);
            

    		_dataBySymbol = new Dictionary<Symbol, SymbolData>();
    		
            foreach (var ticker in new [] {"ETHBTC", "LTCBTC","EOSBTC", "ADABTC"})        

			//, "DOTBTC", "LINKBTC", "SOLBTC", "MATICBTC", "XMRBTC", "UNIBTC", "VETBTC", "TRXBTC", "EGLDBTC", "AVAXBTC", "XTZBTC", "WAVESBTC", "FTMBTC"
			/*"ETHBTC", "ADABTC", "DOTBTC", "AXSBTC", "LINKBTC", "RUNEBTC", "SOLBTC", "MATICBTC", "XMRBTC", "UNIBTC", "ALICEBTC", "VETBTC", "TLMBTC",
			"COMPBTC", "SUSHIBTC", "FILBTC", "SANDBTC", "CAKEBTC", "CRVBTC", "NEOBTC", "XLMBTC", "FETBTC", "TRXBTC", "ATOMBTC",
			"RVNBTC", "KAVABTC", "SXPBTC", "STORJBTC", "NMRBTC", "1INCHBTC", "ETCBTC", "CHZBTC", "TFUELBTC", "ALGOBTC","AAVEBTC",
			"EGLDBTC", "ZILBTC", "AVAXBTC", "OMGBTC", "SNXBTC", "NANOBTC", "MANABTC", "KSMBTC", "ENJBTC", "NEARBTC", "XTZBTC", "IOTABTC", "DASHBTC", "HBARBTC", "FTTBTC",
			"WAVESBTC", "AUDIOBTC", "IOSTBTC", "CELRBTC", "HNTBTC", "ALPHABTC", "ZECBTC", "ICXBTC", "LTCBTC", 
			"COTIBTC", "FTMBTC", "ONEBTC", "CHRBTC", "ARBTC", "CTSIBTC", "GRTBTC",
			"ANKRBTC", "GASBTC", "ARPABTC", "KNCBTC", "ADXBTC", "TVKBTC", "OGNBTC", "LRCBTC", "ONTBTC",
			"RENBTC", "DIABTC", "SUPERBTC", "BAKEBTC", "THETABTC" */                                                                 
            {																		
            																		
            	var crypto = AddCrypto(ticker, res);								
            	_dataBySymbol.Add(crypto.Symbol, new SymbolData(this, crypto));		
            }

            
            
            SetWarmUp(3 * SymbolData.MinutesOfTrading, res);
            //SetWarmUp(SymbolData.MinutesOfTrading, Resolution.Minute);
        }
            

		private decimal NormalizeQuantity(Symbol symbol, decimal quantity)
		{
			var pip = Securities[symbol].SymbolProperties.MinimumPriceVariation;
			return Math.Round(quantity/pip) * pip;
		}


        // ON DATA BLOCK (waar bestanden/data binnenkomt in het programma)
        public override void OnData(Slice data)
        {
        	if (IsWarmingUp) return;
        	if (!_momentumPercent.IsReady) return;
        	

        	foreach (var kvp in _dataBySymbol)
        	{
        		var symbolData = kvp.Value;
        		if (!symbolData.IsReady)
        		{
        			continue;
        		}

        		var symbol = kvp.Key;
        		if (!data.Bars.ContainsKey(symbol))
        		{
        			continue;
        		}
        		
        		
        		if (!data.ContainsKey(symbol) | !data.ContainsKey("BTCUSD")) // !data.ContainsKey(symbol)

        		{
        			return;
        		}
        		

        		
        		//Calculate usdAmount to BtcAmount
        		var btcAmount = usdAmount / data[btcusd].Close;

				//DETERMINE WHAT THE VALUE OF $150 USD IS IN BTC
        		Plot("150 USD in BTC", "Value", btcAmount);
        		
        		var price = data[symbol].Price;
        		
        		var invested = Portfolio[symbol].Invested;
            	_btc = Portfolio.CashBook[valuta].Amount;
            	
        		//_volume = data.Bars[symbol].Volume;

				
				//Log Message  for checking if we getting Data!
				if (LiveMode)
				{
					
					var msg = $"\n{symbol} :: IsInvested? {invested} | Factor: {symbolData.Factor} | ";
					msg += $"LowestAvg: {symbolData.LowestAverage} | Price: {price} | MACD Change: {symbolData.MacdChange} | BTC 24h change %: {_momentumPercent} | Portfolio Amount: {_btc}\n";
					Log(msg);
					
				}

				//BUYING PART!!
        		if (!invested && symbolData.Factor >= 3 && symbolData.LowestAverage >= price && _momentumPercent > _btcStijging && _btc > _minPosition) // && _momentumPercent >= _btcStijging  && _btc > _minPosition
        		{
        			if (symbolData.MacdChange >= 0 && symbolData._rsi <= 20)//&& symbolData.MacdChange < 2  
        			{
        				//Determine order size.       				
      					var quantity = NormalizeQuantity(symbol, btcAmount / data[symbol].Close);
        				
						//var msg = $"\n\n AANKOOP ter waarde van {btcAmount} BTC | {symbol} Hoeveelheid: {quantity} voor een bedrag van {usdAmount} euro | Aankoopprijs {symbol} van {data[symbol].Price}BTC\n\n";
						//Log(msg);
          				//Debug(msg);
          				
						if (quantity == 0) continue;	

						//Placing Order
						MarketOrder(symbol, quantity);
            			
        				Plot("Trades", "AANKOOP", price);

						

					
        				Debug($"\n\n ********** AANKOOP: {symbol} aankoopprijs {data[symbol].Price} ter waarde van {usdAmount}euro **********\n\n");   // Als het order gemaakt is word dit bevestigd door de debug
						
						//Sending message to telegram group
            			Notify.Telegram("-100155824763**", $"Aankoopmogelijkheid {symbol} met aankoopprijs: {data[symbol].Price}", "**087994843:AAGz-tc6Jc5rXuHtNSQcWAJVZygTlZSpUdE");
						
						//Sending message to mail
            			Notify.Email("tradingbot*******@gmail.com", "TradeAlert",$"Gekocht {symbol} op {data[symbol].Price}");

						//Log message
            			Log($"prijs {price} en Max 24uur {symbolData.MaxExchange} en MIN 24uur {symbolData.MinExchange}");

						//Determine Which selling price.
						symbolData.TargetPrice = price * (1 + _targetPercent);   //DETERMINE WICH SELLING PRICE WHEN PROFIT.
						symbolData.StopPrice = price * (1 - _stopPercent);       //DETERMINE WICH SELLING PRICE WHEN LOSS.
            			//symbolData.StopPrice = Math.Max(symbolData.StopPrice, price - (price * _trailPercent));
						
        			}
        		}

        		//SELLING PART!!
				if (invested)
                {
					//Selling with GAIN
                	if (price >= symbolData.TargetPrice)
                	{
                	
                		Debug($"\n\n********** VERKOOP WINST: {symbol} {data[symbol].Price} **********\n\n ");   // Als het order gemaakt is word dit bevestigd door de debug
					

                		Plot("BTC", "Holdings", Portfolio.CashBook["BTC"].Amount);
                		Plot("Trades", "VERKOOP WINST \n", price);
                		
                		var tag = $"+1% WINST VERKOCHT {symbol} op {data[symbol].Price}";
                		
						//Sell Order
                		Liquidate(symbol, tag);  

						//log message  
                    	Log(tag);
					
						//Sending message to telegram group					
						Notify.Telegram("-100155824763**", $"VERKOOP WINST {symbol} met verkoopprijs: {data[symbol].Price}", "**087994843:AAGz-tc6Jc5rXuHtNSQcWAJVZygTlZSpUdE");
                    	
						//Sending message to mail
						Notify.Email("tradingbot*******@gmail.com", "TradeAlert", tag);
                	}

						//Selling with Loss
                	if (price < symbolData.StopPrice)
                	{
                		
                		Debug($"\n\n********** VERKOOP VERLIES: {symbol} {data[symbol].Price} van een bedrag van {usdAmount}euro ********** \n\n");   // Als het order gemaakt is word dit bevestigd door de debug
					

                		Plot("BTC", "Holdings", Portfolio.CashBook["BTC"].Amount);
                		Plot("Trades", "VERKOOP VERLIES \n", price);
                		
                		var tag = $"-10% VERLIES VERKOCHT {symbol} op {data[symbol].Price}";
                		
						//Sell order
                		Liquidate(symbol, tag);

						//Log message
						Log(tag);
						
						//Sending message to mail
						Notify.Telegram("-100155824763***", $"VERKOOP VERLIES {symbol} met verkoopprijs: {data[symbol].Price}", "***087994843:AAGz-tc6Jc5rXuHtNSQcWAJVZygTlZSpUdE");
                    	
						//Sending message to mail
						Notify.Email("tradingbot*****@gmail.com", "TradeAlert", tag);
                	}	
                }
        	}
        }
    }
    

    public class SymbolData
    {
    	private Cash _cash;
    	
		public static int MinutesOfTrading = 1140;
		int MomentumPercentPeriod = 1440;		

		
		public decimal StopPrice;
		public decimal TargetPrice;

        
		//Macd
        public int fast = 12;	//12		5
        public int slow = 26;	//26		35
        public int sig = 9;		//9			5
        
		//RSI
		public Minimum _minCustom;
		public Maximum _maxCustom;

		
		public decimal Holding => _cash.Amount;
		public Maximum MaxExchange { get; private set; }
		public Minimum MinExchange { get; private set; }
 
		
		public MovingAverageConvergenceDivergence _macd {get; private set;}
		public RollingWindow<IndicatorDataPoint> _macdWin {get; private set;}
		public RelativeStrengthIndex _rsi {get; private set;}
		
		
		public bool IsReady => MaxExchange.IsReady && MinExchange.IsReady && _macdWin.IsReady && _macd.IsReady; //&& _rsi.IsReady;
		
		public decimal MacdChange =>(_macdWin[0] - _macdWin[_macdWin.Count - 1]);

		public decimal Factor => (((MaxExchange - MinExchange)/2)/MaxExchange)*100;

		decimal percentage = 2.1m;
		public decimal LowestAverage => ((MaxExchange + MinExchange)/2 + MinExchange)/percentage;
		

	   	public SymbolData(QCAlgorithm algorithm, Crypto crypto)
    	{
    		Resolution resM = Resolution.Minute;
			//Resolution resH = Resolution.Hour;
    		_cash = algorithm.Portfolio.CashBook[crypto.BaseCurrencySymbol];
            MaxExchange = algorithm.MAX(crypto.Symbol, MinutesOfTrading, resM);
            MinExchange = algorithm.MIN(crypto.Symbol, MinutesOfTrading, resM);
            _macd = algorithm.MACD(crypto.Symbol, fast, slow, sig, MovingAverageType.Exponential,resM);
			_macdWin = new RollingWindow<IndicatorDataPoint>(5);
    		_macd.Signal.Updated +=(sender, updated) => _macdWin.Add(updated);
    		_rsi = algorithm.RSI(crypto.Symbol, 4, MovingAverageType.Simple, resM);
    	}
    }

}
#region imports
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Globalization;
    using System.Drawing;
    using QuantConnect;
    using QuantConnect.Algorithm.Framework;
    using QuantConnect.Algorithm.Framework.Selection;
    using QuantConnect.Algorithm.Framework.Alphas;
    using QuantConnect.Algorithm.Framework.Portfolio;
    using QuantConnect.Algorithm.Framework.Execution;
    using QuantConnect.Algorithm.Framework.Risk;
    using QuantConnect.Parameters;
    using QuantConnect.Benchmarks;
    using QuantConnect.Brokerages;
    using QuantConnect.Util;
    using QuantConnect.Interfaces;
    using QuantConnect.Algorithm;
    using QuantConnect.Indicators;
    using QuantConnect.Data;
    using QuantConnect.Data.Consolidators;
    using QuantConnect.Data.Custom;
    using QuantConnect.DataSource;
    using QuantConnect.Data.Fundamental;
    using QuantConnect.Data.Market;
    using QuantConnect.Data.UniverseSelection;
    using QuantConnect.Notifications;
    using QuantConnect.Orders;
    using QuantConnect.Orders.Fees;
    using QuantConnect.Orders.Fills;
    using QuantConnect.Orders.Slippage;
    using QuantConnect.Scheduling;
    using QuantConnect.Securities;
    using QuantConnect.Securities.Equity;
    using QuantConnect.Securities.Future;
    using QuantConnect.Securities.Option;
    using QuantConnect.Securities.Forex;
    using QuantConnect.Securities.Interfaces;
    using QuantConnect.Storage;
    using QuantConnect.Data.Custom.AlphaStreams;
    using QCAlgorithmFramework = QuantConnect.Algorithm.QCAlgorithm;
    using QCAlgorithmFrameworkBridge = QuantConnect.Algorithm.QCAlgorithm;
#endregion
namespace QuantConnect.Algorithm.CSharp
{
}
/*
using QuantConnect.Securities.Crypto;
namespace QuantConnect.Algorithm.CSharp
{
    public class VentralTransdimensionalChamber : QCAlgorithm
    {
    	 
    	//	Trading bot that trades with the highest and lowest exchange rate of the last 24 hours.
    	//	Buying determined bacause the factor and the current price.
    	
      
    	private Dictionary<Symbol, SymbolData> _dataBySymbol;
        
        // VARIABELEN DECLAREREN
        private string _ticker = "ETHEUR";       //virtueel paar - tracks the current USD value of 1 ether.
        private int _startingCash = 2000;
        private decimal _weight = 1m;          ///Percentage van portfolio dat je wilt investeren // % of portfolio for every trade.
        
        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%
        
        int _maxPosition = 900;                  // Max USD invested
        int _minPosition = 750;                  // min USD needed to invest.

        //INITIALIZE BLOCK
        public override void Initialize()
        {
            SetStartDate(2017, 1, 3); 
            SetEndDate(2018, 1, 1);
            SetCash("EUR", _startingCash);
            SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash);
    
    		_dataBySymbol = new Dictionary<Symbol, SymbolData>();
    		
            foreach (var ticker in new [] { "ETHEUR" })
            {
            	var crypto = AddCrypto(ticker, Resolution.Minute);
            	_dataBySymbol.Add(crypto.Symbol, new SymbolData(this, crypto));
            }
            
            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;

        		if (!invested &&
        		    symbolData.Factor >= 3)// &&
        		    //symbolData.LowestAverage > price)
        		{
        			var qnty = CalculateOrderQuantity(symbol, _weight);
        			SetHoldings(symbol, _weight);          // om een order te maken ==>percentage van portfolio dat je wilt investeren
					Debug($"Purchased Stock: {symbol}");   // Als het order gemaakt is word dit bevestigd door de debug
                    //Log($"prijs {price} en Max 24uur {symbolData.MaxExchange} en MIN 24uur symbolData.MinExchange}");

					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 - 2%)     // determine wich selling price at loss.
                }

                if (invested)
                {
                	if (price >= symbolData.TargetPrice)
                	{
                    	Sell(symbol, symbolData.Holding);
                    	//Log($"prijs {price}");
                	}

                	if (price < symbolData.StopPrice)
                	{
                    	Sell(symbol, symbolData.Holding);
                    	//Log($"prijs {price}");
                	}	
                }
        	}
        }
    }

    public class SymbolData
    {
    	private Cash _cash;
    	
		public static int MinutesOfTrading = 1140;

		public decimal StopPrice;
		public decimal TargetPrice;

		//Het aantal Ether we in onze portfolio hebben zitten.
		public decimal Holding => _cash.Amount;
		public Maximum MaxExchange { get; private set; }
		public Minimum MinExchange { get; private set; }

		public bool IsReady => MaxExchange.IsReady && MinExchange.IsReady;

		public decimal Factor => (((MaxExchange - MinExchange)/2)/MaxExchange)*100;

		public decimal LowestAverage => ((MaxExchange + MinExchange)/2 + MinExchange)/2;

	   	public SymbolData(QCAlgorithm algorithm, Crypto crypto)
    	{
    		_cash = algorithm.Portfolio.CashBook[crypto.BaseCurrencySymbol];
            MaxExchange = algorithm.MAX(crypto.Symbol, MinutesOfTrading, Resolution.Minute);
            MinExchange = algorithm.MIN(crypto.Symbol, MinutesOfTrading, Resolution.Minute);
    	}
    }
}
*/