<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def factor_returns(factor_data, demeaned=True, group_adjust=False, equal_weight=False, by_asset=False):
 """ Computes period wise returns for portfolio weighted by factor values. Parameters factor_data : pd.DataFrame - MultiIndex A MultiIndex DataFrame indexed by date (level 0) and asset (level 1), containing the values for a single alpha factor, forward returns for each period, the factor quantile/bin that factor value belongs to, and (optionally) the group the asset belongs to. - See full explanation in utils.get_clean_factor_and_forward_returns demeaned : bool Control how to build factor weights -- see performance.factor_weights for a full explanation group_adjust : bool Control how to build factor weights -- see performance.factor_weights for a full explanation equal_weight : bool, optional Control how to build factor weights -- see performance.factor_weights for a full explanation by_asset: bool, optional If True, returns are reported separately for each esset. Returns ------- returns : pd.DataFrame Period wise factor returns """


    weights = \
        factor_weights(factor_data, demeaned, group_adjust, equal_weight)

    weighted_returns = \
        factor_data[utils.get_forward_returns_columns(factor_data.columns)] \
        .multiply(weights, axis=0)

    if by_asset:
        returns = weighted_returns
    else:
        returns = weighted_returns.groupby(level='date').sum()

    return returns