Financials tearsheet challenge

The fourth tearsheet challenge is here and we're again mixing things up a bit. While we're back in more familiar US Equities waters, we will focus on the financials sector exclusively this time. In addition, this time we are looking for strategies with higher turnover - between 10% and 50% daily on average. Ideally your ideas will be unique and targeted to things that might work in financials, rather than generic factors that could also work across sectors.

There is also a questionnaire for all entrants that we would appreciate if you filled it out, but you do not have to.

Here are the rules:

• There is no submission or live-updated leaderboard like for the contest.
• To enter this challenge, simply post an alpha tearsheet as a reply to this thread. Clone the attached template and add your own pipeline factor code.
• The deadline to submit a factor is Dec 7, 2019. There is no hold-out testing, just post your best factor starting on June 1, 2015, until Oct 1, 2018. We will look at all tearsheet submissions and manually determine 5 best factors according to our discretion. Each winner gets a \$100 prize. There is no limit on the number of submissions.

Algorithm requirements to enter the challenge:

• Your factor must run on the US financials sector. It can however, use any dataset(s) you want.
• Turnover must be between 10% and 50%.

When selecting a winner, we will primarily look at:

• Specific Sharpe Ratio (IR) in the first 5 to 10 days in the alpha decay analysis (higher is better).
• For more examples on what we look for, check out our last live tearsheet review.

You can use the attached algorithm as a template.

Good luck and happy coding!

228
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
 Returns 1 Month 3 Month 6 Month 12 Month
 Alpha 1 Month 3 Month 6 Month 12 Month
 Beta 1 Month 3 Month 6 Month 12 Month
 Sharpe 1 Month 3 Month 6 Month 12 Month
 Sortino 1 Month 3 Month 6 Month 12 Month
 Volatility 1 Month 3 Month 6 Month 12 Month
 Max Drawdown 1 Month 3 Month 6 Month 12 Month
"""
Sample algo for using in the financials challenge

This template is based on an example algorithm from Daniel Cascio.
"""

# Import required pipeline methods
from quantopian.pipeline import Pipeline, CustomFactor
from quantopian.algorithm import attach_pipeline, pipeline_output

# Import any built in filters and/or factors
from quantopian.pipeline.domain import US_EQUITIES
from quantopian.pipeline.data.factset import RBICSFocus
from quantopian.pipeline.data import EquityPricing

# Import optimize
import quantopian.optimize as opt

import pandas as pd

def initialize(context):
# Normally a contest algo uses the default commission and slippage
# This is unique and only required for this 'mini-contest'

attach_pipeline(make_pipeline(context), 'pipeline')

# Place orders towards the end of each day
schedule_function(rebalance, date_rules.every_day(), time_rules.market_close(hours=2))

# Record any custom data at the end of each day
schedule_function(record_positions, date_rules.every_day(), time_rules.market_close())

class Momentum(CustomFactor):
inputs = [EquityPricing.close]
window_length = 252

def compute(self, today, assets, out, prices):
out[:] = ((prices[-21] - prices[-252]) / prices[-252] -
(prices[-1] - prices[-21]) / prices[-21])

def create_factor():
# Use the QTradableStocksUS universe as a base
sector = RBICSFocus.l1_name.latest
# Create an alpha factor
alpha_factor = Momentum()

# Filter out securities with very few estimates or factor is invalid
screen = qtu & ~alpha_factor.isnull() & alpha_factor.isfinite() & sector.eq('Finance')

return alpha_factor, screen

def make_pipeline(context):
alpha_factor, screen = create_factor()

