Overall Statistics
Total Trades
15544
Average Win
0.22%
Average Loss
-0.11%
Compounding Annual Return
96.517%
Drawdown
16.600%
Expectancy
0.163
Net Profit
270.095%
Sharpe Ratio
2.114
Probabilistic Sharpe Ratio
88.026%
Loss Rate
62%
Win Rate
38%
Profit-Loss Ratio
2.05
Alpha
0.331
Beta
0.235
Annual Standard Deviation
0.32
Annual Variance
0.102
Information Ratio
-1.407
Tracking Error
0.565
Treynor Ratio
2.884
Total Fees
$1292258.19
Estimated Strategy Capacity
$210000.00
Lowest Capacity Asset
GHSTUSDT 18N
using System.Drawing;
using Newtonsoft.Json;

namespace QuantConnect 
{
    public class BasicTemplateAlgorithm : QCAlgorithm
    {
    	int arraySize, avgSize;
    	Dictionary<Symbol, decimal[]> yArrays = new Dictionary<Symbol, decimal[]>();
    	Dictionary<Symbol, decimal[]> xArrays = new Dictionary<Symbol, decimal[]>();
    	Dictionary<Symbol, decimal[]> slopeArrays = new Dictionary<Symbol, decimal[]>();
    	Dictionary<Symbol, decimal[]> yLongArrays = new Dictionary<Symbol, decimal[]>();
    	Dictionary<Symbol, decimal[]> smaArrays = new Dictionary<Symbol, decimal[]>();
    	Dictionary<Symbol, decimal> slopes = new Dictionary<Symbol, decimal>();
    	Dictionary<Symbol, decimal> slopeLongs = new Dictionary<Symbol, decimal>();
    	Dictionary<Symbol, decimal> smaSlopes = new Dictionary<Symbol, decimal>();
    	Dictionary<Symbol, decimal> maxPrice = new Dictionary<Symbol, decimal>();
    	Dictionary<Symbol, decimal> stopPrice = new Dictionary<Symbol, decimal>();
    	Dictionary<Symbol, decimal> maxBar = new Dictionary<Symbol, decimal>();
    	Dictionary<Symbol, decimal> avgBar = new Dictionary<Symbol, decimal>();
    	Dictionary<Symbol, decimal> avgSlope = new Dictionary<Symbol, decimal>();
    	Dictionary<Symbol, List<decimal>> barSize = new Dictionary<Symbol, List<decimal>>();
    	Dictionary<Symbol, List<decimal>> slopeSize = new Dictionary<Symbol, List<decimal>>();  
    	Resolution _res; 
    	List<string> _symbols;
    	string _stableSymbol = "USDT";
    	Dictionary<Symbol, int> count = new Dictionary<Symbol, int>();
    	Dictionary<Symbol, int> startCounter = new Dictionary<Symbol, int>();
    	Dictionary<Symbol, bool> start = new Dictionary<Symbol, bool>();
    	Dictionary<Symbol, bool> canBuyAgain = new Dictionary<Symbol, bool>();
    	Dictionary<Symbol, Chart> _charts = new Dictionary<Symbol, Chart>();
    	Dictionary<Symbol, decimal> _priceArray = new Dictionary<Symbol, decimal>();
    	Dictionary<Symbol, SimpleMovingAverage> _smas = new Dictionary<Symbol, SimpleMovingAverage>();
        Dictionary<Symbol, HullMovingAverage> _hmas = new Dictionary<Symbol, HullMovingAverage>();
        Dictionary<Symbol, HullMovingAverage> _hmasLong = new Dictionary<Symbol, HullMovingAverage>();      
    	
