Overall Statistics |
Total Trades 374 Average Win 2.33% Average Loss -2.19% Compounding Annual Return 17172.516% Drawdown 29.500% Expectancy 0.458 Net Profit 443.643% Sharpe Ratio 4.374 Loss Rate 29% Win Rate 71% Profit-Loss Ratio 1.07 Alpha 4.831 Beta -0.515 Annual Standard Deviation 1.1 Annual Variance 1.209 Information Ratio 4.255 Tracking Error 1.12 Treynor Ratio -9.333 Total Fees $3410.70 |
using System; using System.Collections.Generic; using QuantConnect.Data.Market; using QuantConnect.Orders; using QuantConnect.Orders.Fees; using QuantConnect.Orders.Fills; using QuantConnect.Orders.Slippage; using QuantConnect.Securities; namespace QuantConnect { public class Algo4 : QCAlgorithm { //You can adjust this first set to optimize. int atrPeriod = 15; decimal minimumAtrPercentage=0.015m; decimal atrMultiplier=3m; //Your broker is going to hate you if you set these too low as it will result in large amounts of unfilled //order cancellations. It bogs down LEAN as well. int barsToHoldBuyOrdersFor=3; int barsToHoldSellOrdersFor=3; //Be careful adjusting this next one, too high of a setting will result in unrealistically large //purchases being made with no regards for slippage. decimal ratioOfLastBarForMaxTrade =0.05m; Resolution resolution = Resolution.Minute; Dictionary<string,AverageTrueRange> atrs=new Dictionary<string,AverageTrueRange>(); Dictionary<string,OrderTicket> buyOrders=new Dictionary<string,OrderTicket>(); Dictionary<string,int> buyOrderCounts = new Dictionary<string,int>(); Dictionary<string,decimal> buyOrderPrices = new Dictionary<string,decimal>(); Dictionary<string,OrderTicket> sellOrders=new Dictionary<string,OrderTicket>(); Dictionary<string,int> sellOrderCounts = new Dictionary<string,int>(); public override void Initialize() { SetStartDate(2016, 1, 1); SetEndDate(2016, 5, 1); SetCash(20000); //volatile etf's //string tickersString="JDST,JNUG,DRIP,NUGT,GUSH,UVXY,GASL,LABU,LABD,GASX,TVIX,DWTI,UWTI,DGAZ,UGAZ,UBIO,ZBIO,BRZU,ERY,SCO,ERX,RUSS,UCO,RUSL,SILJ,XIV,SVXY,BIB,VXX,BIS,VIXY,SOXL,VIIX,BOIL,SOXS,SLVP,USLV,DSLV,GDXJ,BZQ,GLDX,RING,TZA,TNA,AMZA,DUG,DIG,XES,SRTY,SIL,PSCE,URTY,YINN,SGDM,YANG,OIL,XME,GDX,DRV,DRN,XOP,TQQQ,SMHD,SQQQ,CURE,XBI,FCG,OIH,SBIO,MIE,EDC,FAZ,FAS,MLPI,EDZ,IEZ,ZSL,AGQ,FXN,JGBT,AMU,SLX,TECL,USO,NTG,TECS,AMLP,BNO,MLPN,MIDU,MLPA,NGE,AMJ,INDL,IEO,UNG,EPU,UGLD,DGLD,YMLP"; //volatile stocks string tickersString="LGCY,CDRB,RPRX,BCEI,SXE,UNXL,LEI,ARGS,ALIM,MCEP,AREX,CWEI,DRYS,GBSN,ORIG,SRPT,DNR,CBAY,DRWI,ECR,RLYP,NADL,EVEP,SKYS,VRNG,PTCT,ERN,CLF,RESN,WG,EPE,BAS,GLF,SDRL,PLG,VYGR,HCLP,ANFI,GST,LEU,GSL,RXII,MEP,FCSC,CHMA,DSX,EMES,TDW,GNCA,CCXI,VSLR,JONE,TTPH,CNXR,CRMD,CARA,SALT,GRAM,SN,CBMX,MEMP,FMSA,CPXX,TROV,ETE,CLVS,OVAS,ENPH,OMEX,NGL,TMST,CHK,CLMT,ORPN,WLL,SM,HBM,GOL,YRD,BBG,BPT,SGYP,UNT,CNAT,RXDX,CLD,VRX,ATW,RBPAA,GLBL,PES,CIE,TKAI,AMID,AVGR,HLX,SKY,SDLP,INAP,AEGR"; string[] tickers = tickersString.Split(new string[1] { "," }, StringSplitOptions.RemoveEmptyEntries); foreach (string ticker in tickers) { AddSecurity(SecurityType.Equity,ticker,resolution); } foreach (Security s in Securities.Values) { s.FeeModel=new CustomFeeModel(); atrs.Add(s.Symbol,ATR(s.Symbol,atrPeriod,MovingAverageType.Simple,resolution)); } } public void OnData(TradeBars data) { Buy(data); Sell(data); } public void Buy(TradeBars data) { CancelBuyOrders(); int quantity = 0; decimal minimumPurchase = 500m; decimal maxTrade; OrderTicket orderTicket; decimal buyPrice; decimal atrPercentage; foreach (TradeBar bar in data.Values) { if (Portfolio.Cash - SumBuyOrders(buyOrders,buyOrderPrices) < minimumPurchase) { break; } if (!Portfolio[bar.Symbol].HoldStock) { maxTrade = bar.Close * bar.Volume / ratioOfLastBarForMaxTrade; quantity =(int)Math.Floor(Math.Min(Portfolio.Cash-SumBuyOrders(buyOrders,buyOrderPrices), maxTrade) / bar.Close); if (quantity * bar.Close > minimumPurchase & quantity > 0) { atrPercentage=atrs[bar.Symbol] / bar.Close; if (atrPercentage > minimumAtrPercentage) { if (buyOrders.ContainsKey(bar.Symbol) == false) { buyPrice=bar.Low * (1-atrPercentage*atrMultiplier); orderTicket = LimitOrder(bar.Symbol, quantity,buyPrice); buyOrders.Add(bar.Symbol,orderTicket); buyOrderCounts.Add(bar.Symbol,0); buyOrderPrices.Add(bar.Symbol,buyPrice); } } } } } foreach (string key in buyOrderCounts.Keys.ToList()) { buyOrderCounts[key] = buyOrderCounts[key] + 1; } } public void Sell(TradeBars data) { CancelSellOrders(); decimal sellPrice; TradeBar bar; OrderTicket orderTicket; decimal atrPercentage; foreach (SecurityHolding stock in Portfolio.Values) { if (Portfolio[stock.Symbol].Quantity > 0 & data.ContainsKey(stock.Symbol)) { bar = data[stock.Symbol]; if (sellOrders.ContainsKey(stock.Symbol)==false) { atrPercentage=atrs[bar.Symbol] / bar.Close; sellPrice = bar.High * (1+atrPercentage*atrMultiplier); orderTicket = LimitOrder(stock.Symbol, -Portfolio[stock.Symbol].Quantity, sellPrice); sellOrders.Add(stock.Symbol,orderTicket); sellOrderCounts.Add(stock.Symbol,0); } } } foreach (string key in sellOrderCounts.Keys.ToList()) { sellOrderCounts[key] = sellOrderCounts[key] + 1; } } public void CancelBuyOrders() { string[] symbols=buyOrders.Keys.ToArray(); foreach (string symbol in symbols) { if (buyOrderCounts[symbol]>barsToHoldBuyOrdersFor) { buyOrders[symbol].Cancel(); buyOrders.Remove(symbol); buyOrderCounts.Remove(symbol); buyOrderPrices.Remove(symbol); } } symbols=buyOrders.Keys.ToArray(); foreach (string symbol in symbols) { if (buyOrders[symbol].Status == OrderStatus.Filled) { buyOrders.Remove(symbol); buyOrderCounts.Remove(symbol); buyOrderPrices.Remove(symbol); } } } public void CancelSellOrders() { string[] symbols=sellOrders.Keys.ToArray(); foreach (string symbol in symbols) { if (sellOrderCounts[symbol]>barsToHoldSellOrdersFor) { sellOrders[symbol].Cancel(); sellOrders.Remove(symbol); sellOrderCounts.Remove(symbol); } } symbols=sellOrders.Keys.ToArray(); foreach (string symbol in symbols) { if (sellOrders[symbol].Status == OrderStatus.Filled) { sellOrders.Remove(symbol); sellOrderCounts.Remove(symbol); } } } public static decimal SumBuyOrders(Dictionary<string,OrderTicket> buyOrders, Dictionary<string,decimal> buyOrderPrices) { decimal sum=0; foreach (string key in buyOrders.Keys.ToList()) { sum += buyOrders[key].Quantity * buyOrderPrices[key]; } return sum; } public override void OnEndOfAlgorithm() { Console.WriteLine("TotalProfit: {0}", Portfolio.TotalProfit); } } public class CustomFeeModel : IFeeModel { public decimal GetOrderFee(Security security, Order order) { var fee = order.AbsoluteQuantity*0.01m; if (fee<5) { fee=5; } if (fee>10) { fee=10; } return fee; } } }