# Winsorize to remove extreme outliers
alpha_winsorized = alpha_factor.winsorize(min_percentile=0.01,
max_percentile=0.99,

# Zscore to get long and short (positive and negative) alphas to use as weights
alpha_zscore = alpha_winsorized.zscore()

return Pipeline(columns={'alpha_factor': alpha_zscore},
screen=screen, domain=US_EQUITIES)

def rebalance(context, data):
# Get the alpha factor data from the pipeline output
output = pipeline_output('pipeline')
alpha_factor = output.alpha_factor

# Weight securities by their alpha factor
# Divide by the abs of total weight to create a leverage of 1
weights = alpha_factor / alpha_factor.abs().sum()

# Must use TargetWeights as an objective
order_optimal_portfolio(
objective=opt.TargetWeights(weights),
constraints=[],
)

def record_positions(context, data):
pos = pd.Series()
for position in context.portfolio.positions.values():
pos.loc[position.sid] = position.amount

pos /= pos.abs().sum()

# Show quantiles of the daily holdings distribution
# to show if weights are being squashed to equal weight
# or whether they have a nice range of sensitivity.
quantiles = pos.quantile([.05, .25, .5, .75, .95]) * 100
record(q05=quantiles[.05])
record(q25=quantiles[.25])
record(q50=quantiles[.5])
record(q75=quantiles[.75])
record(q95=quantiles[.95])
There was a runtime error.
Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

87 responses

Hi @Thomas,

I'm curious to understand the rationale behind the higher turnover preference for stocks in the Financial sector? Is this a general new preference (to make more active bets that can be more accurately determined to be profitable OOS), or only in relation to the Financial sector?

Also, what was the reason why you used a Momentum factor in the template? Was it mainly because it has a higher turnover, or because Financials might use different Fundamental based factors (e.g. due to their bigger balance sheet) than stocks in other sectors?

Lastly, in the template, you're using l1_name (Economy) rather than l2_name (Sector), and it looks like "Finance" at l1 level includes Morningstar's Real Estate stocks in addition to (Morningstar) Financial Services stocks. Was this intentional?

Thanks!

FYI, here's the new tearsheet of the above template, without any changes made. Note the exposure to Real Estate in addition to Financial Services.

I'm assuming this is the tearsheet we should be attaching, unless there's an updated/improved one?

49

My initial model 0.1. Average daily turnover during this period was 12%. I can't quite understand the minimum turnover requirement of 10%, as trading is expensive, but I'm probably missing something. Perhaps the combined model will result in lower overall turnover due to internally matched 'wash-trades' that are never sent to the broker/exchange?

11

@Joakim: Thanks for all the great questions!

I'm curious to understand the rationale behind the higher turnover preference for stocks in the Financial sector? Is this a general new preference (to make more active bets that can be more accurately determined to be profitable OOS), or only in relation to the Financial sector?

Not a general new preference, but this challenges are a great playground for us (and you) to explore different avenues. For some portfolios you might want to be more active in your trading because you maybe you found that factors that actively turn over has been working well for you in the past. For example, if you signal is only predictive over shorter time horizons, why would you want to sit on old positions that do not have predictive power anymore?
It's not something specific to financials.

Also, what was the reason why you used a Momentum factor in the template? Was it mainly because it has a higher turnover, or because Financials might use different Fundamental based factors (e.g. due to their bigger balance sheet) than stocks in other sectors?

It's rather mundane, I had this factor lying around and just put it in as a place-holder. Maybe an example that actually looks a bit better would be more motivating but I was lazy :). So this shouldn't be taken as a hint or prescriptive in any way. The only thing it shows maybe is that this momentum factor does not work well here.

Lastly, in the template, you're using l1_name (Economy) rather than l2_name (Sector), and it looks like "Finance" at l1 level includes Morningstar's Real Estate stocks in addition to (Morningstar) Financial Services stocks. Was this intentional?

Yeah, the naming is a bit confusing here. We do mean economy here so it's fine if others are pulled in that morning star considers belonging to a different sector. The main idea here is to do something more targeted, what that specific target is secondary, so no need to read too much into it. If, however, you find that your idea would only make sense on actual financial services but not real estate stocks, feel free to exclude those from your universe.

I'm assuming this is the tearsheet we should be attaching, unless there's an updated/improved one?

Yes, that's exactly the right one, thanks for posting it.

Would the accepted Algo be funded?

@Leo C: That's never a guarantee, even for winning factors, but in this competition it is definitely more likely than in the Japan one.

v0.1

5

We can use Morningstar's Financial and Real Estate sectors combined or just Morningstar's Financial?

@Leo C: The example uses RBICS from FactSet which you should use, is there a reason you would like to use Morningstar?

v0.2

2

Are custom datasets allowed for this challenge?

@Robert: Yes, definitely!

v0.2

6

Model 01

5

v1

1

Here's my 1st submission of an individual factor specific to Financials. Need to work on it a bit more but I thought the exposures and IR decay were good.

0

Turnover 10.0 %. IR is steady for 5 days, then drops.

1

v1.0 - Average Daily Turnover: 19.10%

1

v2.0 - Average Daily Turnover: 27.81%

3

Still needs some improvement, excited to work on it over the break!

1

Everyone: To give people a bit more breathing room we extended the deadline for this challenge to Dec 7.

Quo prodis

1

Est

1

2

1

Finding a model specific to the sector and inclusive of all financial industries is a great challenge. In 8 years trying quant value models on paper and in real, I often came to exclude financials of the universe. My suggestion to participants is to explicitely or implicitely focus on subsets and exclude some industries. Hope this helps and best of luck, I am out...

My 1st attmpts

0

Maybe this can help? I am too lazy to derive these ratios in quantopian.

First submission using general factors

0

Another algorithm using several different factors

0

Same factors as second algorithm but a different group ranking method

1

version F - a set of factors

2

version T

0

version F5T5

2

version F7T3

0

Model 02

0

Model 03

1

v1

1

v3.0 - Average Daily Turnover: 15.54%

0

Using both fundamental and estimate factors

0

Submission #2. Very fast through 1-6 days but thought I would send it in anyways.

1

Version 2.2
Average turnover is 10.3%

0

Version 3.2 added one factor to reduce turnover

0

V2

1

Submission #3.

0

V3.
Turnover keeps on going down as I add more factors. Average Turnover: 12.8%.

1

First crack after a long break from the platform...

0

V4
Average Turnover: 10.8 %. (V3 was combination of V4 + general factors)

0

Submission #4 with AVG Turnover @ 12.5%

0

Final Submission #5 (same factors as V4 above) only change made was to increase AVG Turnover @ 24.5%

0

v4.0 - Average Daily Turnover: 11.69%

1

v4.1 - Average Daily Turnover: 11.65%

0

0

Hi, version 1.0 - average daily turnover 10.28%. Cheers!

0

V 1.0 with 32.81% turnover

0

Attemp #1

I find the "Turnover must be between 10% and 50%" a little bit problematic. I think this is forcing the trading strategy to tile to technical side as fundamental data does not update that frequently and naturally gives a low turnover. My factors relies on more the fundamental side.

0

Attemp #2

0

Attempt #3

(I do not really like this one better than the other two... But it has more positions.)

0

v4.2 - Average Daily Turnover: 11.39%

That's the best I can do. Fingers crossed it'll hold up reasonably well during the holdout period (I haven't peeked).

1

Attempt #4

0

Attempt #5

0

Attempt #6

0

My final version for this challenge. I added more factors and even though it has lower IR in the challenge period than my previous submissions, I think this version works better over a longer horizon. Going to delete my previous submissions to avoid clutter.

0

finance factor1

0

financials-tearsheet-challenge

0

V5 (Combination of top factors) with higher average turnover of 15.5% (but reduced IR).

0

V 2.0 with 38.09% turnover

0

Updated

2

Daily turnover 32.3%

0

Daily turnover 11.8%
One of the factors in this one is only active every 10 days, hence the spikes.

0

MultiFactors-ML - Daily turnover 17.2%

0

V2-MultiFactors-ML - Daily turnover 14.9%

0

V1

0

V3 - MultiFactors-ML -Daily turnover 13.3%

1

I know it's late but I'll throw this in there.

0

50 % turnover, Sharpe, 1.26

0

Check this out.
This is simply for entertainment purposes and I would not trade this algorithm at the moment. The contest did not include an out of sample period, and I believe a number of solutions are overfit. I wanted to see how far this could be taken, so here we are.

I'd be happy to talk about how I did this, but please do not get mad if I don't share all my code.

3

@Peter Harrington, wow! That's some insanely high Alpha! What's the average daily turnover? Which dataset(s) did you use primarily? Are you able to increase the number of holdings at all? Are you using limit orders with stop-loss and profit targets?

@Peter Harrington glad I did not bother to enter this competition!!

This is my first post on Quantopian...

i am currently reading "Finding Alphas" by Igor Tulchinsky, and he use an anology in the book comparing alpha researching to treasure hunting and so when i re-read the "Good luck and happy coding!" i thought would be more exciting if it read instead "Good luck and happy hunting!".

what you guys think?

Btw, that is a great book.. i recomend it!

"Good luck and happy hunting!"

Thanks for that line, I do like that better actually.

@Joakim Arvidsson I used the FactSet Insider Purchases dataset, I feel this dataset could be improved. Right now Quantopian dumbs down the dataset and throws out potentially useful information. Another piece of data I was using was the FactSet Altman-Z score, this is only computed for ~70 tickers in the Financial dataset which is why my number of holdings is reduced. I have computed Ohlson's O-score (an improved safety score) using Morningstar fundamentals but I was too lazy to add that, doing so would have allowed me to use all ~520 tickers from the Financial dataset.

I didn't do anything different with the order types, or use a profit target. It would be interesting to see if a profit target for each equity is more effective than a fixed rebalance date.

Thanks @Peter, super impressive!!

@Peter Harrington do you think overfit will show up in the total IR being significantly higher than specific IR

@Peter,
Usually I use the analogy an old friend once told me...if it looks like a duck, walks like a duck, and quacks like a duck...then it must be a duck!

So when I see a sophisticated simulator(zipline) produce outsized returns, then I think:
...mis-use of simulator (look-ahead bias, data problems, bugs of various nasty sorts), which I have done many times.

Now, that may not be the case in this case, yet I can't tell without doing massive testing, including line-by-line debugging.
Anyway, thanks for spicing this thread up...and I'm still using your alpha-compiler...so thanks for that also!

alan

Thanks everyone for submitting to the challenge. Here are the ranked winners as announced in the live webinar:

1. Joakim Arvidsson (Cream Mongoose)
2. Shiv Chawla
3. Indigo Monkey
4. Leo M
5. Leo c

The prize for best OOS performance goes to: Vasilis Nikolaou

Hi @Thomas,

Great webinar, as always.

I forgot to ask (and I don’t think you mentioned) about possibility of any of these getting funded. Though since most entries didn’t seem to perform as well on the holdout period, I could definitely understand if you need to collect more live performance data in order to assess likelihood of models being overfit or not. More colour on this would be greatly appreciated.

As a first timer, I was looking for the New Comer prize, but surprise, there was no New Comer price this time...

anyway, financial sector is tough as many sub-sectors behave totally differently, such as RE vs insurance vs Bank...