def update_position_avg_price_2way(cma_price, position_qty, trade_action, trade_direction, trade_price, trade_qty):
    """
    Update position quantity and calculate average prices with a new trade.
    Long/short positions are updated together, i.e. sell long == buy short.
    Moving average price of current position is only updated when the position direction flips.
    :param cma_price: Cumulative moving average prices of current position, either long or short.
    :param position_qty: Position qty. Positive: long, negative: short.
    :param trade_action: 0 - buy, 1 - sell
    :param trade_direction: 0 - long, 1 -short
    :param trade_price: float
    :param trade_qty: int
    :return: int, float, float. New position qty, average price and realized gain.

    **Note**: Returned realized gain is not scaled with contract unit.
    """
    if trade_action != trade_direction:  # short
        trade_qty *= -1
    position_qty_new = position_qty + trade_qty

    if position_qty_new == 0:
        cma_price_new = 0.0
    elif position_qty == 0 or (position_qty > 0) != (position_qty_new > 0):
        cma_price_new = float(trade_price)
    elif (position_qty > 0) == (trade_qty > 0):
        cma_price_new = float(cma_price * position_qty + trade_price * trade_qty) / position_qty_new
    else:
        cma_price_new = cma_price

    if position_qty != 0 and ((position_qty > 0) != (trade_qty > 0)):
        realized_gain = (trade_price - cma_price) * (
            2 * int(position_qty > 0) - 1) * min(abs(position_qty), abs(trade_qty))
    else:
        realized_gain = 0

    return cma_price_new, position_qty_new, realized_gain