Welcome! Hope this explanation helps.
Custom factors have dataset columns as their inputs. Examples of a dataset are USEquityPricing and Fundamentals. Examples of a dataset column are USEquityPricing.close and Fundamentals.cash_and_cash_equivalents. Really just attributes of a dataset. See the docs for a bit more explanation https://www.quantopian.com/help#importing-datasets .
So, to create a custom factor one needs to import the `CustomFactor' class as well as any of the datasets one wishes to use. Something like this.
# Imports needed to create and run pipeline
from quantopian.pipeline import Pipeline, CustomFactor
from quantopian.research import run_pipeline
# Import any pipeline data we want to use. These are most common.
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.data import Fundamentals # Morningstar
from quantopian.pipeline.data import factset # Factset
Next, create a subclass of CustomFactor as a new class. (see the docs https://www.quantopian.com/help#custom-factors)
class MyFactor(CustomFactor):
# assign any default input(s). not required but maybe convenient.
inputs = [Fundamentals.cash_and_cash_equivalents, USEquityPricing.close]
# assign a default window_length. again not required
window_length = 2
# factors can have multiple outs. if so, then give them names
outputs= ["cash_n_days_ago", "close_n_days_ago"]
def compute(self, today, asset_ids, out, cash, close):
# do any logic here
# the inputs appear in the same order as assigned above
# inputs are numpy arrays.
# columns are the assets. rows are the days with the earliest first [0] and most recent last [-1]
out.cash_n_days_ago[:] = cash[0]
out.close_n_days_ago[:] = close[0]
The above custom factor will return the 'cash_and_cash_equivalents' and the 'close' price from 2 days ago. It needs to be instantiated when defining the pipeline like this
my_factor = MyFactor()
cash_n_days_ago = my_factor.cash_n_days_ago
close_n_days_ago = my_factor.close_n_days_ago
This shows how a custom factor can have multiple outputs. Typically one would only have a single output. This is just to show how.
Often one doesn't need to write a custom factor especially for the fundamental data. Typically one just wants the latest value without doing any manipulation. A factor can simply be built directly from the dataset column by using the latest method.
current_cash = Fundamentals.cash_and_cash_equivalents.latest
Finally, there are currently a couple of sources for fundamental data - Morningstar and Factset. Both can be used together if desired. Take a look at the documentation for available fields
https://www.quantopian.com/docs/data-reference/overview
https://www.quantopian.com/docs/data-reference/factset_fundamentals
https://www.quantopian.com/docs/data-reference/morningstar_fundamentals
Attached is a notebook which shows a custom factor in action. It's a modification of the one used in this post https://www.quantopian.com/posts/change-in-fundamental-data-in-research
Hope that helps.