How to return a set of rows from this function?
Your query returns two columns (one integer, one float), but the function is defined as returning a table with a single varchar column.

You need to change your function definition to:

RETURNS table(maturity integer, avg_implied numeric) 


to match the query result. 

returns setof and returns table are the same thing but returns table lets you define names for each column in the result.



You also don't need PL/pgSQL for this, a simple SQL function will do just fine:

CREATE OR REPLACE FUNCTION generate_term_structure_by_moneyness(arg_ticker text
                                  ,arg_date integer
                                  ,arg_underlying float
                                  ,arg_lower float
                                  ,arg_higher  float)
  RETURNS table(maturity integer, avg_implied numeric) 
$BODY$
    select maturity,avg(Implied) 
    from options.options 
    where ticker=arg_ticker 
      and date=arg_date 
      and strike/arg_underlying &gt; arg_lower 
      and strike/arg_underlying &lt; arg_higher 
    group by maturity 
    order by maturity asc;
$BODY$ 
LANGUAGE sql;




You probably also want to re-think the usage of the approximate data type double:
http://floating-point-gui.de/



date is a horrible name for a column. For one because it is also a keyword, but more importantly it doesn't document the column's content. Is that a "start date"? An "end date"? A "due date"? A "registration date"? A "change date"? A "creation date"? And even more so if you don't actually store a date in that column but an integer value. What kind of date is the value 42 supposed to be?