' Helper function.
subroutine local create_decile_reference(scalar n, vector ref)
	vector(2 * n) ref
	ref(1) = @ceil(10 / n)
	ref(2) = 1
	for !i = 2 to n
		!decile = @ceil(10 * !i / n)
		ref(2 * !i - 1) = @ceil(10 * !i / n)
		if ref(2 * !i - 1) = ref(2 * !i - 3) then
			ref(2 * !i) = ref(2 * !i - 2) + 1
		else
			ref(2 * !i) = 1
		endif
	next
endsub

' The first half of this program creates a matrix, m, that holds the stock indices (into the *_group structures) for all deciles.  Since there is missing cumulative return data, the number of "active" indices per month (row of m) varies.  A vector, active, tracks this information.  For row i of m, the first active(i) columns hold meaningful stock indices.  Those indices are ordered by decending cumulative return.

' Move to the page with cr_group.
pageselect 6mRet
' A temporary holding the cannonical index ordering, e.g., 1..200.
rowvector(cr_group.@count) inc
for !i = 1 to inc.@cols
	inc(!i) = !i
next
' Convert all data to a matrix so we may grab individual rows as vectors.
matrix tmp
stomna(cr_group, tmp)
' Results matrix.
matrix(tmp.@rows, tmp.@cols) m
' We'll record all the dates on the Monthly page so we can refer to them on the Daily page.
svector(tmp.@rows) dates
' Track the number of non-missing columns per row (month)
series _active = @robs(cr_group)
vector active
stom(_active, active)
delete _active
for !i = 1 to tmp.@rows
	' For every month, sort the stock indices by decending the cumulative return.
	rowplace(m, @rapplyranks(inc, @ranks(@rowextract(tmp, !i), "d", "r")), !i)
	' Record the month.
	dates(!i) = @otod(!i)
next


' The second half of the program uses the above data to fill out the portfolio data.


' Move the generated data to the Daily page and clean up temporaries.
copy m dRet\m
copy dates dRet\dates
copy active dRet\active
delete inc tmp m dates active
' Move to the page with dr_group and mv_group.
pageselect dRet
' Create the portfolio structures.
' First, generate the various indices for the portfolio series.
vector ref
call create_decile_reference(dr_group.@count, ref)
' Then create the series.
for !i = 1 to @rows(ref) / 2
	%tmp1 = @str(ref(2 * !i - 1), "i02")
	%tmp2 = @str(ref(2 * !i), "i02")
	series p_{%tmp1}_{%tmp2}
next
' And then group them.
group portfolio_all
for !i = 1 to 10
	%tmp = @str(!i, "i02")
	group portfolio!i p_{%tmp}_*
	portfolio_all.add portfolio!i
next
' Copy the series slices into the portfolios.
for !i = 1 to @rows(dates)
	if active(!i) > 0 then
		' Use the monthly dates to create a daily sample.
		%tmp = dates(!i)
		smpl if @event(%tmp)
		' Generate the indices of the portfolios we'll be copying to.
		call create_decile_reference(active(!i), ref)
		for !j = 1 to active(!i)
			' For each month, copy each selected stock's DR * MV to the portfolio.
			%tmp1 = @str(ref(2 * (active(!i) - !j + 1) - 1), "i02")
			%tmp2 = @str(ref(2 * (active(!i) - !j + 1)), "i02")
			p_{%tmp1}_{%tmp2} = dr_group(m(!i, !j))' * mv_group(m(!i, !j))
		next
	endif
next
' Clean up temporaries.
delete m dates active ref
smpl @all
' Move the portfolio infomation to its own page.
copy p* Portfolios\
delete p*


