Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Fun PARTY development - FactSet Fundamentals

Still going through the many great FactSet Fundamentals data fields, but here's my first attempt. It's exclusively using FactSet Fundamental data, and I've tried not to use too many fields that are similar to Morningstar fields (some overlap of course).

It doesn't quite meet the daily turnover requirement (just below 5%) so I can't submit it to the contest yet (maybe I need to add a bit of noise to it to bring up turnover? ;)).

Any and all feedback appreciated! I'd like to run it from early 2007 to see how it did during the GFC, but get the below error. Any help on how to fix this also appreciated.

There was a runtime error. ValueError:NaN or Inf values provided to
FactorExposure for argument 'loadings'. Rows/Columns with NaNs:
row=Equity(32620 [PFF]) col='momentum' row=Equity(32620 [PFF])
col='short_term_reversal' row=Equity(32620 [PFF]) col='size'
row=Equity(32620 [PFF]) col='value' row=Equity(32620 [PFF])
col='volatility' Rows/Columns with Infs: None Line: 287 inrebalance
max_volatility=MAX_STYLE_EXPOSURE,

11 responses

I am hitting the 5% constraint as well in a new algorithm, so I could not submit it to the contest. Maybe they need to allow it go under 5% a greater percentage of time than it is now (2%). There are some spots like end of Decembers where there is no company that is scheduling earnings reports, so no new data to work with.

I would go even further and suggest that perhaps this 'turnover floor' needs to be lowered to 4%, 3%, or even lower. I think it would be a good practise to regularly review (every 6 months perhaps) and reassess all the constraint parameters, and adjust them as needed. Most appear to be set quite appropriately already (in my view anyway) but for this one, I don't quite see the cost/benefit of keeping it at 5% and not lower.

Similarly, I think the Volatility floor of 2% could be lowered as well, perhaps to 1%, though this one may be more tricky as it's so important in the 'score' calculation (and one could fairly easily 'spoof' historical volatility to artificially inflate one's score early on in the contest). If I increase position concentration it brings up both average daily turnover and volatility, but it lowers sharpe quite significantly (for this one anyway), and lower concentration levels is preferred I think for an allocation, so a bit conflicting it seems.

In short, I think it may be time to review/reassess the appropriateness of some of the constraint levels, to even further align the contest incentives with desired allocation strategies.

Just my opinion... :)

I agree Joakim with what you said. I understand it is not easy to design a contest that satisfies everyone's needs, but in this case I feel there can be more viable fundamental strategies that satisfy the contest if the numbers are lowered.

Thanks Leo! I honestly don't know what the right levels are; I think they are in a much better position to decide that. All I'm suggesting is for Q to (somewhat regularly) review and reassess if the imposed levels are still valid, appropriate, and not conflicting with their allocation aspirations.

Take this strategy for example. I'm fairly confident this is a) a decent strategy, and b) aligned with their allocation preferences. However, I can't submit it to the contest due to it not meeting the >5% daily average turnover requirement. Even if I could, it would then be 'penalized' (unfairly in my opinion) by the imposed 2% volatility floor.

So, if I want to submit it to the contest, I'm effectively 'forced' to increase position concentration levels to bring up both turnover and volatility, which brings down the sharpe ratio quite a bit (all four of which are 'bad' from an allocation perspective).

Attaching screenshots to hopefully help prove my point :)

Hi Joakim, Leo M,

I also agree with all your observations and assessments with regards to turnover and volatility. In fact, most of the algos I've been working on lately behaves exactly as Joakim describes it.

+1 for review of constraints

Turnover constraint violated

This is the image of the turnover constraint being violated on the 2% outlier guard onthe 5% lower limit, every other check passes.

Thanks guys! Glad I'm not the only one with this dilemma.

Why is there a need for a lower bound for turnover I asked myself, and found:

