| 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)