Well, I'm trying to do that... the code above iterate over the last 252 day (a trading year) and store the value on each change or when there isn't any change for more than 70 days (meaning the value in the current quarter is the same as in the previous one).
The problem is than the loop takes too long for Quantopian and a timeout occurs.
I cannot yet figure how to overcome this issue and hope in the help of the community.
I attach now the full algo again because I fear the source code wasn't available in my previous post:
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline import CustomFactor
from quantopian.pipeline.data import morningstar
import numpy as np
days_in_quarter = 70
NA = object()
def retrieve_ttm(column):
ttm = []
i = 0
j = 0
ttm.append(column[i])
for previous, current in zip(column, column[1:]):
i += 1
if np.isnan(previous):
previous = NA
if np.isnan(current):
current = NA
if previous != current:
if i - j > days_in_quarter:
ttm.append(column[j])
ttm.append(column[i])
j = i
if len(ttm) < 4:
ttm.append(column[i])
return ttm[-4:]
class RevenueTTM(CustomFactor):
inputs = [morningstar.income_statement.total_revenue]
window_length = 252
def compute(self, today, assets, out, revenue):
out_list = []
for i in range(revenue.shape[1]):
column = revenue[:,i]
ttm = retrieve_ttm(column)
out_list.append(ttm)
all_revenues = np.transpose(np.array(out_list))
revenue_ttm = np.sum(all_revenues, axis=0)
out[:] = revenue_ttm[0]
def initialize(context):
# Create the pipe
pipe = Pipeline()
attach_pipeline(pipe, 'Revenue-TTM-Example')
revenue_ttm = RevenueTTM()
pipe.add(revenue_ttm, 'revenue_ttm')
# Create and apply a filter representing
revenue_ttm_top_100 = revenue_ttm.top(100)
pipe.set_screen(revenue_ttm_top_100)
def before_trading_start(context, data):
context.output = pipeline_output('Revenue-TTM-Example').sort(['revenue_ttm'], ascending=False)
update_universe(context.output.index)
def handle_data(context, data):
print "SECURITY LIST"
log.info("\n" + str(context.output))