There are a lot of people who do not know and I can see that is the case here so I will answer instead. Good question.
The query section populates the dataframe with the particular values.
Since those values are not being used, there's no need to collect them.
That's the case in a lot of algorithms.
When the values are not being used, just leave query empty like this:
fundamental_df = get_fundamentals(
query()
.filter(fundamentals.valuation.market_cap > 0)
.filter(fundamentals.operation_ratios.roic > 0.1)
.filter(fundamentals.valuation.shares_outstanding != None)
.order_by(fundamentals.operation_ratios.revenue_growth.desc())
.limit(num_stocks)
)
To see that, try as is, with a breakpoint on line 88 (in the algo above), and type fundamental_df in the debugger console window (hit [Enter]).
Then make that just query() and repeat.
Maybe someone here or from Q can round that out with some finer points in exploring pandas dataframes (technically a panel in this case, although also a dataframe, I think, a single dataframe inside a panel, there could be more than one unless I'm mistaken, something like that).
Query and filters can be entirely different from each other.
This is an example of combining a couple of dataframes (or panels), using the values from query, and assembling a score from those values.
c = context
f = fundamentals
panel1 = get_fundamentals(
query(
f.cash_flow_statement.cash_flow_from_continuing_operating_activities,
f.operation_ratios.roa,
f.cash_flow_statement.operating_cash_flow,
f.valuation_ratios.ev_to_ebitda,
f.operation_ratios.current_ratio,
f.valuation_ratios.pb_ratio,
#f.valuation_ratios.pe_ratio,
)
.filter(f.share_class_reference.is_primary_share == True)
.filter(f.share_class_reference.is_depositary_receipt == False)
.filter(f.operation_ratios.roa > .002)
.filter(f.valuation.market_cap > 3000e6)
.filter(f.cash_flow_statement.cash_flow_from_continuing_operating_activities > 0)
.order_by(f.valuation.market_cap.desc())
.limit(120) # 30-40.6 80-36.7 300-29.1
)
panel = panel1
'''
# Use to add some manually
panel2 = get_fundamentals( # Fundamentals for specific symbols
query(
f.cash_flow_statement.cash_flow_from_continuing_operating_activities,
f.operation_ratios.roa,
f.cash_flow_statement.operating_cash_flow,
f.valuation_ratios.ev_to_ebitda,
f.operation_ratios.current_ratio,
f.valuation_ratios.pb_ratio,
)
.filter(f.company_reference.primary_symbol.in_(['TSLA']))
#.filter(f.company_reference.primary_symbol.in_(['ENLK', 'PKD', 'TSLA', 'NNBR', 'OWW']))
)
panel = panel1.append(panel2) # creates dupes
panel = panel.groupby(panel.index).sum() # dedupe
'''
# Normalize the values 0 to 100 in relation to each other
for i in range(len(panel)): # 0 and 1 for two elements in query above, they are indexes
value_list = panel.iloc[i, :].values
top = max(value_list)
bottom = min(value_list)
count = 0
for v in value_list: # each value across all stocks
prcnt = 100 * (v - bottom) / (top - bottom) # where this value sits, percentage
panel[panel.columns[count]][i] = prcnt
count += 1
c.fstocks = []
for s in panel.columns.values:
if s.symbol in c.excludes: continue
if '_' in s.symbol: continue
c.fstocks.append(s)
# panel[s][1] is operation_ratios.roa
# Try multiplying these also, instead of adding them
score = panel[s][0] + panel[s][1] + panel[s][2] + panel[s][3] + panel[s][4] - panel[s][5]
if np.isnan(score):
c.fscore[s] = 0
else:
c.fscore[s] = score
update_universe( c.fstocks )