Overall Statistics |
Total Trades 541 Average Win 0.16% Average Loss -0.31% Compounding Annual Return 23.965% Drawdown 15.600% Expectancy -0.698 Net Profit 23.673% Sharpe Ratio 1.246 Loss Rate 80% Win Rate 20% Profit-Loss Ratio 0.51 Alpha 0.154 Beta 2.562 Annual Standard Deviation 0.159 Annual Variance 0.025 Information Ratio 1.138 Tracking Error 0.159 Treynor Ratio 0.078 Total Fees $541.00 |
from QuantConnect.Data.UniverseSelection import * import pandas as pd num = 275 use_fine_filter = 1 # Try 0. There are no orders, why? class BasicTemplateAlgorithm(QCAlgorithm): def Initialize(context): context.universe = [] context.SetCash(10000) context.SetStartDate(2017, 1, 3) context.SetEndDate (2017,12,31) context.UniverseSettings.Resolution = Resolution.Daily context.UniverseSettings.MinimumTimeInUniverse = 0 if use_fine_filter: context.AddUniverse(context.universe_filter_coarse, context.universe_filter_fine) else: # why does coarse alone fail with no orders? context.AddUniverse(context.universe_filter_coarse) context.Schedule.On( # Schedule the 'trade' method to run context.DateRules.EveryDay(), context.TimeRules.At(9, 30), Action(context.trade)) def universe_filter_fine(context, fine_data): # Only looking at price. Seems redundant since coarse does that. data_df = pd.DataFrame.from_records( [(float(s.Price),) for s in fine_data], index = [s.Symbol for s in fine_data], columns = ['prc'], coerce_float=True) #context.Log("data: {}".format((data_df.prc.values))) #context.Log("fine len: {}".format(len(data_df))) context.universe = data_df.index.tolist() return context.universe def universe_filter_coarse(context, coarse_data): columns = ['Price', 'HasFundamentalData'] data_df = pd.DataFrame.from_records( [[getattr(s, name) for name in columns] for s in coarse_data], index = [s.Symbol for s in coarse_data], columns = columns, coerce_float=True) data_df = data_df.query("(Price > .50) and (Price < 4.0) and HasFundamentalData").nsmallest(num, 'Price') context.Log('len {} prc min {} max {}'.format(len(data_df), data_df.Price.min(), data_df.Price.max())) #context.Log(data_df.sort_values(by='Price', ascending=False).head()) #context.Log(data_df.sort_values(by='Price', ascending=False).tail()) context.universe = data_df.index.tolist() return context.universe return context.universe.index.tolist() def trade(context): #for u in context.UniverseManager.Keys: # context.Log("universe name: {}".format(u)) #for u in context.UniverseManager.Values: # context.Log("universe count: {}".format(u.Members.Count)) if not len(context.universe): return cash = float(context.Portfolio.CashBook["USD"].Amount) if cash < 500: return cnt = 0 # count, to only log a few of them weight = 1.0 / len(context.universe) val = weight * cash context.Log('weight ' + '%.4f' % weight) context.Log(' {} '.format(cash)) for s in context.universe: if not context.Securities.ContainsKey(s): continue prc = float(context.Securities[s].Price) cb = float(context.Portfolio[s].AveragePrice) # cost basis i presume if cb: if cnt < 5: # only log a sampling of them cnt += 1 context.Log("{} cb {} prc {}".format(s, '%.2f' % cb, '%.2f' % prc)) if prc > 1.25 * cb: # close if up a lot context.Log(" close {} cb {} prc {}".format(s, '%.2f' % cb, '%.2f' % prc)) context.SetHoldings(s, 0) continue limit_prc = prc * .995 if limit_prc <= 0: continue quantity = int(val / limit_prc) if quantity < 1: continue context.LimitOrder(s, quantity, limit_prc)