ib-api-reloaded/ib_async

Update ContractDetails

Opened this issue ยท 7 comments

These fund items have been added under def ContractDetails

      # FUND values
        self.fundName = ""
        self.fundFamily = ""
        self.fundType = ""
        self.fundFrontLoad = ""
        self.fundBackLoad = ""
        self.fundBackLoadTimeInterval = ""
        self.fundManagementFee = ""
        self.fundClosed = False
        self.fundClosedForNewInvestors = False
        self.fundClosedForNewMoney = False
        self.fundNotifyAmount = ""
        self.fundMinimumInitialPurchase = ""
        self.fundSubsequentMinimumPurchase = ""
        self.fundBlueSkyStates = ""
        self.fundBlueSkyTerritories = ""
        self.fundDistributionPolicyIndicator = FundDistributionPolicyIndicator.NoneItem
        self.fundAssetType = FundAssetType.NoneItem

Also this code has been added at the end:

class FundAssetType(Enum):
    NoneItem = ("None", "None")
    Others = ("000", "Others"), 
    MoneyMarket = ("001", "Money Market")
    FixedIncome = ("002", "Fixed Income")
    MultiAsset = ("003", "Multi-asset")
    Equity = ("004", "Equity")
    Sector = ("005", "Sector")
    Guaranteed = ("006", "Guaranteed")
    Alternative = ("007", "Alternative")

class FundDistributionPolicyIndicator(Enum):
    NoneItem = ("None", "None")
    AccumulationFund = ("N", "Accumulation Fund")
    IncomeFund = ("Y", "Income Fund")

def listOfValues(cls):
    return list(map(lambda c: c, cls))

def getEnumTypeFromString(cls, stringIn):
    for item in cls:
        if item.value[0] == stringIn:
            return item
    return listOfValues(cls)[0]

def getEnumTypeName(cls, valueIn):
    for item in cls:
        if item == valueIn:
            return item.value[1]
    return listOfValues(cls)[0].value[1]

Indeed! It's on the todo list. We'll need to make some new classes and types and add these new details to the protocol parser for those fields.

Most of the work will be a refactor of the twsapi/ibapi python implementation's protocol decoder in ibapi/decoder.py around here:

        if (
            self.serverVersion >= MIN_SERVER_VER_FUND_DATA_FIELDS
            and contract.contract.secType == "FUND"
        ):

Did you want to add me to the repo and I can assign this to myself?

Thanks! Yeah, feel free to give it a try. These are a different input format than anything else, so it may take some decisions to figure out what goes where and how.

I'll select you on the assigned field and just drop a PR if it looks good enough to review. I'd be curious to test it too but I don't know what symbols are this FUND type yet. Maybe we can even try to add some automated test cases for it (against a readonly gateway?).

Looking through it a bit, those Enum cases are just weird/bad. The reason their format is like ("001", "Money Market") is because the ibapi decoder is reading 001 from the IBKR protocol then replacing it with Money Market on the returned object for the user to see.

BUT โ€” these should just be dicts mapping the key to the enum value then? They have that awful thing called getEnumTypeFromString() which just linearly searches each enum if x[0] == value? why would they do it that way? it's 10x more difficult than just using a dict for those mappings. more like lookupFundAssetType: dict[str, FundAssetType] = {"None": FundAssetType.NoneItem, "001": FundAssetType.MoneyMarket, ...} etc?

@ClimberMel have you been able to progress on this one?

No, I got sidetracked. I was having trouble finding example to test it with. I'm not familiar with bonds, and that is all these changes pertain to.

Yeah, testing this would be a bit weird. Probably just making it match the existing twsapi interface should be good enough then people can complain if it doesn't work. I think these are only informational APIs anyway and don't impact trading at all?

I can look through it again to see what matches for adapting if your attempts have run out of steam.

You know that's not a bad idea, I have the code changes so I'll upload them and wait to see if anyone uses them.