def test_combineToZero(self, p: Position) -> None:
        opposite = Position(
            instrument=p.instrument, quantity=-p.quantity, costBasis=-p.costBasis
        )

        combined = p + opposite
        self.assertEqual(combined.quantity, Decimal(0))
        self.assertEqual(combined.costBasis, Decimal(0))
Beispiel #2
0
def _parseFidelityPosition(p: _FidelityPosition,
                           instrumentFactory: _InstrumentFactory) -> Position:
    qty = Decimal(p.quantity)
    return Position(
        instrument=instrumentFactory(p),
        quantity=qty,
        costBasis=Cash(currency=Currency.USD, quantity=Decimal(p.costBasis)),
    )
    def test_combineIncreasesBasis(self, i: Instrument) -> None:
        a = Position(
            instrument=i,
            quantity=Decimal("100"),
            costBasis=Cash(currency=i.currency, quantity=Decimal("10")),
        )
        b = Position(
            instrument=i,
            quantity=Decimal("300"),
            costBasis=Cash(currency=i.currency, quantity=Decimal("20")),
        )

        combined = a + b
        self.assertEqual(combined.instrument, i)
        self.assertEqual(combined.quantity, Decimal("400"))
        self.assertEqual(
            combined.costBasis, Cash(currency=i.currency, quantity=Decimal("30"))
        )
Beispiel #4
0
    def test_fuzzPosition(self, position: IB.Position) -> None:
        try:
            parsedPosition = _extractPosition(position)
        except ValueError:
            return

        self.assertEqual(
            parsedPosition.quantity,
            Position.quantizeQuantity(Decimal(position.position)),
        )
        self.validatePositionContract(position, parsedPosition.instrument)
    def test_combineIsCommutative(
        self,
        i: Instrument,
        aQty: Decimal,
        aPrice: Decimal,
        bQty: Decimal,
        bPrice: Decimal,
    ) -> None:
        assume(aQty != -bQty)

        a = Position(
            instrument=i,
            quantity=aQty,
            costBasis=Cash(currency=i.currency, quantity=aPrice),
        )
        b = Position(
            instrument=i,
            quantity=bQty,
            costBasis=Cash(currency=i.currency, quantity=bPrice),
        )
        self.assertEqual(a + b, b + a)
def _parseVanguardPosition(p: _VanguardPosition,
                           activity: List[Activity]) -> Position:
    instrument: Instrument
    if len(p.symbol) > 0:
        instrument = Stock(p.symbol, currency=Currency.USD)
    else:
        instrument = _guessInstrumentForInvestmentName(p.investmentName)

    qty = Decimal(p.shares)

    realizedBasis = _realizedBasisForSymbol(instrument.symbol, activity)
    assert realizedBasis, "Invalid realizedBasis: %s for %s" % (
        realizedBasis,
        instrument,
    )

    return Position(instrument=instrument,
                    quantity=qty,
                    costBasis=realizedBasis)
def _parseSchwabPosition(p: _SchwabPosition) -> Optional[Position]:
    if re.match(r"Futures |Cash & Money Market|Account Total", p.symbol):
        return None

    instrument: Instrument
    if re.match(r"Equity|ETFs", p.securityType):
        instrument = Stock(p.symbol, currency=Currency.USD)
    elif re.match(r"Option", p.securityType):
        instrument = _parseOption(p.symbol)
    elif re.match(r"Fixed Income", p.securityType):
        instrument = Bond(p.symbol, currency=Currency.USD)
    else:
        raise ValueError(f"Unrecognized security type: {p.securityType}")

    return Position(
        instrument=instrument,
        quantity=_schwabDecimal(p.quantity),
        costBasis=Cash(currency=Currency.USD,
                       quantity=_schwabDecimal(p.costBasis)),
    )
def _extractPosition(p: IB.Position) -> Position:
    tag = p.contract.secType
    symbol = p.contract.localSymbol

    if p.contract.currency not in Currency.__members__:
        raise ValueError(f"Unrecognized currency in position: {p}")

    currency = Currency[p.contract.currency]
    exchange = p.contract.exchange or None

    try:
        instrument: Instrument
        if tag == "STK":
            instrument = Stock(symbol=symbol,
                               currency=currency,
                               exchange=exchange)
        elif tag == "BILL" or tag == "BOND":
            instrument = Bond(
                symbol=symbol,
                currency=currency,
                validateSymbol=False,
                exchange=exchange,
            )
        elif tag == "OPT":
            instrument = _parseOption(
                symbol=symbol,
                currency=currency,
                multiplier=_parseFiniteDecimal(p.contract.multiplier),
                exchange=exchange,
            )
        elif tag == "FUT":
            instrument = Future(
                symbol=symbol,
                currency=currency,
                multiplier=_parseFiniteDecimal(p.contract.multiplier),
                expiration=_parseIBDate(
                    p.contract.lastTradeDateOrContractMonth).date(),
                exchange=exchange,
            )
        elif tag == "FOP":
            instrument = _parseFutureOptionContract(p.contract,
                                                    currency=currency,
                                                    exchange=exchange)
        elif tag == "CASH":
            instrument = _parseForex(symbol=symbol,
                                     currency=currency,
                                     exchange=exchange)
        else:
            raise ValueError(
                f"Unrecognized/unsupported security type in position: {p}")

        qty = _parseFiniteDecimal(p.position)
        costBasis = _parseFiniteDecimal(p.avgCost) * qty

        return Position(
            instrument=instrument,
            quantity=qty,
            costBasis=Cash(currency=Currency[p.contract.currency],
                           quantity=costBasis),
        )
    except InvalidOperation:
        raise ValueError(
            f"One of the numeric position or contract values is out of range: {p}"
        )