The solution depends how you actually want to handle missing values, is the previous or the next value taken from each 5 minutes and so on.
But some kind of idea could be to generate datetime values first and then try fetching the next stock value in time. So something like
create table stockdata (
id int ,
updatetime datetime,
price float
);
insert into stockdata values ( 5, '2015-07-17T09:02:00.000', 65.5);
insert into stockdata values ( 5, '2015-07-17T09:03:00.000', 65.5);
insert into stockdata values ( 5, '2015-07-17T09:05:00.000', 65.5);
insert into stockdata values ( 5, '2015-07-17T09:06:00.000', 66);
insert into stockdata values ( 5, '2015-07-17T09:07:00.000', 66);
insert into stockdata values ( 5, '2015-07-17T09:08:00.000', 66);
insert into stockdata values ( 5, '2015-07-17T09:16:00.000', 66.5);
insert into stockdata values ( 5, '2015-07-17T09:17:00.000', 66.3);
insert into stockdata values ( 5, '2015-07-17T09:18:00.000', 66.25);
insert into stockdata values ( 5, '2015-07-17T09:19:00.000', 66.3);
declare @startdate datetime = convert(datetime, '2015-07-17T09:00:00.000', 126)
declare @enddate datetime = convert(datetime, '2015-07-17T10:00:00.000', 126)
;with minutes5 as (
select @startdate DateAndTime
union all
select dateadd(minute, 5, minutes5.DateAndTime) DateAndTime
from minutes5
where DateAndTime <= @enddate
)
select *
from minutes5 m, stockdata sd
where sd.updatetime >= m.DateAndTime
and sd.updatetime = (select min(sd2.updatetime)
from stockdata sd2
where sd2.updatetime >= m.DateAndTime
and sd2.updatetime < dateadd(minute, 5, m.DateAndTime))