        public override void Initialize()  
        {
        	//_symbols = new List<string>() {"ETH"+_stableSymbol};
        	_symbols = new List<string>() {
        		"BTC"+_stableSymbol, 
        		"LTC"+_stableSymbol, 
        		"ETH"+_stableSymbol,
        		"ADA"+_stableSymbol,
        		"DOGE"+_stableSymbol,
        		"XMR"+_stableSymbol,
        		"XRP"+_stableSymbol,
        		"AAVE"+_stableSymbol,
        		"SOL"+_stableSymbol,
        		"ALGO"+_stableSymbol,
        		"MATIC"+_stableSymbol,
        		"DOT"+_stableSymbol,
        		"UNI"+_stableSymbol,
        		"CAKE"+_stableSymbol,
        		"SAND"+_stableSymbol,
        		"AXS"+_stableSymbol,
        		"MANA"+_stableSymbol,
        		"GHST"+_stableSymbol,
        		"ILV"+_stableSymbol,
        		"SHIB"+_stableSymbol,
        		"LINK"+_stableSymbol,
        		"BEAM"+_stableSymbol,
        		"BCH"+_stableSymbol 
        	}; 
        	
        	//SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash);
        	//DefaultOrderProperties = new GDAXOrderProperties { PostOnly = true };
        	//SetBrokerageModel(BrokerageName.AlphaStreams, AccountType.Margin); 
        	SetBrokerageModel(BrokerageName.Binance, AccountType.Cash);
        	_res = Resolution.Hour;    
        	 
            SetStartDate(2020, 01, 01);                                    
            //SetEndDate(2018, 08, 13);                   
            SetEndDate(DateTime.Now.Date.AddDays(-1));      
            
            SetAccountCurrency(_stableSymbol);
            
            SetCash(_stableSymbol, 1000000);  
            
            //used variables
            arraySize = 2;
            avgSize = 700;
            foreach (var etf in _symbols)
            { 
            	AddCrypto(etf, Resolution.Second, Market.Binance);  
            	var hourConsolidator = new TradeBarConsolidator(TimeSpan.FromMinutes(60));         
            	
            	var sma = new SimpleMovingAverage("SMA_" + etf, 5);   
            	var hma = new HullMovingAverage("HMA_" + etf, 50);
            	var hmaL = new HullMovingAverage("HMAL_" + etf, 500);     
            	
            	_priceArray.Add(etf, 0.0m);
            	_smas.Add(etf, sma);
            	_hmas.Add(etf, hma);
            	_hmasLong.Add(etf, hmaL); 
            	
            	RegisterIndicator(etf, sma, hourConsolidator);
            	RegisterIndicator(etf, hma, hourConsolidator);
            	RegisterIndicator(etf, hmaL, hourConsolidator);
            	
            	SubscriptionManager.AddConsolidator(etf, hourConsolidator);   
            	hourConsolidator.DataConsolidated += theHandler; 
            	
            	var plotter = new Chart("Plotter-"+etf);
	        	_charts.Add(etf, plotter);
	        	
				plotter.AddSeries(new Series("Price-"+etf, SeriesType.Line, index:0));
				plotter.AddSeries(new Series("HMA-"+etf, SeriesType.Line, index:0));
				plotter.AddSeries(new Series("SMA-"+etf, SeriesType.Line, index:0));
				plotter.AddSeries(new Series("Buy-"+etf, SeriesType.Scatter, string.Empty, Color.Green, ScatterMarkerSymbol.Triangle));
				plotter.AddSeries(new Series("Sell-"+etf, SeriesType.Scatter, string.Empty, Color.Red, ScatterMarkerSymbol.TriangleDown));
				AddChart(plotter);
				
				yArrays.Add(etf, new decimal[arraySize]);
				xArrays.Add(etf, new decimal[arraySize]);
				slopeArrays.Add(etf, new decimal[arraySize]);
				yLongArrays.Add(etf, new decimal[arraySize]);
				smaArrays.Add(etf, new decimal[arraySize]);
				barSize.Add(etf, new List<decimal>());
				slopeSize.Add(etf, new List<decimal>());
				slopes.Add(etf, 0.0m);
				slopeLongs.Add(etf, 0.0m);
				smaSlopes.Add(etf, 0.0m);
				maxPrice.Add(etf, 0.0m);
				stopPrice.Add(etf, 0.0m);
				maxBar.Add(etf, 0.0m);
				avgBar.Add(etf, 0.0m);
				avgSlope.Add(etf, 0.0m);
				
				count.Add(etf, 0);
				startCounter.Add(etf, 0);
				start.Add(etf, true);
				canBuyAgain.Add(etf, false);
				var history = History(etf, 700);
	            foreach (var tradeBar in history)
	            {
	            	_priceArray[etf] = tradeBar.Close;
	            	_smas[etf].Update(tradeBar.EndTime, tradeBar.Close);
	            	_hmas[etf].Update(tradeBar.EndTime, tradeBar.Close);
	            	_hmasLong[etf].Update(tradeBar.EndTime, tradeBar.Close); 
	            	
	            	if(count[etf] < avgSize)
			    	{
			    		if((tradeBar.Open - tradeBar.Close) > 0)
			    		{
			    			barSize[etf].Add(Math.Abs(tradeBar.Open - tradeBar.Close));
			    		}
	            	
		            	decimal add = 0;
		            	
		            	for (int i = 0; i < barSize[etf].Count; i++) 
				            add = add + barSize[etf][i];
		            	
		            	if(barSize[etf].Count > 0)
		            		avgBar[etf] = add / barSize[etf].Count;
				    }
			    	else
			    	{
			    		if(barSize[etf].Count > avgSize)
			    		{
			    			if((tradeBar.Open - tradeBar.Close) > 0)
			    			{
			    				for (int i = 0; i < barSize[etf].Count-1; i++)
					       		{
					       			barSize[etf][i] = (decimal)barSize[etf][i+1]; 
					       		}
				       		
				       			barSize[etf][barSize[etf].Count-1] = Math.Abs(tradeBar.Open - tradeBar.Close);
			    			}
			    		}
			       		
			       		decimal add = 0;
		            	
		            	for (int i = 0; i < barSize[etf].Count; i++) 
				            add = add +barSize[etf][i];
				            
		            	if(barSize[etf].Count > 0)
		            		avgBar[etf] = add / barSize[etf].Count;
			    	}
	            	
	            	if(count[etf] < arraySize)
			    	{
			    		yArrays[etf][count[etf]] = _hmas[etf];
			    		yLongArrays[etf][count[etf]] = _hmasLong[etf];
			    		smaArrays[etf][count[etf]] = _smas[etf];
			    		xArrays[etf][count[etf]] = count[etf];
			    		slopeArrays[etf][count[etf]] = 0;
			    		count[etf]++;
			    	}
			    	else
			    	{
			       		for (int i = 0; i < arraySize-1; i++)
			       		{
			       			yArrays[etf][i] = (decimal)yArrays[etf][i+1]; 
			       			yLongArrays[etf][i] = (decimal)yLongArrays[etf][i+1]; 
			       			smaArrays[etf][i] = (decimal)smaArrays[etf][i+1];  
			       		}
			       		
			       		yArrays[etf][arraySize-1] = _hmas[etf];
			       		yLongArrays[etf][arraySize-1] = _hmasLong[etf];
			       		smaArrays[etf][arraySize-1] = _smas[etf];
						
						slopes[etf] = Math.Round(GetSlope(xArrays[etf], yArrays[etf]), 10);
						slopeLongs[etf] = Math.Round(GetSlope(xArrays[etf], yLongArrays[etf]), 10);
						smaSlopes[etf] = Math.Round(GetSlope(xArrays[etf], smaArrays[etf]), 10);
						
						if(count[etf] < avgSize)
				    	{
				    		if(slopes[etf] > 0)
				    		{
				    			slopeSize[etf].Add(slopes[etf]);
				    		}
		            	
			            	decimal add = 0;
			            	
			            	for (int i = 0; i < slopeSize[etf].Count; i++) 
					            add = add +slopeSize[etf][i];
			            	
			            	if(slopeSize[etf].Count > 0)
			            		avgSlope[etf] = add / slopeSize[etf].Count;
					    }
				    	else
				    	{
				    		if(slopeSize[etf].Count > avgSize)
				    		{
				    			if(slopes[etf] > 0)
				    			{
				    				for (int i = 0; i < slopeSize[etf].Count-1; i++)
						       		{
						       			slopeSize[etf][i] = (decimal)slopeSize[etf][i+1]; 
						       		}
					       		
					       			slopeSize[etf][slopeSize[etf].Count-1] = slopes[etf];
				    			}
				    		}
				       		
				       		decimal add = 0;
			            	
			            	for (int i = 0; i < slopeSize[etf].Count; i++) 
					            add = add + slopeSize[etf][i];
					            
			            	if(slopeSize[etf].Count > 0)
			            		avgSlope[etf] = add / slopeSize[etf].Count;
				    	}
			    	}
	            }
            }
        }
		
