Overall Statistics
Total Trades
894
Average Win
0.28%
Average Loss
-0.42%
Compounding Annual Return
98.029%
Drawdown
4.900%
Expectancy
0.367
Net Profit
98.400%
Sharpe Ratio
6.173
Loss Rate
18%
Win Rate
82%
Profit-Loss Ratio
0.67
Alpha
0.562
Beta
0.062
Annual Standard Deviation
0.092
Annual Variance
0.008
Information Ratio
3.142
Tracking Error
0.162
Treynor Ratio
9.087
Total Fees
$894.00
//Copyright HardingSoftware.com 2019, granted to the public domain.
//Use at your own risk. Do not remove this copyright notice.
namespace QuantConnect.Algorithm.CSharp
{
    public class TMA2Algo : QCAlgorithm
    {
		Symbol symbol = QuantConnect.Symbol.Create("Y", SecurityType.Equity, Market.USA);
		int period = 10;
		decimal LimitRatio = 0.5m;
		Resolution resolution = Resolution.Minute;
		TimeSpan orderExpiryTime = new TimeSpan(0,0,0,59);
		int priceDecimals = 2;
		List<TradeBar> history = new List<TradeBar>();
		decimal startCash = 5000;
		
        public override void Initialize()
        {
            SetStartDate(2018, 8, 14);
            SetEndDate(2019, 8, 14);
            SetCash(startCash);
            
            AddEquity(symbol, resolution);
        }

        public override void OnData(Slice data)
        {
        	CancelExpiredOrders();
        	if (data.Bars.ContainsKey(symbol) && data.Bars[symbol] != null)
        	{
        		history.Add(data.Bars[symbol]);
        		if (history.Count > period)
        		{
        			history.RemoveAt(0);
        		}
        		else
        		{
        			return;
        		}
                decimal tma = TMA2.TriangularCandleAverage(history);
                decimal range = TMA2.FullRange(history);
                decimal buyPrice = tma - LimitRatio * range;
                decimal sellPrice = tma + LimitRatio * range;
    			if (Portfolio[symbol].Quantity == 0)
    			{
    				buyPrice = Math.Round(buyPrice, priceDecimals);
    				if (buyPrice > 0)
    				{
	    				decimal quantity = startCash / buyPrice;
	    				if (OrderIsPlaced(symbol, quantity) == false)
	    				{
	    					Transactions.CancelOpenOrders();
	        				LimitOrder(symbol, quantity, buyPrice);
	    				}
    				}
    			}
    			else if (Portfolio[symbol].Quantity > 0)
    			{
    				sellPrice = Math.Round(sellPrice, priceDecimals);
    				if (sellPrice > 0)
    				{
	    				decimal quantity = -Portfolio[symbol].Quantity;
	    				if (OrderIsPlaced(symbol, quantity) == false)
	    				{
	    					Transactions.CancelOpenOrders();
	        				LimitOrder(symbol, quantity, sellPrice);
	    				}
    				}
    			}
        	}
        }
        
        public bool OrderIsPlaced(Symbol symbol, decimal quantity)
        {
        	List<Order> orders = Transactions.GetOpenOrders(symbol);
        	foreach (Order order in orders)
        	{
        		if (order.Symbol == symbol)
        		{
        			if (Math.Sign(quantity) == Math.Sign(order.Quantity))
        			{
        				return true;
        			}
        		}
        	}
        	return false;
        }
        
        public void CancelExpiredOrders()
        {
        	List<Order> orders = Transactions.GetOpenOrders();
        	foreach (Order order in orders)
        	{
        		if (Time > order.Time + orderExpiryTime)
        		{
        			Transactions.CancelOrder(order.Id);
        		}
        	}
        }

		public class TMA2
		{
			//Copyright HardingSoftware.com 2019, granted to the public domain.
			//Use at your own risk. Do not remove this copyright notice.
			
			public static decimal TriangularCandleAverage(List<TradeBar> candles)
	        {
	            return TriangularMovingAverage(CandleAverages(candles));
	        }
	
	        public static decimal[] CandleAverages(List<TradeBar> candles)
	        {
	            return candles.Select(x => CandleAverage(x)).ToArray();
	        }
	
	        public static decimal CandleAverage(TradeBar candle)
	        {
	            return (candle.Open + candle.High + candle.Low + candle.Close) / 4;
	        }
	        
	        public static decimal[] TriangularWeightsDecimal(int length)
	        {
	            int[] intWeights = Enumerable.Range(1, length).ToArray();
	            return intWeights.Select(x => Convert.ToDecimal(x)).ToArray();
	        }
	
	        public static decimal TriangularMovingAverage(decimal[] values)
	        {
	            return WeightedAverage(values, TriangularWeightsDecimal(values.Length));
	        }
	        
	        public static decimal FullRange(List<TradeBar> candles)
	        {
	            return candles.Select(x => x.High).Max() - candles.Select(x => x.Low).Min();
	        }
	        
	        public static decimal WeightedAverage(decimal[] values, decimal[] weights)
	        {
	            return values.Zip(weights, (x, y) => x * y).Sum() / weights.Sum();
	        }
		}
    }
}