def openpositions_fromwikipedia(ib, db, accid, scancode):
    try:
        tickers = save_tickers(
            'http://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
        # tickers= save_tickers('https: // en.wikipedia.org / wiki / NASDAQ - 100  # Components')
        # tickers= save_tickers('https://www.nasdaq.com/quotes/nasdaq-100-stocks.aspx')

        for ticker in tickers:
            cnt = ibsync.Contract(symbol=ticker,
                                  secType=cf.myscaninstrument,
                                  currency=cf.mycurrency,
                                  exchange=cf.myprefexchange)
            isopen = ibdb.positionisopen(db, accid, ticker)
            if ib.qualifyContracts(cnt) != [] and not isopen:
                try:
                    breakout = requesthistoricaldata(ib, cnt, cf.myprdnum,
                                                     cf.myprdscale,
                                                     cf.mybarsixe)
                except ValueError as e:
                    print(e, cnt)
                    continue
                if breakout > 0:
                    ibdb.dbfill_fundamentals(db, accid,
                                             fillfundamentals(ib, db, [cnt]))
                    opennewoption(ib, db, cnt, "SELL", "P", cf.myoptselldte,
                                  scancode)
                elif breakout < 0:
                    ibdb.dbfill_fundamentals(db, accid,
                                             fillfundamentals(ib, db, [cnt]))
                    opennewoption(ib, db, cnt, "SELL", "C", cf.myoptselldte,
                                  scancode)
    except Exception as err:
        #error_handling(err)
        raise
示例#2
0
文件: app.py 项目: omdv/ibkr-trading
    def get_state(self):
        """
        Handle interactions with API and raise related exceptions here
        """
        self.connect_to_gateway()

        self.ptf = self.ib.portfolio()
        self.options = [
            p.contract for p in self.ptf if p.contract.secType == 'OPT'
        ]
        self.options = self.ib.qualifyContracts(*self.options)
        self.tickers = self.ib.reqTickers(*self.options)

        # get underlying contracts and tickers
        underConIds = [
            self.ib.reqContractDetails(c)[0].underConId for c in self.options
        ]
        underContracts = [ib_insync.Contract(conId=c) for c in underConIds]
        underContracts = self.ib.qualifyContracts(*underContracts)
        underTickers = self.ib.reqTickers(*underContracts)

        df_under = ib_insync.util.df(underTickers)
        df_under['price'] = df_under.apply(self.price_getter, axis=1)
        df_under = df_under[['contract', 'price']].add_suffix('_und')

        df = pd.concat([
            ib_insync.util.df(self.options),
            ib_insync.util.df(self.tickers), df_under
        ],
                       axis=1)

        df['option_price'] = df.apply(self.price_getter, axis=1)

        self.options = df
        self.ib.disconnect()
示例#3
0
def get_optionfromunderlying(cnt, optright, strike, expdate):
    try:
        # preparem el nou trade: definim i qualifiquem la nova opció
        option = ibsync.Contract()
        option.symbol = cnt.symbol
        option.strike = strike
        option.secType = "OPT"
        option.exchange = cf.myprefexchange
        option.currency = cnt.currency
        option.right = optright
        option.lastTradeDateOrContractMonth = expdate
        return option
    except Exception as err:
        # error_handling(err)
        raise
示例#4
0
def contract_from_specifier(
        specifier: ContractSpecifier) -> ib_insync.Contract:
    """
    Converts a ContractSpecifier into an ib_insync Contract object.
    
    This does not guarantee that the resulting Contract actually refers to a real security.
    """

    security_type_mapping = {
        ContractSpecifier.SecurityType.STOCK: "STK",
        ContractSpecifier.SecurityType.OPTION: "OPT",
        ContractSpecifier.SecurityType.FUTURE: "FUT",
        ContractSpecifier.SecurityType.INDEX: "IND",
        ContractSpecifier.SecurityType.FUTURES_OPTION: "FOP",
        ContractSpecifier.SecurityType.CASH: "CASH",
        ContractSpecifier.SecurityType.CFD: "CFD",
        ContractSpecifier.SecurityType.COMBO: "BAG",
        ContractSpecifier.SecurityType.WARRANT: "WAR",
        ContractSpecifier.SecurityType.BOND: "BOND",
        ContractSpecifier.SecurityType.COMMODITY: "CMDTY",
        ContractSpecifier.SecurityType.NEWS: "NEWS",
        ContractSpecifier.SecurityType.FUND: "FUND",
    }

    right_mapping = {
        ContractSpecifier.Right.UNSPECIFIED_RIGHT: "",
        ContractSpecifier.Right.PUT: "P",
        ContractSpecifier.Right.CALL: "C",
    }

    return ib_insync.Contract(
        symbol=specifier.symbol,
        secType=security_type_mapping[specifier.securityType],
        lastTradeDateOrContractMonth=specifier.lastTradeDateOrContractMonth,
        strike=float(specifier.strike) if specifier.strike else 0.0,
        right=right_mapping[specifier.right],
        multiplier=specifier.multiplier,
        exchange=specifier.exchange,
        currency=specifier.currency,
        localSymbol=specifier.localSymbol,
        primaryExchange=specifier.primaryExchange,
        tradingClass=specifier.tradingClass,
        includeExpired=specifier.includeExpired,
    )
示例#5
0
    def get_security_historical(self,
                                contract_id,
                                durationStr,
                                barSizeSetting,
                                whatToShow,
                                useRTH,
                                endDateTime='',
                                updateDB=True):
        """

        Note: cannot be used for expired options - alternative here (https://www.ivolatility.com/)
        """
        assert self.connected, "Must connect to IBKR's Trader Workstation application before using this function"

        # create contract object uing the unique contract ID
        contract = ib_insync.Contract(conId=contract_id)
        self.client.qualifyContracts(contract)

        # use the IBKR API to get historical data
        bars = self.client.reqHistoricalData(contract,
                                             endDateTime=endDateTime,
                                             durationStr=durationStr,
                                             barSizeSetting=barSizeSetting,
                                             whatToShow=whatToShow,
                                             useRTH=useRTH)

        # convert to pandas dataframe
        df = ib_insync.util.df(bars)

        if updateDB:
            df['stock_id'] = contract.symbol
            df['ib_id'] = contract_id
            df = df.astype({"date": str})
            df = df.drop(columns=['average', 'barCount'])

            if 'day' in barSizeSetting:
                price_history_table = 'Price_History_Day'
            elif 'hour' in barSizeSetting:
                price_history_table = 'Price_History_Hour'
                df['hour'] = df['date'].str.split(" ").str[1].str.split(
                    ':').str[0]
            elif 'min' in barSizeSetting:
                price_history_table = 'Price_History_Minute'
                df['hour'] = df['date'].str.split(" ").str[1].str.split(
                    ':').str[0]
                df['minute'] = df['date'].str.split(" ").str[1].str.split(
                    ':').str[1]
            else:
                raise ValueError(
                    "price data with bar size of {} cannot be inserted into the database"
                    .format(barSizeSetting))

            start_date = df['date'].min()
            end_date = df['date'].max()
            sql_execute = queries.sql_get_existing_records_dates.format(
                table=price_history_table,
                ib_id=contract_id,
                start_date=start_date,
                end_date=end_date)

            df['mid'] = (df['high'] + df['low']) / 2

            dates_already_in_db = [
                date[0]
                for date in queries.execute_sql(self.conn, sql_execute)
            ]
            df_new_records = df[~df['date'].isin(dates_already_in_db)]
            schema.insert_price_history(price_history_table, self.conn,
                                        df_new_records)

        return df
def branco_strategy1(ib, db, accid):
    try:
        cnt = ibsync.Stock('VXX', 'SMART', 'USD')
        ib.qualifyContracts(cnt)
        pricevxx = ib.reqTickers(cnt)[0].marketPrice()

        chains = ib.reqSecDefOptParams(cnt.symbol, '', cnt.secType, cnt.conId)
        chain = next(c for c in chains if c.tradingClass == cnt.symbol
                     and c.exchange == cf.myprefexchange)

        lexps = []
        for e in chain.expirations:
            lexps.append(int(e))
        desiredexpiration = (date.today() +
                             timedelta(days=15)).strftime('%Y%m%d')
        expiration = min(lexps,
                         key=lambda x: abs(int(x) - int(desiredexpiration)))
        strikes = [
            strike for strike in chain.strikes
            if (pricevxx * 0.9 < strike < pricevxx * 1.1)
        ]

        contracts = [
            ibsync.Option('VXX',
                          expiration,
                          strike,
                          "C",
                          'SMART',
                          tradingClass='VXX') for strike in strikes
        ]
        ib.qualifyContracts(*contracts)
        greeks = [
            ibutil.get_greeks(ib, contract).modelGreeks
            for contract in contracts
        ]
        deltas = [greek.delta for greek in list(filter(None, greeks))]

        ishort = int(
            min(range(len(deltas)), key=lambda i: abs(deltas[i] - 0.7)))
        ilong = int(min(range(len(deltas)),
                        key=lambda i: abs(deltas[i] - 0.3)))

        #combo = ibsync.Contract()
        #combo.symbol = "VXX"
        #combo.secType = "BAG"
        #combo.exchange = "SMART"
        #combo.currency = "USD"

        #leg1 = ibsync.ComboLeg ()
        #leg1.conId = contracts[ishort]
        #leg1.ratio = 1
        #leg1.action = "SELL"
        #leg1.exchange = "SMART"

        #leg2 = ibsync.ComboLeg()
        #leg2.conId = contracts[ilong]
        #leg2.ratio = 1
        #leg2.action = "BUY"
        #leg2.exchange = "SMART"

        #combo.comboLegs = []
        #combo.comboLegs.append(leg1)
        #combo.comboLegs.append(leg2)

        #order = ibsync.order.LimitOrder("BUY", 1, 1, tif="GTC", transmit=False)
        #trade = ib.placeOrder(combo, order)

        combo = ibsync.Contract(symbol='VXX',
                                secType='BAG',
                                exchange='SMART',
                                currency='USD',
                                comboLegs=[
                                    ibsync.ComboLeg(conId=contracts[ishort],
                                                    ratio=1,
                                                    action='SELL',
                                                    exchange='SMART'),
                                    ibsync.ComboLeg(conId=contracts[ilong],
                                                    ratio=1,
                                                    action='BUY',
                                                    exchange='SMART')
                                ])
        trade = tradelimitorder(ib, db, combo, 1, 1, "BRANCO_1")
        order = ibsync.LimitOrder(action='SELL',
                                  totalQuantity=1,
                                  lmtPrice=1,
                                  transmit=False,
                                  account=accid)
        trade = ib.placeOrder(combo, order)
        print(trade)
    except Exception as err:
        # error_handling(err)
        raise
示例#7
0
    log.debug(args)
    if args.debug:
       log.setLevel(logging.DEBUG)
    settings = yaml.load(open(args.settings,'r'))
    
    tickLogger = TickLogger(settings['dataRoot'])
    
    ib = ibis.IB()
    log.info('Connecting to IB')
    
    ib.connect('127.0.0.1', 4002, clientId=10)
    ib.pendingTickersEvent += tickLogger.tickHandler
    
    
    # subscribe to data
    
    contracts = [ibis.Contract(**sub)  for sub in settings['subscriptions']]
    
    for contract in contracts:
        log.info('Subscribing to '+str(contract))
        ib.reqMktData(contract, '', False, False)
    
    
    try:
        while True:    
            ib.sleep(60)
            tickLogger.flush()
    except KeyboardInterrupt:
        log.info('Exiting')
    
示例#8
0
            elif q.lower() == "mavpaper2":
                rslt = ibutil.execute_query(mydb, sql + " connName = 'mavpaper2'")
                break
            elif q.lower() == "exit":
                sys.exit("Exit requested! ")
            else:
                q = input ("Unknown account! ")

        myib.connect(rslt[0][0], rslt[0][1], rslt[0][3])
        myaccId = rslt[0][2]

        tickers= save_tickers('http://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
        # tickers= save_tickers('https: // en.wikipedia.org / wiki / NASDAQ - 100  # Components')
        # tickers= save_tickers('https://www.nasdaq.com/quotes/nasdaq-100-stocks.aspx')
        for ticker in tickers:
            cnt = ibsync.Contract(symbol = ticker, secType = "STK", currency = "USD", exchange = "SMART")
            isopen = ibdb.positionisopen(mydb, myaccId, ticker )
            if not myib.qualifyContracts(cnt) != [] and not isopen:
                try:
                    breakout = requesthistoricaldata(cnt, 5, "Y", "1 week")
                except ValueError as e:
                    print(e, cnt)
                    continue
                if  breakout > 0:
                    opennewoption(myib, mydb, cnt, "SELL", "P", cf.myoptselldte, "5YHIGH")
                elif breakout < 0:
                    opennewoption(myib, mydb, cnt, "SELL", "C", cf.myoptselldte, "5YLOW")

    except Exception as err:
        #error_handling(err)
        raise
示例#9
0
def opennewoption(ib, cnt, opttype, optright, optdaystoexp):
    print("\n\t opennewoption")
    try:
        # agafem lastprice del underlying provinent de ticker
        lastpricestk = ib.reqTickers(cnt)[0].marketPrice()
        # busquem la cadena d'opcions del underlying
        chains = ib.reqSecDefOptParams(cnt.symbol, '', cnt.secType, cnt.conId)
        chain = next(c for c in chains
                     if c.tradingClass == cnt.symbol and c.exchange == 'SMART')

        # separem strikes i expiracions (tenir en compte que strikes i expiracions estan en forma de Set, no de List
        lstrikes = chain.strikes

        # busquem el strike que més s'acosta a lastpricestk
        orderstrike = min(lstrikes, key=lambda x: abs(int(x) - lastpricestk))

        # busquem la expiration que més s'acosta a desiredexpiration
        lexps = []
        for e in chain.expirations:
            lexps.append(int(e))
        desiredexpiration = date.today() + timedelta(days=optdaystoexp)
        desiredexpiration = int(
            str(desiredexpiration)[0:4] + str(desiredexpiration)[5:7] +
            str(desiredexpiration)[8:10])
        orderexp = min(lexps, key=lambda x: abs(int(x) - desiredexpiration))

        # preparem el nou trade: definim i qualifiquem la nova opció
        optcnt = ibsync.Contract()
        optcnt.symbol = cnt.symbol
        optcnt.strike = orderstrike
        optcnt.secType = "OPT"
        optcnt.exchange = "SMART"
        optcnt.currency = cnt.currency
        optcnt.right = optright
        optcnt.lastTradeDateOrContractMonth = orderexp

        # no tots els strikes possibles (entre ells potser el ja triat) són vàlids.
        # si el strike triat no és vàlid en busquem un que sigui vàlid apujant (i baixant) el strike en 0.5
        # fins a trobar un que sigui acceptat. Això pot provocar que ens allunyem del ATM, però no hi ha altra solució
        ct = 0
        while ib.qualifyContracts(optcnt) == [] and ct < 11:
            optcnt.strike = orderstrike = int(orderstrike + 0.5 *
                                              (optright == "C") - 0.5 *
                                              (optright == "P"))
            ct += 1
        # busquem el preu al que cotitza la nova opció de la que obrirem contracte
        topt = ib.reqTickers(optcnt)
        lastpriceopt = topt[0].marketPrice()

        # fem un reqN¡MktData per obtenir (hopefully) els Greeks
        opttkr = ib.reqMktData(optcnt, '', False,
                               False)  # això torna un objecte Ticker
        l = 0
        while (opttkr.lastGreeks == None
               ) and l < 5:  # mini-bucle per esperar que es rebin els Greeks
            opttkr = ib.reqMktData(optcnt, '', False, False)
            ib.sleep(5)
            l += 1
        # definim la quantitat = (Capital màxim)/(100*preu acció*Delta)
        # en cas que la delta torni buida, usem 0.5 (de moment agafem opcions AtTheMoney igualment)
        if (opttkr.lastGreeks.delta is not None):
            qty = (1 - 2 * -(opttype == "SELL")) * round(
                ibconfig.mymaxposition /
                (100 * lastpricestk * abs(opttkr.lastGreeks.delta)))
        else:
            qty = (1 - 2 *
                   (opttype == "SELL")) * round(ibconfig.mymaxposition /
                                                (100 * lastpricestk * 0.5))

        print("symbol  ", optcnt.symbol, "lastpricestk  ", lastpricestk,
              "desiredstrike", lastpricestk, "orderstrike  ", orderstrike,
              "desiredexpiration", desiredexpiration, "orderexp  ", orderexp,
              "quantity", qty, "conId", optcnt.conId, "price", lastpriceopt)

        if lastpriceopt == lastpriceopt:  #checks if nan
            return tradelimitorder(ib, optcnt, qty, lastpriceopt)
        else:
            return None
    except Exception as err:
        error_handling(err)
        raise
示例#10
0
def opendefensiveposition(ib, cnt, pos):
    try:
        print("opendefensiveposition")
        # creem objectes tupus contracte
        stkcnt = ibsync.Contract()  # el underlying de la opció
        optcnt1 = ibsync.Contract()  # la opció que hi ha al portfolio
        optcnt2 = ibsync.Contract()  # la potencial nova opció que es crearà

        # composem el contracte del underlying de la opció analitzada
        # stkcnt = Stock(cnt.symbol, "SMART", cnt.currency)
        stkcnt.symbol = cnt.symbol
        stkcnt.currency = cnt.currency
        stkcnt.secType = "STK"
        stkcnt.exchange = "SMART"
        ib.qualifyContracts(stkcnt)
        print("defensiveposition de: ", stkcnt)
        # composem el contracte de la opció analitzada
        optcnt1.conId = pos.conId
        ib.qualifyContracts(optcnt1)

        # composem la data d'expiració que és la mateixa tant per la opció original (optcnt1) com la nova defensiva (optcnt2)
        dateexpiration = str(optcnt1.lastTradeDateOrContractMonth)[0:4] + str(
            optcnt1.lastTradeDateOrContractMonth)[4:6] + str(
                optcnt1.lastTradeDateOrContractMonth)[6:8]

        # agafem lastprice del underlying provinent de ticker
        tstk = ib.reqTickers(stkcnt)
        topt1 = ib.reqTickers(optcnt1)
        lastpricestk = tstk[0].marketPrice()
        lastpriceopt1 = topt1[0].marketPrice()
        ib.sleep(1)

        # busquem la cadena d'opcions del underlying
        chains = ib.reqSecDefOptParams(stkcnt.symbol, '', stkcnt.secType,
                                       stkcnt.conId)
        chain = next(
            c for c in chains
            if c.tradingClass == stkcnt.symbol and c.exchange == 'SMART')

        # separem strikes i expiracions
        lexps = []
        lstrikes = []
        lexps = chain.expirations
        lstrikes = chain.strikes
        myList = lstrikes
        lastpricestk = int(lastpricestk)

        # calculem la distància entre el preu del underlying ara i el strike de la opció venuda que estem analitzant
        strikedistance = abs(optcnt1.strike - lastpricestk)

        # busquem l'strike que més s'acosta al del preu actual del underlying
        orderstrike = min(lstrikes,
                          key=lambda x: int(abs(int(x) - lastpricestk)))

        # preparem el nou trade: si era un call ara un put...i al inreves
        if optcnt1.right == "C":
            opt2right = "P"
        else:
            opt2right = "C"

        # preparem el nou trade: qualifiquem la nova opció compensatoria
        optcnt2.symbol = optcnt1.symbol
        optcnt2.strike = orderstrike
        optcnt2.secType = optcnt1.secType
        optcnt2.exchange = "SMART"
        optcnt2.currency = optcnt1.currency
        optcnt2.right = opt2right
        optcnt2.lastTradeDateOrContractMonth = dateexpiration
        ib.qualifyContracts(optcnt2)
        print("optcon2", optcnt2)

        # busquem el preu al que cotitza la nova opció compensatoria
        topt2 = ib.reqTickers(optcnt2)
        lastpriceopt2bis = (topt2[0].bid + topt2[0].ask) / 2
        # lastprice = formatPrice(lastprice, 2)

        lastpriceopt2 = topt2[0].marketPrice()
        ib.sleep(1)
        # executem la ordre
        print("opendefensiveposition - ", optcnt2, pos.shares, lastpriceopt2,
              pos.conId)
        tradelimitorder(ib, optcnt2, pos.shares, lastpriceopt2)
    except Exception as err:
        error_handling(err)
        raise
示例#11
0
def processopenpositions(ib, db, vAccId):
    print("\nprocessopenpositions")
    try:

        # llegim posicions obertes de la base de dades
        query = "SELECT pId, pExecId, pAccId, pConId, pDate, pType, pMultiplier, pShares, pInitialPrice,pInitialValue, pClosingPrice, pClosingValue," \
                " pClosingDate, pClosingId, pPNL, pCommission, pLiquidation, pActive" \
                " FROM positions LEFT JOIN contracts ON positions.pConId = contracts.kConId" \
                " WHERE pAccId =  '" + vAccId + "' AND pActive = 1"

        rst = execute_query(db, query, values=None)
        # definim namedtuple "positions" per a processar posicions obertes
        positions = namedtuple(
            "positions", "Id execId accId conId  \
                                     date type multiplier shares initialPrice initialValue closingPrice \
                                     closingValue closingDate closingId PNL commission liquidation \
                                     active")

        # passem les execucions obertes en forma de namedtuple a la llista "openpos"
        openpos = []
        for i in range(len(rst)):
            position = positions(Id=rst[i][0],
                                 execId=rst[i][1],
                                 accId=rst[i][2],
                                 conId=rst[i][3],
                                 date=rst[i][4],
                                 type=rst[i][5],
                                 multiplier=rst[i][6],
                                 shares=rst[i][7],
                                 initialPrice=rst[i][8],
                                 initialValue=rst[i][9],
                                 closingPrice=rst[i][10],
                                 closingValue=rst[i][11],
                                 closingDate=rst[i][12],
                                 closingId=rst[i][13],
                                 PNL=rst[i][14],
                                 commission=rst[i][15],
                                 liquidation=rst[i][16],
                                 active=rst[i][17])
            openpos.append(position)
        # llegim "openpos" en forma de loop per a decidir què fer amb cada execució oberta
        pctProfitList = []
        for pos in openpos:
            # creem un objecte Contract
            cnt = ibsync.Contract()
            # fem una instancia de contract amb el contracte llegit del query de trades oberts de la db trades
            cnt.conId = pos.conId

            ib.qualifyContracts(cnt)
            pfl = ib.portfolio()

            # obtenim i formategem data expiració
            dateexpiration = str(cnt.lastTradeDateOrContractMonth)[0:4] + str(
                cnt.lastTradeDateOrContractMonth)[4:6] + str(
                    cnt.lastTradeDateOrContractMonth)[6:8]

            # agafem lastprice provinent de portfolio
            lastprice = 0
            for f in pfl:
                if pos.conId == f.contract.conId:
                    lastprice = f.marketPrice
                    # lastprice = f.marketValue
            # demanem dades a traves de reqMktData
            # m_data = ib.reqMktData(cnt)
            # while m_data.last != m_data.last: ib.sleep(0.01)  # Wait until data is in.
            # ib.cancelMktData(cnt)
            # print("m_data   ",m_data.last)

            avgcost = float(pos.initialPrice)
            vshares = pos.shares
            # calculem pctprofitnow (el pnl de la posició)
            if vshares < 0:
                pctprofitnow = (1 - (lastprice / avgcost)) * 100
            else:
                pctprofitnow = ((lastprice / avgcost) - 1) * 100
            print(cnt.symbol, "  ", vshares, "lastprice   ", lastprice,
                  "avgcost", avgcost, "pctprofitnow  ", pctprofitnow)

            # calculem percentatge temps passat entre apertura posició i expiració per a posicions d'opcions
            pctpostimeelapsed = 0
            if cnt.secType == "OPT":
                dateentry = str(pos.date)[0:4] + str(pos.date)[5:7] + str(
                    pos.date)[8:10]
                datetoday = datetime.datetime.now().strftime("%Y%m%d")
                datedifffromentry = diffdays
                datedifffromentry = diffdays(dateentry, dateexpiration)
                datedifffromtoday = diffdays(datetoday, dateexpiration)
                pctpostimeelapsed = int(
                    (1 - datedifffromtoday / datedifffromentry) * 100)

            # d'acord amb els paràmetres calculats decidim si es fa un trade o no a la funció "allowtrade"
            # allowtrade = allowTrade(pctpostimeelapsed, pctprofitnow)
            allowtrade = allowTrade(pctpostimeelapsed, pctprofitnow,
                                    cnt.secType)
            # allowtrade = 0
            pctProfitList.append([
                cnt.symbol, pos.shares, cnt.right, cnt.strike,
                pos.initialPrice, lastprice,
                int(pctprofitnow), pctpostimeelapsed, allowtrade
            ])

            # allowtrade = 1 tancar posició per recollida de beneficis, allowtrade = 2 fem un trade defensio de la posició
            price = 0
            if allowtrade == 1:
                if pos.shares < 0:
                    ordertype = 'BUY'
                else:
                    ordertype = 'SELL'
                # Configurem preu operació
                if ordertype == "BUY" and cnt.secType == "OPT":
                    # price = ((avgcost * ((100 - pctprofitnow)) / 100)) / 100
                    price = avgcost * (1 - pctprofitnow / 100)
                elif ordertype == "SELL" and cnt.secType == "OPT":
                    # price = (avgcost * (1 + (pctprofitnow / 100))) / 100
                    price = avgcost * (1 + pctprofitnow / 100)
                fmtprice = formatPrice(price, 2)
                print("Close Position: \t", cnt, "\t", ordertype, "\t",
                      fmtprice)
                tradelimitorder(ib, cnt, -vshares, fmtprice)
            elif allowtrade == 2:
                # obrim posició defensiva
                opendefensiveposition(ib, cnt, pos)
            elif allowtrade == 3:
                if pos.shares < 0:
                    ordertype = 'BUY'
                else:
                    ordertype = 'SELL'
                # Configurem preu operació
                if ordertype == "BUY":
                    price = lastprice
                    # price = avgcost * (1 - pctprofitnow / 100)
                elif ordertype == "SELL":
                    price = lastprice
                    # price = avgcost * (1 + pctprofitnow / 100)
                fmtprice = formatPrice(price, 2)
                print("Close Position: \t", cnt, "\t", ordertype, "\t",
                      fmtprice)
                tradelimitorder(ib, cnt, -vshares, fmtprice)
            elif allowtrade == 4:
                if pos.shares < 0:
                    ordertype = 'BUY'
                else:
                    ordertype = 'SELL'
                # Configurem preu operació
                if ordertype == "BUY":
                    price = lastprice
                    # price = avgcost * (1 - pctprofitnow / 100)
                elif ordertype == "SELL":
                    price = lastprice
                    # price = avgcost * (1 + pctprofitnow / 100)
                fmtprice = formatPrice(price, 2)
                print("Close Position: \t", cnt, "\t", ordertype, "\t",
                      fmtprice)
                tradelimitorder(ib, cnt, -vshares, fmtprice)
            elif allowtrade == "8888":
                pass
            else:
                pass
    except Exception as err:
        error_handling(err)
        raise