Why Is It Required?
The lower bound of 5% exists because algorithms
that place trades (“bets”) less frequently need more time for their
performance to be evaluated. The more frequently an algorithm trades,
the sooner an algorithm accumulates a larger number of out-of-sample
trades. The lower bound on turnover requires algorithms to make active
decisions.

Fair enough, but I still think 5% is too high, counterproductive to creating allocation strategies, and possibly should be adjusted.

Regarding the 2% volatility floor, perhaps this could be removed (or at least lowered to 1%) for contest entries that have been running live for >63 days?

Just thinking out-loud... :)

Joakim, I agree with everything you have said in this thread. Just from numerical face value I believe there shouldn't be a whole lot of difference between a 5% turnover and 4% turnover strategies maybe 20% more out of sample period?

Here's a tear sheet of my Fun PARTY algo (Fun-damentals Pure Alpha Risk pariTY :)), which is currently running (1 day) in the contest. It's exclusively using FactSet's Fundamentals, and is a 'Quality, Value, Growth' based strategy.

The 'live_start_date' is not the 'true' live start date of course, but just the start of the 'hold out' period that I didn't have access to when I developed the model. I think there's quite a bit of 'luck factor' involved here, but at least it doesn't look too overfit? The bayesian cone I believe is based on just the first year, so may not be that accurate? At least that's what I'm trying to convince myself is the reason why the red line is above and outside of the cone... Thoughts?

It's a bit too concentrated than I would have liked, but I don't want to be too penalized by the 'volatility floor' of 2%, or risk being withdrawn due to 'daily average turnover' dipping below 5%.

Feedback anyone? I'd especially like to hear what you don't like about the strategy.

Hey Joakim,

As I already said in the other thread, looks like a winner, at least in my opinion. With regards to "luck factor" on 1 year OOS, you'll have to go further back into your insample backtest to make a more meaningful assessment. The other thing to consider is when the 1 year holdout data (OOS) is tagged with a "live start date", does it simulate "live trading" and throws out slippage costs? If that is the case, it could partly explain the better than normal outcome.

As for concentration / turnover issues, I would'nt worry too much on these. The way I look at it, your parameter adjustment on concentration (0.16% or 600 stocks) is just tuned for optimal results given contest contraints. It is what it is!

Good lucky, buddy! Have a sip of mojitos at the beach, relax!

Hey MAGIC,

Thanks - appreciated! I wanted to know what you DON'T like about it though... ;)

Regarding your question about my opinion on FactSet vs Morningstar Fundamentals, I think FactSet is really really good! A lot easier to understand and work with, and lot's more relevant ratios and fields from companies financial statements. The documentation is much better too which is great, and the fields better labled (qf, af, saf, etc). In short, much easier to research and discover alpha, and lot's more factors to be discovered in FactSet (plenty enough for everyone I reckon... :))

Thanks to @Cal, I'm now able to run earlier backtest, but unfortunately now I'm running into 'memory issues' (kernel restarting) when trying to generate a Pyfolio tear sheet. Here's a tear sheet of this algo from early 2005-2016 that mostly finished (the risk tear sheet didn't complete, but should be very similar). Notice the VERY long (though not that deep, about 4%) drawdown period from early 2009 (late 2008 even) to mid 2011. That's quite a long time if it was running live with real money. It also would have been withdrawn from the Q Contest early 2011 had it been running then...

JFYI, here's the code to filter out the NaNs from the Risk Pipeline in before_trading_start, if anyone else has the same problem:

    context.risk_loadings = algo.pipeline_output('risk_factors')  
    context.risk_loadings.dropna(inplace=True)  

Next I'm working on a 'Fun & Trendy MARTY', as well as a 'Mean & Trendy MARTY' algo. :) My hope is that if my 'strategic intent' is different enough, and if I'm mostly using different data fields / factors, these new strategies should be (hopefully) uncorrelated with my current strategies (I may test the correlation of their return streams too at some point).

Cheers,
MARTY