		public override void OnOrderEvent(OrderEvent orderEvent)
        {
        	if (orderEvent.FillQuantity == 0)
            	return;
        
        	var fetched = Transactions.GetOrderById(orderEvent.OrderId);
        	
        	Debug(fetched.Type + " filled Symbol: " + orderEvent.Symbol + " Quantity: " + orderEvent.FillQuantity + " Price: " + fetched.Price + " Direction: " + orderEvent.Direction);
        	
        	if(orderEvent.Direction.ToString() == "Buy")
            {
            	Plot("Plotter-"+orderEvent.Symbol, "Buy-"+orderEvent.Symbol, fetched.Price);
            	maxPrice[orderEvent.Symbol] = fetched.Price; 
            	stopPrice[orderEvent.Symbol] = fetched.Price - (avgBar[orderEvent.Symbol]/2) * fetched.Price;
            }
            else if(orderEvent.Direction.ToString() == "Sell") 
            {
            	Plot("Plotter-"+orderEvent.Symbol, "Sell-"+orderEvent.Symbol, fetched.Price);
	            canBuyAgain[orderEvent.Symbol] = false;
            }
        }
        
        private void buyMeSome(TradeBar consolidated, string symbol)
        {
        	decimal price = consolidated.Close; 
        	decimal toInvest;
        	
        	int countInSymbols = 0;
        	decimal takeOut = 0;
        	
        	foreach (var etf in _symbols)
            {
            	string s = etf.Replace(_stableSymbol,"");
            	decimal sQuantity = Portfolio.CashBook[s].Amount;
            	if(sQuantity > 0.0001m)  
            	{
            		countInSymbols++;
            		//takeOut = takeOut + (sQuantity * Portfolio[etf].Price);
            	}
            }
            
            int insym = countInSymbols;
            countInSymbols = Math.Abs(_symbols.Count - countInSymbols);
            
            if(countInSymbols == 0) 
            	countInSymbols = 1;
        	
        	toInvest = (Portfolio.CashBook[_stableSymbol].Amount * 0.98m) - takeOut;    
        	toInvest = toInvest / countInSymbols;   
        	
        	//Debug("Buy symbol "+ symbol +" Portfolio.CashBook[\""+_stableSymbol+"\"].Amount " + Portfolio.CashBook[_stableSymbol].Amount+" toInvest " + toInvest + " Price "+price); 
        	
        	//Debug("countOutSymbols "+ countInSymbols+" Portfolio.TotalPortfolioValue " + Portfolio.TotalPortfolioValue+" toInvest " + toInvest);
        	
        	decimal amount = Math.Round((decimal)(toInvest) / (decimal)price, 10); 
        	double confidence = Convert.ToDouble((slopes[symbol]*100)/avgSlope[symbol]);   
        	
        	if(confidence>100)
        		confidence = 100;
        	
        	EmitInsights(
                Insight.Price(symbol, TimeSpan.FromMinutes(60), InsightDirection.Up, null, confidence, null)    
            );
        	
        	//Buy(symbol, amount); 
        	MarketOrder(symbol, amount);
        }
        
