Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
0
Tracking Error
0
Treynor Ratio
0
Total Fees
$0.00
using System;
using System.Linq;
using QuantConnect.Brokerages;
using QuantConnect.Data;
using QuantConnect.Data.Consolidators;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Orders;
using QuantConnect.Securities;

//Copyright HardingSoftware.com, 2018.
//Granted to the public domain.
//Use entirely at your own risk.
namespace QuantConnect 
{   
    public class MultiCoinFramework : QCAlgorithm
    {
    	public ExponentialMovingAverage EMA26;
    	public ExponentialMovingAverage EMA200;
    	
    	string tickersString ="BTCUSD,ETHUSD,LTCUSD";
    	string symbol = "BTCUSD";
    	decimal changes1Ratio=-1.0m; //The influence of change upon fitness.
    	decimal changes2Ratio=0.0m; //The influence of change in change upon fitness.
    	int emaOfChanges1Length=24; //The length of the change indicator. 24
		int emaOfChanges2Length=24; //The length of the change in change indicator. 24
		int ResolutionOffset = 0;
		decimal leverage=1m;
		
		int historyLength=2;
		int changes1Length=2;
		int changes2Length=2;
		Resolution resolution=Resolution.Minute;
		List<StockData> stockDatas = new List<StockData>();
		string stockHeld="";
		
		bool FirstCheck = true;
		bool BoughtDip = false;
		decimal PriceBought = 0;
        public override void Initialize() 
        {
        	
            SetStartDate(2018, 3, 1); 
            SetEndDate(DateTime.Now);
            SetCash(50);
            //SetBenchmark("BTCUSD");
            
            
			string[] tickers = tickersString.Split(new string[1] { "," }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string ticker in tickers)
			{
				Symbol symbol = QuantConnect.Symbol.Create(ticker, SecurityType.Crypto, Market.GDAX);
				AddCrypto(symbol, resolution);
				//Securities[ticker].FeeModel = new ConstantFeeTransactionModel(0.04m); 
				StockData stockData=new StockData();
				stockData.Ticker=ticker;
				stockData.emaOfChanges1Indicator = new ExponentialMovingAverage(emaOfChanges1Length);
            	stockData.emaOfChanges2Indicator = new ExponentialMovingAverage(emaOfChanges2Length);
				stockDatas.Add(stockData);
			}
			foreach (Security s in Securities.Values)
			{
			    s.FeeModel=new CustomFeeModel();
			}
			EMA26 = new ExponentialMovingAverage(26);
			EMA200 = new ExponentialMovingAverage(200);
    	    
        }
		
        public  void SetHoldings_(Symbol symbol,Decimal ratio) 
        {
        	
        	decimal price = Securities[symbol].Price;
		    var quantity =Securities[symbol].Holdings.Quantity;
			
		    // Keep 3% Cash    (for the limit order, rounding errors, and safety)
		    var keep = .03;
		    var usablePortfolioValue = Portfolio.TotalPortfolioValue * Convert.ToDecimal(1 - keep);
		    
		    // +0.1% Limit Order
		   // (to make sure it executes quickly and without much loss)
		   // (if you set the limit large it will act like a market order)
		    var limit = 1.001;
		    var desiredQuantity = usablePortfolioValue * ratio / price;
		    var orderQuantity = desiredQuantity - quantity;
		    // limit needs to be inverse when selling
		    decimal limitPrice = 0;
		    if (orderQuantity >= 0) {
		    	limitPrice = price * Convert.ToDecimal(limit);
		    }else {
		    	limitPrice = price * Convert.ToDecimal(1/limit);	
		    }
		    
		    Log("Limit Order: "+ orderQuantity+ " coins @ $"+limitPrice+ " per coin");
		    LimitOrder(symbol, orderQuantity, limitPrice);
		        	
        }
        
        public override void OnData(Slice data) 
        {
        	if (data.ContainsKey(symbol))
        	{
        		//ResolutionOffset++;
	        	//if (ResolutionOffset > 30 || FirstCheck)
	        	//{
	      
	        	    	
		        	    Debug(EMA26.ToString());
		        		FirstCheck = false;
		        		ResolutionOffset = 0;
		        		if(BoughtDip && Securities[symbol].BidPrice > PriceBought + (PriceBought * 0.002m)  )
		        		{
		        			PriceBought = 0;
		        			BoughtDip = false;
		        			Liquidate();
		        		}
			        	else if (!Portfolio.Invested && EMA26 < EMA200 &&
			        		Securities[symbol].AskPrice < EMA26 - (EMA26 * 0.05m) )		
			        	{
			        		PriceBought = Securities[symbol].AskPrice;
			        		BoughtDip = true;
			        		SetHoldings(symbol, leverage);
			        		
			        	}
	        	    }
		        	//else
		        	//{
		        		//StockData selectedStockData=q2.First();
		        		//if (selectedStockData.Ticker != stockHeld)
		        		//{
		        			//Liquidate();
		        			//SetHoldings_(symbol, leverage);
							//stockHeld=selectedStockData.Ticker;
		        		//}
		
		        	//}
	        	//}
        	
        }
        
        class StockData
        {
        	public string Ticker;
			public List<decimal> history=new List<decimal>();
			public List<decimal> changes1History=new List<decimal>();
			public List<decimal> changes2History=new List<decimal>();
			public ExponentialMovingAverage emaOfChanges1Indicator;
			public ExponentialMovingAverage emaOfChanges2Indicator;
			public decimal Fitness;
        }
        
		
		
		// Custom fee implementation
		public class CustomFeeModel : IFeeModel
	    {
	        public decimal GetOrderFee(Security security, Order order)
	        {
	            var fee = order.AbsoluteQuantity*0.0025m*security.Price;
	            return fee;
	        }
	    }
    }
}