Example #1
0
def add_to_position(session, raw, pos):
    # find opening commission transaction
    logger.debug("Adding raw trade %d to position %d for  %s", raw.id, pos.id, raw.broker_ref)
    comm = get_comm_for_position(session, raw.ref_date, raw.broker_ref)
    if len(comm) > 1:
        logger.info("%d commissions found for multi-tranche %s", len(comm), raw.broker_ref)
    pos.num_closes += 1
    pos.entry_quantity += raw.size

    c_open = None
    c_close = None

    if len(comm) > 0:
        c_close = comm[-1]
        pos.brokerage += c_close.amount
        logger.debug("Using commission %d for ANOTHER close of %s", c_close.id, raw.broker_ref)
        if c_close.ref_date != raw.ref_date:
            logger.error("CLOSING COMMISSION DATE MISMATCH on %d for close of %s", c_close.id, raw.broker_ref)
        # TODO: Handle/Check for more than 2 commissions?  Check dates??
        # Closing commission should be on same date as closing trade.

    a_close = StockActivity(ActionType.CLOSE, raw=raw, comm=c_close)

    # Update quantity in first open activity.
    # The underlying logic only works if there is only one open, but multiple closes.
    a_open = get_position_activities(session, pos, True)
    a_open.quantity += raw.size

    trade = StockTrade(a_open, a_close, raw)

    session.add(trade)
    session.add(a_close)
    session.commit()

    if c_close:
        c_close.position_id = pos.id
        c_close.activity_id = a_close.id
    a_close.position_id = pos.id
    a_close.trade_id = trade.id
Example #2
0
def new_position(session, raw):
    # find opening commission transaction
    logger.debug("Creating new position for %s", raw.broker_ref)
    q = session.query(RawData).filter(
        RawData.category == RawData.CAT_RISK,
        RawData.ref_date <= raw.ref_date,
        RawData.description.like("%" + raw.broker_ref + "%"),
    )
    other_fees = q.all()
    total_other_fees = D(0)
    if len(other_fees):
        for fee in other_fees:
            total_other_fees += fee.amount
        logger.debug("Total of %d other fees for %s: %s", len(other_fees), raw.broker_ref, total_other_fees)
    comm = get_comm_for_position(session, raw.ref_date, raw.broker_ref)
    if len(comm) == 2:
        logger.debug("%d commissions found for %s", len(comm), raw.broker_ref)
    else:
        logger.warn("FOUND %d COMMISSIONS FOR %s (%s)", len(comm), raw.broker_ref, raw.description)

    pos = StockPosition(raw.description, raw.description, raw.ref_date)
    pos.broker_ref = raw.broker_ref
    pos.num_opens += 1
    pos.num_closes += 1
    pos.entry_quantity += raw.size
    pos.fees += total_other_fees

    c_open = None
    c_close = None

    if len(comm) > 0:
        c_open = comm[0]
        pos.brokerage += c_open.amount
        logger.debug("Using commission %d for open of %s", c_open.id, raw.broker_ref)
        if len(comm) > 1:
            c_close = comm[1]
            pos.brokerage += c_close.amount
            logger.debug("Using commission %d for close of %s", c_close.id, raw.broker_ref)
            if c_close.ref_date != raw.ref_date:
                logger.error("CLOSING COMMISSION DATE MISMATCH on %d for close of %s", c_close.id, raw.broker_ref)
        # TODO: Handle/Check for more than 2 commissions?  Check dates??
        # Closing commission should be on same date as closing trade.

    a_open = StockActivity(ActionType.OPEN, raw=raw, comm=c_open)
    a_open.fees = total_other_fees
    a_close = StockActivity(ActionType.CLOSE, raw=raw, comm=c_close)
    trade = StockTrade(a_open, a_close, raw)

    session.add(pos)
    session.add(trade)
    session.add(a_open)
    session.add(a_close)
    session.commit()

    if c_open:
        c_open.position_id = pos.id
        c_open.activity_id = a_open.id
    if c_close:
        c_close.position_id = pos.id
        c_close.activity_id = a_close.id
    if len(other_fees):
        for fee in other_fees:
            fee.position_id = pos.id
            fee.activity_id = a_open.id

    trade.position_id = pos.id
    a_open.position_id = pos.id
    a_close.position_id = pos.id
    a_open.trade_id = trade.id
    a_close.trade_id = trade.id