        private void sellMeSome(TradeBar consolidated, string symbol)
        {
        	EmitInsights(
                Insight.Price(symbol, TimeSpan.FromMinutes(60), InsightDirection.Flat, null, 100, null)      
            );
            
            //Debug("Sell symbol "+ symbol +" Portfolio.CashBook[\""+_stableSymbol+"\"].Amount " + Portfolio.CashBook[_stableSymbol].Amount); 
            //decimal amount = Portfolio[symbol].Quantity;
            //Sell(symbol, amount);
        	SetHoldings(symbol, 0m);    
        }

        
        public void OnData(TradeBars data) 
        { 
        	foreach (var bar in data.Values)
		    {
		    	foreach (var etf in _symbols)
	            {
	            	if (etf == bar.Symbol) 
	            	{
	            		/*
	            		if(Portfolio[etf].Quantity > 0.001m && data[etf].Close > maxPrice[etf]) 
			        	{
			        		maxPrice[etf] = data[etf].Close;
			        		stopPrice[etf] = maxPrice[etf] - (avgBar[etf] * maxPrice[etf]);           
			        	}
			        		
			        	if(Portfolio[etf].Quantity > 0.001m && data[etf].Close <= stopPrice[etf])  
			        	{
			        		Debug(etf+" hit trailing stop of " + stopPrice);
			        		sellMeSome(bar, etf);  
			        	}
			        	*/
			        	//if(Portfolio[_symbol].Quantity > 0.001m && data[_symbol].Close > takeProfit)      
			        		//sell = true;
			        } 
	            }
		    }
        }
        
