You are using joins which creates cross product rows and therefore you are getting sum higher than expected try this with correlated subquery
SELECT
DISTINCT f.forecast_id,
(SELECT SUM(e.amount) FROM expense e WHERE e.forecast_id = f.forecast_id )
AS expense,
(SELECT SUM(i.amount) FROM income i WHERE i.forecast_id = f.forecast_id )
AS income
FROM
forecast f
WHERE
f.forecast_id = 721