        private void theHandler(object sender, TradeBar consolidated)
        {
        	string currentSymbol = consolidated.Symbol;
        	
        	if (!_hmas[currentSymbol].IsReady || !_hmasLong[currentSymbol].IsReady|| !_smas[currentSymbol].IsReady) return;
        	 
        	decimal _price = consolidated.Close;
        	_priceArray[currentSymbol] = _price;
        	decimal mb = Math.Abs(consolidated.Open - consolidated.Close);
        	if(mb > maxBar[currentSymbol])
        		maxBar[currentSymbol] = mb;
        		
        	if(count[currentSymbol] < avgSize)
	    	{
	    		if((consolidated.Open - consolidated.Close) > 0)
	    		{
	    			barSize[currentSymbol].Add(Math.Abs(consolidated.Open - consolidated.Close));
	    		}
        	
            	decimal add = 0;
            	
            	for (int i = 0; i < barSize[currentSymbol].Count; i++) 
		            add = add + barSize[currentSymbol][i];
            	
            	if(barSize[currentSymbol].Count > 0)
            		avgBar[currentSymbol] = add / barSize[currentSymbol].Count;
		    }
	    	else
	    	{
	    		if(barSize[currentSymbol].Count > avgSize)
	    		{
	    			if((consolidated.Open - consolidated.Close) > 0)
	    			{
	    				for (int i = 0; i < barSize[currentSymbol].Count-1; i++)
			       		{
			       			barSize[currentSymbol][i] = (decimal)barSize[currentSymbol][i+1]; 
			       		}
		       		
		       			barSize[currentSymbol][barSize[currentSymbol].Count-1] = Math.Abs(consolidated.Open - consolidated.Close);
	    			}
	    		}
	       		
	       		decimal add = 0;
            	
            	for (int i = 0; i < barSize[currentSymbol].Count; i++) 
		            add = add + barSize[currentSymbol][i];
		            
            	if(barSize[currentSymbol].Count > 0)
            		avgBar[currentSymbol] = add / barSize[currentSymbol].Count;
	    	}
    		
        	if(count[currentSymbol] < arraySize)
	    	{
	    		yArrays[currentSymbol][count[currentSymbol]] = _hmas[currentSymbol];
	    		yLongArrays[currentSymbol][count[currentSymbol]] = _hmasLong[currentSymbol];
	    		smaArrays[currentSymbol][count[currentSymbol]] = _smas[currentSymbol];
	    		xArrays[currentSymbol][count[currentSymbol]] = count[currentSymbol];
	    		slopeArrays[currentSymbol][count[currentSymbol]] = 0;
	    		count[currentSymbol]++;
	    	}
	    	else
	    	{
	       		for (int i = 0; i < arraySize-1; i++)
	       		{
	       			yArrays[currentSymbol][i] = (decimal)yArrays[currentSymbol][i+1]; 
	       			yLongArrays[currentSymbol][i] = (decimal)yLongArrays[currentSymbol][i+1]; 
	       			smaArrays[currentSymbol][i] = (decimal)smaArrays[currentSymbol][i+1];
	       		}
	       		
	       		yArrays[currentSymbol][arraySize-1] = _hmas[currentSymbol];
	       		yLongArrays[currentSymbol][arraySize-1] = _hmasLong[currentSymbol];
	       		smaArrays[currentSymbol][arraySize-1] = _smas[currentSymbol];
				
				slopes[currentSymbol] = Math.Round(GetSlope(xArrays[currentSymbol], yArrays[currentSymbol]), 10);
				slopeLongs[currentSymbol] = Math.Round(GetSlope(xArrays[currentSymbol], yLongArrays[currentSymbol]), 10); 
				smaSlopes[currentSymbol] = Math.Round(GetSlope(xArrays[currentSymbol], smaArrays[currentSymbol]), 10);
				
				if(count[currentSymbol] < avgSize)
		    	{
		    		if(slopes[currentSymbol] > 0)
		    		{
		    			slopeSize[currentSymbol].Add(slopes[currentSymbol]);
		    		}
            	
	            	decimal add = 0;
	            	
	            	for (int i = 0; i < slopeSize[currentSymbol].Count; i++) 
			            add = add +slopeSize[currentSymbol][i];
	            	
	            	if(slopeSize[currentSymbol].Count > 0)
	            		avgSlope[currentSymbol] = add / slopeSize[currentSymbol].Count;
			    }
		    	else
		    	{
		    		if(slopeSize[currentSymbol].Count > avgSize)
		    		{
		    			if(slopes[currentSymbol] > 0)
		    			{
		    				for (int i = 0; i < slopeSize[currentSymbol].Count-1; i++)
				       		{
				       			slopeSize[currentSymbol][i] = (decimal)slopeSize[currentSymbol][i+1]; 
				       		}
			       		
			       			slopeSize[currentSymbol][slopeSize[currentSymbol].Count-1] = slopes[currentSymbol];
		    			}
		    		}
		       		
		       		decimal add = 0;
	            	
	            	for (int i = 0; i < slopeSize[currentSymbol].Count; i++) 
			            add = add + slopeSize[currentSymbol][i];
			            
	            	if(slopeSize[currentSymbol].Count > 0)
	            		avgSlope[currentSymbol] = add / slopeSize[currentSymbol].Count;
		    	}
					
				decimal divide = 1;
				if(avgBar[currentSymbol] > 0)
					divide = avgBar[currentSymbol];
				
				decimal slopeCoeficient = avgSlope[currentSymbol] / 4; 
				decimal getoutCoeficient = slopeCoeficient * 0.03m;        
	             
	            //Debug(currentSymbol+" slope <" + slopes[currentSymbol] + "> HMALong <" + _hmasLong[currentSymbol] + "> HMAShort <" + _hmas[currentSymbol] + "> SMA <" + _smas[currentSymbol] + "> SMA-Slope <" + smaSlopes[currentSymbol] + ">"); 
	            //Debug(currentSymbol+" slopeCoeficient <" + Math.Round(slopeCoeficient, 10) +  "> getoutCoeficient <" + Math.Round(getoutCoeficient, 10) +"> avgBar <" + avgBar[currentSymbol] +"> divide <" + divide +"> _price <" + _price +">"); 
	            //Debug(currentSymbol+" slopeCoeficient:" + Math.Round(slopeCoeficient, 10)+" slope:" + Math.Round(slopes[currentSymbol], 10) +  " getoutCoeficient:" + Math.Round(getoutCoeficient, 10) +"avgBar:" + avgBar[currentSymbol] +" divide:" + divide +" _price:" + _price +" avgSlope:"+avgSlope[currentSymbol]); 
	            
	            
	            startCounter[currentSymbol]++;
	            if(startCounter[currentSymbol] < 2) 
	            	return;
	            	
	            if(_smas[currentSymbol] < _hmas[currentSymbol] )
					start[currentSymbol] = false; 
					
				if(start[currentSymbol])
					return;
					
				if(!canBuyAgain[currentSymbol]) 
					canBuyAgain[currentSymbol] = true; 
					
				plotOnTick(currentSymbol);
				
				if(!consolidated.Time.ToString().Contains("8/8/2018") && !consolidated.Time.ToString().Contains("8/9/2018") && !consolidated.Time.ToString().Contains("8/10/2018"))
				{
					if(Portfolio[currentSymbol].Quantity < 0.001m) 
		            {   
		            	if(slopes[currentSymbol] > slopeCoeficient && canBuyAgain[currentSymbol] && _smas[currentSymbol] > _hmas[currentSymbol])            
		            	{
		                	//Debug("Conditions to BUY in... "+currentSymbol); 
		                	buyMeSome(consolidated, currentSymbol);
		            	}
		            }
		            else
		            {
		            	if((slopes[currentSymbol] < getoutCoeficient || _smas[currentSymbol] < _hmas[currentSymbol]))   
		            	{
		                    //Debug("Conditions to SELL out... "+currentSymbol);   
		                    sellMeSome(consolidated, currentSymbol);
		            	}
		            }
				}
        	}
        } 

        
        public static decimal GetSlope(decimal[] xArray, decimal[] yArray)
		{
		    if (xArray == null)
		        throw new ArgumentNullException("xArray");
		    if (yArray == null)
		        throw new ArgumentNullException("yArray");
		    if (xArray.Length != yArray.Length)
		        throw new ArgumentException("Array Length Mismatch");
		    if (xArray.Length < 2)
		        throw new ArgumentException("Arrays too short.");
		
		    decimal n = xArray.Length;
		    decimal sumxy = 0, sumx = 0, sumy = 0, sumx2 = 0;
		    for (int i = 0; i < xArray.Length; i++)
		    {
		        sumxy += xArray[i] * yArray[i];
		        sumx += xArray[i];
		        sumy += yArray[i];
		        sumx2 += xArray[i] * xArray[i];
		    }
		    return ((sumxy - sumx * sumy / n) / (sumx2 - sumx * sumx / n));
		}
		
		public void plotOnTick(string currentSymbol) {
            if (!_hmas[currentSymbol].IsReady || !_hmasLong[currentSymbol].IsReady|| !_smas[currentSymbol].IsReady) return; 
            Plot("Plotter-"+currentSymbol, "Price-"+currentSymbol, _priceArray[currentSymbol]);
            Plot("Plotter-"+currentSymbol, "HMA-"+currentSymbol, _hmas[currentSymbol]); 
            Plot("Plotter-"+currentSymbol, "HMALong-"+currentSymbol, _hmasLong[currentSymbol]);  
            Plot("Plotter-"+currentSymbol, "SMA-"+currentSymbol, _smas[currentSymbol]);  
        }
    }
   
    
}