예제 #1
0
 def updatePortfolio(self, contract: Contract, posSize: float,
                     marketPrice: float, marketValue: float,
                     averageCost: float, unrealizedPNL: float,
                     realizedPNL: float, account: str):
     contract = Contract.create(**dataclassAsDict(contract))
     portfItem = PortfolioItem(contract, posSize, marketPrice, marketValue,
                               averageCost, unrealizedPNL, realizedPNL,
                               account)
     portfolioItems = self.portfolio[account]
     if posSize == 0:
         portfolioItems.pop(contract.conId, None)
     else:
         portfolioItems[contract.conId] = portfItem
     self._logger.info(f'updatePortfolio: {portfItem}')
     self.ib.updatePortfolioEvent.emit(portfItem)
예제 #2
0
 def position(
         self, account: str, contract: Contract, posSize: float,
         avgCost: float):
     contract = Contract.create(**dataclassAsDict(contract))
     position = Position(account, contract, posSize, avgCost)
     positions = self.positions[account]
     if posSize == 0:
         positions.pop(contract.conId, None)
     else:
         positions[contract.conId] = position
     self._logger.info(f'position: {position}')
     results = self._results.get('positions')
     if results is not None:
         results.append(position)
     self.ib.positionEvent.emit(position)
예제 #3
0
파일: wrapper.py 프로젝트: rhawiz/ib_insync
    def openOrder(
            self, orderId: int, contract: Contract, order: Order,
            orderState: OrderState):
        """
        This wrapper is called to:

        * feed in open orders at startup;
        * feed in open orders or order updates from other clients and TWS
          if clientId=master id;
        * feed in manual orders and order updates from TWS if clientId=0;
        * handle openOrders and allOpenOrders responses.
        """
        if order.whatIf:
            # response to whatIfOrder
            if orderState.commissionCurrency:
                self._endReq(order.orderId, orderState)
        else:
            key = self.orderKey(order.clientId, order.orderId, order.permId)
            trade = self.trades.get(key)
            if trade:
                trade.order.permId = order.permId
                trade.order.totalQuantity = order.totalQuantity
                trade.order.lmtPrice = order.lmtPrice
                trade.order.auxPrice = order.auxPrice
                trade.order.orderType = order.orderType
            else:
                # ignore '?' values in the order
                order = Order(**{
                    k: v for k, v in dataclassAsDict(order).items()
                    if v != '?'})
                contract = Contract.create(**dataclassAsDict(contract))
                orderStatus = OrderStatus(
                    orderId=orderId, status=orderState.status)
                trade = Trade(contract, order, orderStatus, [], [])
                self.trades[key] = trade
                self._logger.info(f'openOrder: {trade}')
            self.permId2Trade.setdefault(order.permId, trade)
            results = self._results.get('openOrders')
            if results is None:
                self.ib.openOrderEvent.emit(trade)
            else:
                # response to reqOpenOrders or reqAllOpenOrders
                results.append(order)

        # make sure that the client issues order ids larger then any
        # order id encountered (even from other clients) to avoid
        # "Duplicate order id" error
        self.ib.client.updateReqId(orderId + 1)
예제 #4
0
 def openOrder(self, orderId, contract, order, orderState):
     if order.whatIf:
         # response to whatIfOrder
         orderState = OrderState(**orderState.__dict__)
         self._endReq(orderId, orderState)
     else:
         contract = Contract(**contract.__dict__)
         order = Order(**order.__dict__)
         orderStatus = OrderStatus(status=orderState.status)
         if order.softDollarTier:
             order.softDollarTier = SoftDollarTier(
                     **order.softDollarTier.__dict__)
         trade = Trade(contract, order, orderStatus, [], [])
         if order.clientId == self.clientId and orderId not in self.trades:
             self.trades[orderId] = trade
             _logger.info(f'openOrder: {trade}')
         results = self._results.get('openOrders')
         if results is not None:
             # response to reqOpenOrders
             results.append(order)
예제 #5
0
파일: wrapper.py 프로젝트: rhawiz/ib_insync
 def execDetails(
         self, reqId: int, contract: Contract, execution: Execution):
     """
     This wrapper handles both live fills and responses to
     reqExecutions.
     """
     self._logger.info(f'execDetails {execution}')
     if execution.orderId == UNSET_INTEGER:
         # bug in TWS: executions of manual orders have unset value
         execution.orderId = 0
     trade = self.permId2Trade.get(execution.permId)
     if not trade:
         key = self.orderKey(
             execution.clientId, execution.orderId, execution.permId)
         trade = self.trades.get(key)
     if trade and contract == trade.contract:
         contract = trade.contract
     else:
         contract = Contract.create(**dataclassAsDict(contract))
     execId = execution.execId
     isLive = reqId not in self._futures
     time = self.lastTime if isLive else execution.time
     fill = Fill(contract, execution, CommissionReport(), time)
     if execId not in self.fills:
         # first time we see this execution so add it
         self.fills[execId] = fill
         if trade:
             trade.fills.append(fill)
             logEntry = TradeLogEntry(
                 time,
                 trade.orderStatus.status,
                 f'Fill {execution.shares}@{execution.price}')
             trade.log.append(logEntry)
             if isLive:
                 self._logger.info(f'execDetails: {fill}')
                 self.ib.execDetailsEvent.emit(trade, fill)
                 trade.fillEvent(trade, fill)
     if not isLive:
         self._results[reqId].append(fill)
예제 #6
0
def is_open_today(contracthours: Contract):
    # a return of NONE is when the market is not opern for the given day
    """ Parse contract Trading Hours to Check if Valid Trading Day"""
    #rint("contract hours",contracthours)
    date_re = compile_re(r"([0-9]{8}):([0-9]+)-([0-9]{8}):([0-9]+)")
    #rint("date_re: ",date_re)
    days = contracthours.split(";")                         #parse the list
    today = datetime.today().strftime("%Y%m%d")             #today in fomat matching the list
    yesterday = (datetime.today() - timedelta(days=1)).strftime("%Y%m%d")
    tomorrow = (datetime.today() + timedelta(days=1)).strftime("%Y%m%d")
    hours = []
    tradingDayType, tradingDayRules, currentTimeFrame = checkDayType(today)
    log.debug("Trading date: {td} day type: {dt}".format(td=today,dt=tradingDayType))
    for day in days:
        match = date_re.match(day)
        #rint("date re: ",date_re.match(day))
        if not match: continue
        if match.group(1) not in [today, yesterday]: continue
        if match.group(3) not in [today, yesterday]: continue
        hours += ["{0}-{1}".format(match.group(2), match.group(4))]

    today_hours = ",".join(hours)
    log.debug("todays trading hours are: {th}".format(th=today_hours))

    #csv_file = csv.reader(open('data/tradinghours.csv', "rt"), delimiter = ",")
    #hours_found = False
    #for row in csv_file:
    #    if today_hours == row[0]:
    #        hours_found = True
    #        break
    #if not hours_found:
    #    with open('data/tradinghours.csv', mode='a') as tradehours:
    #        histwriter = csv.writer(tradehours, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
    #        histwriter.writerow([today_hours])
        
    if today_hours == config.NORMAL_TRADING_HOURS:
        return True, tradingDayRules, currentTimeFrame
    return False, tradingDayRules, currentTimeFrame
예제 #7
0
    def openOrder(self, orderId: int, contract: Contract, order: Order,
                  orderState: OrderState):
        """
        This wrapper is called to:

        * feed in open orders at startup;
        * feed in open orders or order updates from other clients and TWS
          if clientId=master id;
        * feed in manual orders and order updates from TWS if clientId=0;
        * handle openOrders and allOpenOrders responses.
        """
        if order.whatIf:
            # response to whatIfOrder
            self._endReq(order.orderId, orderState)
        else:
            key = self.orderKey(order.clientId, order.orderId, order.permId)
            trade = self.trades.get(key)
            if trade:
                trade.order.permId = order.permId
            else:
                # ignore '?' values in the order
                order = Order(**{
                    k: v
                    for k, v in dataclassAsDict(order).items() if v != '?'
                })
                contract = Contract.create(**dataclassAsDict(contract))
                orderStatus = OrderStatus(orderId=orderId,
                                          status=orderState.status)
                trade = Trade(contract, order, orderStatus, [], [])
                self.trades[key] = trade
                self._logger.info(f'openOrder: {trade}')
            self.permId2Trade.setdefault(order.permId, trade)
            results = self._results.get('openOrders')
            if results is None:
                self.ib.openOrderEvent.emit(trade)
            else:
                # response to reqOpenOrders or reqAllOpenOrders
                results.append(order)
예제 #8
0
 def execDetails(self, reqId, contract, execution):
     """
     This wrapper handles both live fills and responses to reqExecutions.
     """
     if execution.orderId == 2147483647:
         # bug in TWS: executions of manual orders have orderId=2**31 - 1
         execution.orderId = 0
     key = self.orderKey(execution.clientId, execution.orderId,
                         execution.permId)
     trade = self.trades.get(key)
     if trade and contract.conId == trade.contract.conId:
         contract = trade.contract
     else:
         contract = Contract(**contract.__dict__)
     execId = execution.execId
     execution = Execution(**execution.__dict__)
     execution.time = util.parseIBDatetime(execution.time). \
             astimezone(datetime.timezone.utc)
     isLive = reqId not in self._futures
     time = self.lastTime if isLive else execution.time
     fill = Fill(contract, execution, CommissionReport(), time)
     if execId not in self.fills:
         # first time we see this execution so add it
         self.fills[execId] = fill
         if trade:
             trade.fills.append(fill)
             logEntry = TradeLogEntry(
                 self.lastTime, trade.orderStatus.status,
                 f'Fill {execution.shares}@{execution.price}')
             trade.log.append(logEntry)
             if isLive:
                 self.handleEvent('execDetailsEvent', trade, fill)
                 self._logger.info(f'execDetails: {fill}')
                 trade.fillEvent(trade, fill)
     if not isLive:
         self._results[reqId].append(fill)
예제 #9
0
    def run(self):
        """ Execute the algorithm """
        key_arr = [
            'blank', 'ATR15', 'ATR1', 'ATRD', 'CCI15', 'CCIA15', 'CCIA1h',
            'CCIA1d', 'BBW15', 'BBb15', 'BBW1h', 'BBb1h', 'BBW1d', 'BBb1d'
        ]
        tradenow = False
        not_finished = True
        tradenow = False
        cci_trade = False
        ccibb_trade = False
        while not_finished:
            print("top of algo run self")
            crossed = False
            self.app.crossover.update(crossed)
            contContract = get_contract(self)
            dataContract = Contract(exchange=config.EXCHANGE,
                                    secType="FUT",
                                    localSymbol=contContract.localSymbol)
            log.info("Got Contract: {}".format(dataContract.localSymbol))
            self.app.contract.update(dataContract.localSymbol)

            # my add
            nextday = datetime.now().day
            nexthour = datetime.now().hour
            # endDateTime=datetime(int(date.today().year),int(date.today().month),int(nextday),int(nexthour),int(nextqtr),int(0)),
            if datetime.now().minute < 15:
                nextqtr = 15
                getqtr = 30

            elif datetime.now().minute < 30:
                nextqtr = 30
                getqtr = 45
            elif datetime.now().minute < 45:
                nextqtr = 45
                getqtr = 0
            else:
                nexthour = nexthour + 1
                nextqtr = 0
                getqtr = 15
            test = (datetime(int(date.today().year), int(date.today().month),
                             int(nextday), int(nexthour), int(getqtr), int(0)))
            print("nextqtr and getqtr {} {}".format(nextqtr, getqtr))
            log.info(
                "next datetime for 15 minutes - should be 15 minutes ahead of desired nextqtr{}"
                .format(test))
            #
            #nextqtr = datetime.now().minute + 1
            #print ("we manually overwrote start time")
            #print (nextqtr)
            #
            self.ib.waitUntil(time(hour=nexthour, minute=nextqtr))
            # 15 Minute Data
            self.app.qtrhour.update(datetime.now())
            print(datetime.now())
            log.info(
                "requesting info for the following timeframe today: {} nexthour: {} minutes: {}"
                .format(date.today().day, nexthour + 1, getqtr))
            bars_15m = self.get_bars_data(dataContract, "2 D", "15 mins",
                                          date.today().day, nexthour + 1,
                                          getqtr)
            x = np.array(bars_15m)
            log.debug("15 min bars {}".format(bars_15m[-1]))
            #sef.app. barupdateEvent_15m(baas_15m, True)
            #aars_15m.updateEvent += self.app.barupdateEvent_15m
            log.info("Got 15m data subscription")
            cci, avg, cci_prior, averageh, cci3 = calculate_cci(bars_15m)
            atr, atrprior = calculate_atr(bars_15m)
            bband_width, bband_b, bband_width_prior, bband_b_prior = calculate_bbands(
                bars_15m)
            log.info("starting 15 minutes".format(datetime.now()))
            log.info("CCI:      {} ".format(cci))
            log.info("CCIA      {} ".format(avg))
            log.info("CCIP      {} ".format(cci_prior))
            log.info("CCIPA:    {} ".format(averageh))
            log.info("ATR:      {} ".format(atr))
            log.info("bband w:  {} ".format(bband_width))
            log.info("bband p:  {} ".format(bband_b))
            qtrtime = datetime.now()
            #key_arr = []
            if (cci > cci_prior
                    and cci_prior < cci3) or (cci < cci_prior
                                              and cci_prior > cci3):
                crossed = True
                tradenow = True
                csv_row = "'" + str(datetime.now()) + ",'long'"
                key_arr[0] = "long"
            else:
                crossed = True
                tradenow = True
                csv_row = "'" + str(datetime.now()) + ",'short'"
                key_arr[0] = "short"
            csv_row += ",'" + str(crossed) + "'," + str(cci) + "," + str(
                avg) + "," + str(cci_prior) + "," + str(averageh) + "," + str(
                    atr) + "," + str(bband_width) + "," + str(bband_b)
            print(key_arr)
            key_arr[1] = categories.categorize_atr15(atr)
            key_arr[4] = categories.categorize_cci_15(cci)
            key_arr[5] = categories.categorize_cci_15_avg(avg)
            key_arr[8] = categories.categorize_BBW15(bband_width)
            key_arr[9] = categories.categorize_BBb15(bband_b)
            stat = "check crossed status"

            #print("printing self app ********************************************")
            #print(Indicator.data)
            self.app.status1.update(stat)
            self.app.crossover.update(crossed)
            self.app.cci15.update(f"{cci:.02f}")
            self.app.cci15_av.update(f"{avg:.02f}")
            self.app.cci15p_av.update(f"{averageh:.02f}")
            self.app.cci15p.update(f"{cci_prior:.02f}")
            self.app.atr15.update(f"{atr:.02f}")
            self.app.bband15_width.update(f"{bband_width:.04f}")
            self.app.bband15_b.update(f"{bband_b:.04f}")
            self.app.qtrhour.update(qtrtime)

            #1 hour data
            test = (datetime(int(date.today().year), int(date.today().month),
                             int(nextday), int(nexthour), int(getqtr), int(0)))
            #log.info("next datetime for 1 hour - should be 1 hour behind current hour {}".format(test))
            log.info(
                "requesting info for the following timeframe today: {} nexthour: {} minutes: {} "
                .format(date.today().day, nexthour, 0))
            bars_1h = self.get_bars_data(dataContract, "5 D", "1 hour",
                                         date.today().day, nexthour, 0)
            cci, avg, cci_prior, averageh, cci3 = calculate_cci(bars_1h)
            log.debug("bars_1h {}".format(bars_1h[-1]))
            atr, atrprior = calculate_atr(bars_1h)
            bband_width, bband_b, bband_width_prior, bband_b_prior = calculate_bbands(
                bars_1h)
            csv_row += "," + str(cci) + "," + str(avg) + "," + str(
                atr) + "," + str(bband_width) + "," + str(bband_b)
            key_arr[2] = categories.categorize_atr1h(atr)
            key_arr[6] = categories.categorize_cci_1h(avg)
            key_arr[10] = categories.categorize_BBW1h(bband_width)
            key_arr[11] = categories.categorize_BBb1h(bband_b)
            log.info("starting 1H ")
            log.info("CCI       {} ".format(cci))
            log.info("CCIA:     {} ".format(avg))
            log.info("ATR:      {} ".format(atr))
            log.info("bband w:  {} ".format(bband_width))
            log.info("bband p:  {} ".format(bband_b))
            qtrtime = datetime.now()
            self.app.cci1h.update(f"{cci:.02f}")
            self.app.cci1h_av.update(f"{avg:.02f}")
            self.app.bband1h_b.update(f"{bband_b:.04f}")
            self.app.bband1h_width.update(f"{bband_width:.04f}")
            self.app.atr1h.update(f"{atr:.02f}")

            log.info(
                "requesting info for the following timeframe today: nextday: {} hour: {} minute: {} "
                .format((nextday - 1), 0, 0))
            bars_1d = self.get_bars_data(dataContract, "75 D", "1 day",
                                         nextday - 1, 0, 0)
            log.debug("1d min bars {}".format(bars_1d[-1]))
            cci, avg, cci_prior, averageh, cci3 = calculate_cci(bars_1d)
            atr, atrprior = calculate_atr(bars_1d)
            bband_width, bband_b, bband_width_prior, bband_b_prior = calculate_bbands(
                bars_1d)
            csv_row += "," + str(cci) + "," + str(avg) + "," + str(
                atr) + "," + str(bband_width) + "," + str(bband_b)
            key_arr[3] = categories.categorize_atr1d(atr)
            key_arr[7] = categories.categorize_cci_1d(avg)
            key_arr[12] = categories.categorize_BBW1d(bband_width)
            key_arr[13] = categories.categorize_BBb1d(bband_b)
            log.info("starting 1H ")
            log.info("starting 1D ")
            log.info("CCIP      {} ".format(cci))
            log.info("CCIPA:    {} ".format(avg))
            log.info("ATR:      {} ".format(atr))
            log.info("bband w:  {} ".format(bband_width))
            log.info("bband p:  {} ".format(bband_b))
            qtrtime = datetime.now()
            qtrtime = datetime.now()
            self.app.cci1d.update(f"{cci:.02f}")
            self.app.cci1d_av.update(f"{avg:.02f}")
            self.app.bband1d_b.update(f"{bband_b:.04f}")
            self.app.bband1d_width.update(f"{bband_width:.04f}")
            self.app.atr1d.update(f"{atr:.02f}")
            if tradenow:
                csv_file = csv.reader(open('data/ccibb.csv', "rt"),
                                      delimiter="'")
                for row in csv_file:
                    if (''.join(key_arr)) == row[0]:
                        print("we have a match in ccibb.csv")
                        print(row)
                        ccibb_trade = True
                csv_file = csv.reader(open('data/cci.csv', "rt"),
                                      delimiter="'")
                for row in csv_file:
                    if (''.join(key_arr[0:7])) == row[0]:
                        print("we have a match in cci.csv")
                        print(row)
                        cci_trade = True
            csv_row += "," + (''.join(key_arr)) + "," + str(
                ccibb_trade) + "," + str(ccibb_trade)
            with open('data/hist15.csv', mode='a') as hist15:
                histwriter = csv.writer(hist15,
                                        delimiter=',',
                                        quotechar='"',
                                        quoting=csv.QUOTE_MINIMAL)
                histwriter.writerow([csv_row])
            print("key array comming *************************")
            print(''.join(key_arr))
            log.info("key array {}".format(key_arr))
            #key_arr.clear()
            tradenow = False
            cci_trade = False
            ccibb_trade = False
예제 #10
0
 def symbolSamples(self, reqId, contractDescriptions):
     cds = [ContractDescription(
             **cd.__dict__) for cd in contractDescriptions]
     for cd in cds:
         cd.contract = Contract(**cd.contract.__dict__)
     self._endReq(reqId, cds)
예제 #11
0
 def contractDetails(self, reqId, contractDetails):
     cd = ContractDetails(**contractDetails.__dict__)
     cd.summary = Contract(**cd.summary.__dict__)
     if cd.secIdList:
         cd.secIdList = [TagValue(s.tag, s.value) for s in cd.secIdList]
     self._results[reqId].append(cd)
예제 #12
0
    def roll_positions(self, positions, right):
        for position in positions:
            symbol = position.contract.symbol

            sell_ticker = self.find_eligible_contracts(
                symbol,
                right,
                excluded_expirations=[
                    position.contract.lastTradeDateOrContractMonth
                ],
            )
            self.wait_for_midpoint_price(sell_ticker)

            quantity = abs(position.position)

            position.contract.exchange = "SMART"
            [buy_ticker] = self.ib.reqTickers(position.contract)
            self.wait_for_midpoint_price(buy_ticker)

            price = midpoint_or_market_price(
                buy_ticker) - midpoint_or_market_price(sell_ticker)

            # Create combo legs
            comboLegs = [
                ComboLeg(
                    conId=position.contract.conId,
                    ratio=1,
                    exchange="SMART",
                    action="BUY",
                ),
                ComboLeg(
                    conId=sell_ticker.contract.conId,
                    ratio=1,
                    exchange="SMART",
                    action="SELL",
                ),
            ]

            # Create contract
            combo = Contract(
                secType="BAG",
                symbol=symbol,
                currency="USD",
                exchange="SMART",
                comboLegs=comboLegs,
            )

            # Create order
            order = LimitOrder(
                "BUY",
                quantity,
                round(price, 2),
                algoStrategy="Adaptive",
                algoParams=[TagValue("adaptivePriority", "Patient")],
                tif="DAY",
            )

            # Submit order
            trade = self.wait_for_trade_submitted(
                self.ib.placeOrder(combo, order))
            click.secho("Order submitted", fg="green")
            click.secho(f"{trade}", fg="green")
예제 #13
0
파일: asex.py 프로젝트: dafa321/ib_tools
def lookup_contracts(symbols):
    return [Contract(**s) for s in symbols]
예제 #14
0
    def run(self):
        """ Execute the algorithm """
        key_arr = [
            'blank', 'ATR15', 'ATR1', 'ATRD', 'CCI15', 'CCIA15', 'CCIA1h',
            'CCIA1d', 'BBW15', 'BBb15', 'BBW1h', 'BBb1h', 'BBW1d', 'BBb1d'
        ]
        tradenow = False
        not_finished = True
        tradenow = False
        cci_trade = False
        ccibb_trade = False
        while not_finished:
            print("top of algo run self")
            crossed = False
            self.app.crossover.update(crossed)
            contContract = get_contract(self)
            #print(contract.tradingHours.split(";"))
            #open_today = helpers.is_open_today(contract)
            #print("open today ",open_today)
            dataContract = Contract(exchange=config.EXCHANGE,
                                    secType="FUT",
                                    localSymbol=contContract.localSymbol)
            log.info("Got Contract: {}".format(dataContract.localSymbol))
            self.app.contract.update(dataContract.localSymbol)
            wait_time, datetime_15, datetime_1h, datetime_1d = self.define_times(
            )
            log.info(
                "next datetime for 15 minutes - should be 15 minutes ahead of desired nextqtr{}"
                .format(wait_time))
            #
            #nextqtr = datetime.now().minute + 1
            #print ("we manually overwrote start time")
            #print (nextqtr)
            #
            self.ib.waitUntil(wait_time)
            # 15 Minute Data
            self.app.qtrhour.update(wait_time)
            log.info("requesting info for the following timeframe today: {} ".
                     format(wait_time))
            bars_15m = self.get_bars_data(dataContract, "2 D", "15 mins",
                                          datetime_15)
            x = np.array(bars_15m)
            log.info("15 min bars {}".format(bars_15m[-1]))
            #sef.app. barupdateEvent_15m(baas_15m, True)
            #aars_15m.updateEvent += self.app.barupdateEvent_15m
            log.info("Got 15m data subscription")
            cci, avg, cci_prior, averageh, cci3 = calculate_cci(bars_15m)
            atr, atrprior = calculate_atr(bars_15m)
            bband_width, bband_b, bband_width_prior, bband_b_prior = calculate_bbands(
                bars_15m)
            log.info("starting 15 minutes".format(datetime.now()))
            log.info("CCI:      {} ".format(cci))
            log.info("CCIA      {} ".format(avg))
            log.info("CCIP      {} ".format(cci_prior))
            log.info("CCIPA:    {} ".format(averageh))
            log.info("ATR:      {} ".format(atr))
            log.info("bband w:  {} ".format(bband_width))
            log.info("bband p:  {} ".format(bband_b))
            qtrtime = datetime.now()
            #key_arr = []
            if cci > cci_prior and cci_prior < cci3:
                crossed = True
                tradenow = True
                csv_row = "'" + str(datetime.now()) + ",'long'"
                key_arr[0] = "long"
            elif cci < cci_prior and cci_prior > cci3:
                crossed = True
                tradenow = True
                csv_row = "'" + str(datetime.now()) + ",'short'"
                key_arr[0] = "short"
            else:
                csv_row = "'" + str(datetime.now()) + ",'flat'"
                crossed = False
                tradenow = False
            csv_row += ",'" + str(crossed) + "'," + str(cci) + "," + str(
                avg) + "," + str(cci_prior) + "," + str(averageh) + "," + str(
                    atr) + "," + str(bband_width) + "," + str(bband_b)
            print(key_arr)
            key_arr[1] = categories.categorize_atr15(atr)
            key_arr[4] = categories.categorize_cci_15(cci)
            key_arr[5] = categories.categorize_cci_15_avg(avg)
            key_arr[8] = categories.categorize_BBW15(bband_width)
            key_arr[9] = categories.categorize_BBb15(bband_b)
            stat = "check crossed status"

            #print("printing self app ********************************************")
            #print(Indicator.data)
            self.app.status1.update(stat)
            self.app.crossover.update(crossed)
            self.app.cci15.update(f"{cci:.02f}")
            self.app.cci15_av.update(f"{avg:.02f}")
            self.app.cci15p_av.update(f"{averageh:.02f}")
            self.app.cci15p.update(f"{cci_prior:.02f}")
            self.app.atr15.update(f"{atr:.02f}")
            self.app.bband15_width.update(f"{bband_width:.04f}")
            self.app.bband15_b.update(f"{bband_b:.04f}")
            self.app.qtrhour.update(qtrtime)

            #1 hour data
            log.info(
                "next datetime for 1 hour - should be 1 hour behind current hour {}"
                .format(datetime_1h))
            bars_1h = self.get_bars_data(dataContract, "5 D", "1 hour",
                                         datetime_1h)
            cci, avg, cci_prior, averageh, cci3 = calculate_cci(bars_1h)
            log.info("bars_1h {}".format(bars_1h[-1]))
            atr, atrprior = calculate_atr(bars_1h)
            bband_width, bband_b, bband_width_prior, bband_b_prior = calculate_bbands(
                bars_1h)
            csv_row += "," + str(cci) + "," + str(avg) + "," + str(
                atr) + "," + str(bband_width) + "," + str(bband_b)
            key_arr[2] = categories.categorize_atr1h(atr)
            key_arr[6] = categories.categorize_cci_1h(avg)
            key_arr[10] = categories.categorize_BBW1h(bband_width)
            key_arr[11] = categories.categorize_BBb1h(bband_b)
            log.info("starting 1H ")
            log.info("CCI       {} ".format(cci))
            log.info("CCIA:     {} ".format(avg))
            log.info("ATR:      {} ".format(atr))
            log.info("bband w:  {} ".format(bband_width))
            log.info("bband p:  {} ".format(bband_b))
            qtrtime = datetime.now()
            self.app.cci1h.update(f"{cci:.02f}")
            self.app.cci1h_av.update(f"{avg:.02f}")
            self.app.bband1h_b.update(f"{bband_b:.04f}")
            self.app.bband1h_width.update(f"{bband_width:.04f}")
            self.app.atr1h.update(f"{atr:.02f}")

            log.info(
                "requesting info for the following timeframe today: nextday: ".
                format(datetime_1d))
            bars_1d = self.get_bars_data(dataContract, "75 D", "1 day",
                                         datetime_1d)
            log.info("1d min bars {}".format(bars_1d[-1]))
            cci, avg, cci_prior, averageh, cci3 = calculate_cci(bars_1d)
            atr, atrprior = calculate_atr(bars_1d)
            bband_width, bband_b, bband_width_prior, bband_b_prior = calculate_bbands(
                bars_1d)
            csv_row += "," + str(cci) + "," + str(avg) + "," + str(
                atr) + "," + str(bband_width) + "," + str(bband_b)
            key_arr[3] = categories.categorize_atr1d(atr)
            key_arr[7] = categories.categorize_cci_1d(avg)
            key_arr[12] = categories.categorize_BBW1d(bband_width)
            key_arr[13] = categories.categorize_BBb1d(bband_b)
            log.info("starting 1H ")
            log.info("starting 1D ")
            log.info("CCIP      {} ".format(cci))
            log.info("CCIPA:    {} ".format(avg))
            log.info("ATR:      {} ".format(atr))
            log.info("bband w:  {} ".format(bband_width))
            log.info("bband p:  {} ".format(bband_b))
            qtrtime = datetime.now()
            qtrtime = datetime.now()
            self.app.cci1d.update(f"{cci:.02f}")
            self.app.cci1d_av.update(f"{avg:.02f}")
            self.app.bband1d_b.update(f"{bband_b:.04f}")
            self.app.bband1d_width.update(f"{bband_width:.04f}")
            self.app.atr1d.update(f"{atr:.02f}")
            if tradenow:
                csv_file = csv.reader(open('data/ccibb.csv', "rt"),
                                      delimiter="'")
                for row in csv_file:
                    if (''.join(key_arr)) == row[0]:
                        print("we have a match in ccibb.csv")
                        print("found a match in CCIBB ", row)
                        status_done = self.row_results(self, row)
                        ccibb_trade = True
                csv_file = csv.reader(open('data/cci.csv', "rt"),
                                      delimiter="'")
                for row in csv_file:
                    if (''.join(key_arr[0:8])) == row[0]:
                        print("we have a match in cci.csv")
                        print("found a math in CCI ", row)
                        status_done = self.row_results(self, row)
                        cci_trade = True
            csv_row += "," + (''.join(key_arr)) + "," + (''.join(
                key_arr[0:8])) + "," + str(ccibb_trade) + "," + str(
                    ccibb_trade)
            with open('data/hist15.csv', mode='a') as hist15:
                histwriter = csv.writer(hist15,
                                        delimiter=',',
                                        quotechar='"',
                                        quoting=csv.QUOTE_MINIMAL)
                histwriter.writerow([csv_row])
            tradenow = False
            cci_trade = False
            ccibb_trade = False
            print(
                "end of run self **********************************************************************************************"
            )
예제 #15
0
def start(config):
    import toml
    import thetagang.config_defaults as config_defaults

    with open(config, "r") as f:
        config = toml.load(f)

    config = normalize_config(config)

    validate_config(config)

    click.secho(f"Config:", fg="green")
    click.echo()

    click.secho(f"  Account details:", fg="green")
    click.secho(
        f"    Number                   = {config['account']['number']}",
        fg="cyan")
    click.secho(
        f"    Cancel existing orders   = {config['account']['cancel_orders']}",
        fg="cyan",
    )
    click.secho(
        f"    Margin usage             = {config['account']['margin_usage']} ({config['account']['margin_usage'] * 100}%)",
        fg="cyan",
    )
    click.secho(
        f"    Market data type         = {config['account']['market_data_type']}",
        fg="cyan",
    )
    click.echo()

    click.secho(f"  Roll options when either condition is true:", fg="green")
    click.secho(
        f"    Days to expiry          <= {config['roll_when']['dte']} and P&L >= {config['roll_when']['min_pnl']} ({config['roll_when']['min_pnl'] * 100}%)",
        fg="cyan",
    )
    click.secho(
        f"    P&L                     >= {config['roll_when']['pnl']} ({config['roll_when']['pnl'] * 100}%)",
        fg="cyan",
    )

    click.echo()
    click.secho(f"  When contracts are ITM:", fg="green")
    click.secho(
        f"    Roll puts               = {config['roll_when']['puts']['itm']}",
        fg="cyan",
    )
    click.secho(
        f"    Roll calls              = {config['roll_when']['calls']['itm']}",
        fg="cyan",
    )

    click.echo()
    click.secho(f"  Write options with targets of:", fg="green")
    click.secho(f"    Days to expiry          >= {config['target']['dte']}",
                fg="cyan")
    click.secho(f"    Default delta           <= {config['target']['delta']}",
                fg="cyan")
    if "puts" in config["target"]:
        click.secho(
            f"    Delta for puts          <= {config['target']['puts']['delta']}",
            fg="cyan",
        )
    if "calls" in config["target"]:
        click.secho(
            f"    Delta for calls         <= {config['target']['calls']['delta']}",
            fg="cyan",
        )
    click.secho(
        f"    Maximum new contracts    = {config['target']['maximum_new_contracts']}",
        fg="cyan",
    )
    click.secho(
        f"    Minimum open interest    = {config['target']['minimum_open_interest']}",
        fg="cyan",
    )

    click.echo()
    click.secho(f"  Symbols:", fg="green")
    for s in config["symbols"].keys():
        c = config["symbols"][s]
        c_delta = f"{get_target_delta(config, s, 'C'):.2f}".rjust(4)
        p_delta = f"{get_target_delta(config, s, 'P'):.2f}".rjust(4)
        weight = f"{c['weight']:.2f}".rjust(4)
        weight_p = f"{(c['weight'] * 100):.1f}".rjust(4)
        click.secho(
            f"    {s.rjust(5)} weight = {weight} ({weight_p}%), delta = {p_delta}p, {c_delta}c",
            fg="cyan",
        )
    assert (sum([
        config["symbols"][s]["weight"] for s in config["symbols"].keys()
    ]) == 1.0)
    click.echo()

    if config.get("ib_insync", {}).get("logfile"):
        util.logToFile(config["ib_insync"]["logfile"])

    # TWS version is pinned to current stable
    ibc = IBC(978, **config["ibc"])

    def onConnected():
        portfolio_manager.manage()

    ib = IB()
    ib.connectedEvent += onConnected

    completion_future = asyncio.Future()
    portfolio_manager = PortfolioManager(config, ib, completion_future)

    probeContractConfig = config["watchdog"]["probeContract"]
    watchdogConfig = config.get("watchdog")
    del watchdogConfig["probeContract"]
    probeContract = Contract(
        secType=probeContractConfig["secType"],
        symbol=probeContractConfig["symbol"],
        currency=probeContractConfig["currency"],
        exchange=probeContractConfig["exchange"],
    )

    watchdog = Watchdog(ibc, ib, probeContract=probeContract, **watchdogConfig)

    watchdog.start()
    ib.run(completion_future)
    watchdog.stop()
    ibc.terminate()
예제 #16
0
    def run(self):
        """ Execute the algorithm """
        key_arr = ['blank','ATR15','ATR1','ATRD','CCI15','CCIA15','CCIA1h','CCIA1d','BBW15','BBb15','BBW1h','BBb1h','BBW1d','BBb1d']
        tradenow = False
        not_finished = True
        pendingshort = False
        pendinglong = False
        tradenow = False
        cci_trade = False
        ccibb_trade = False
        while not_finished:
            print ("top of algo run self")
            #top of logic - want to check status as we enter a new bar/hour/day/contract
            crossed = False
            self.app.crossover.update(crossed)
            contContract, contracthours = get_contract(self)
            # NEW
            tradeContract = self.ib.qualifyContracts(contContract)   # gives all the details of a contract so we can trade it
            #print("fully qualified trading Contract: ",tradeContract)
            positions = self.ib.positions()
            open = self.have_position(positions)
            open_today = helpers.is_open_today(contracthours)
            dataContract = Contract(exchange=config.EXCHANGE, secType="FUT", localSymbol=contContract.localSymbol)
            log.info("Got Contract: {}".format(dataContract.localSymbol))
            self.app.contract.update(dataContract.localSymbol)
            wait_time, datetime_15, datetime_1h, datetime_1d = self.define_times()
            log.info("next datetime for 15 minutes - should be 15 minutes ahead of desired nextqtr{}".format(wait_time))
            #
            # starting the analysis section
            #
            self.ib.waitUntil(wait_time)
            #
            # 15 Minute Data
            #
            self.app.qtrhour.update(wait_time)
            log.info("requesting info for the following timeframe today: {} ".format(wait_time))
            bars_15m = self.get_bars_data(dataContract,"2 D","15 mins",datetime_15)
            x = np.array(bars_15m)
            log.info("15 min bars {}".format(bars_15m[-1]))
            cci, avg, cci_prior, averageh, cci3 = calculate_cci(bars_15m)
            atr, atrprior =  calculate_atr(bars_15m)
            bband_width, bband_b,bband_width_prior, bband_b_prior = calculate_bbands(bars_15m)
            log.info("starting 15 minutes".format(datetime.now()))
            log.info("CCI:      {} ".format(cci))
            log.info("CCIA      {} ".format(avg))
            log.info("CCIP      {} ".format(cci_prior))
            log.info("CCIPA:    {} ".format(averageh))
            log.info("ATR:      {} ".format(atr))
            log.info("bband w:  {} ".format(bband_width))
            log.info("bband p:  {} ".format(bband_b))
            qtrtime = datetime.now()
            if cci > avg and cci_prior < averageh:
                crossed = True
                print("crossed long",crossed)
                tradenow = True
                csv_row = "'"+str(datetime.now())+",'long'"
                key_arr[0] = "long"
            elif cci < avg and cci_prior > averageh:
                crossed = True
                tradenow = True
                print("crossed short",crossed)
                csv_row = "'"+str(datetime.now())+",'short'"
                key_arr[0] = "short"
            else:
                csv_row = "'"+str(datetime.now())+",'cash'"
                crossed = False
                tradenow = False
                print("NOT CROSSED ",crossed)
            print("csv row crossed ",csv_row)
            #if abs(cci - avg) > config.SPREAD:
            #    pending = True
            csv_header = "Date,Status,Crossed,CCI15,CCIA15,CCI15P,CCIA15P,ATR15,BBw15,BBB15"
            csv_row += ",'"+str(crossed)+"',"+str(cci)+","+str(avg)+","+str(cci_prior)+","+str(averageh)+","+str(atr)+","+str(bband_width)+","+str(bband_b)
            print("csv row 15",csv_row)
            key_arr[1] = categories.categorize_atr15(atr)
            key_arr[4] = categories.categorize_cci_15(cci)
            key_arr[5] = categories.categorize_cci_15_avg(avg)
            key_arr[8] = categories.categorize_BBW15(bband_width)
            key_arr[9] = categories.categorize_BBb15(bband_b)
            stat = "check crossed status"

            self.app.status1.update(stat)
            self.app.crossover.update(crossed)
            self.app.cci15.update(f"{cci:.02f}")
            self.app.cci15_av.update(f"{avg:.02f}")
            self.app.cci15p_av.update(f"{averageh:.02f}")
            self.app.cci15p.update(f"{cci_prior:.02f}")
            self.app.atr15.update(f"{atr:.02f}")
            self.app.bband15_width.update(f"{bband_width:.04f}")
            self.app.bband15_b.update(f"{bband_b:.04f}")
            self.app.qtrhour.update(qtrtime)
            
            
            #1 hour data 
            log.info("next datetime for 1 hour - should be 1 hour behind current hour {}".format(datetime_1h))
            bars_1h = self.get_bars_data(dataContract,"5 D","1 hour",datetime_1h)
            cci, avg, cci_prior, averageh, cci3 = calculate_cci(bars_1h)
            log.info("bars_1h {}".format(bars_1h[-1]))
            atr,atrprior = calculate_atr(bars_1h)
            bband_width, bband_b,bband_width_prior, bband_b_prior = calculate_bbands(bars_1h)
            csv_row += ","+str(cci)+","+str(avg)+","+str(atr)+","+str(bband_width)+","+str(bband_b)
            print("csv row 1 hour ",csv_row)
            csv_header += ",CCI1h,CCIA1h,ATR1h,BBW1h,BBB1h"
            key_arr[2] = categories.categorize_atr1h(atr)
            key_arr[6] = categories.categorize_cci_1h(avg)
            key_arr[10] = categories.categorize_BBW1h(bband_width)
            key_arr[11] = categories.categorize_BBb1h(bband_b)
            log.info("starting 1H ")
            log.info("CCI       {} ".format(cci))
            log.info("CCIA:     {} ".format(avg))
            log.info("ATR:      {} ".format(atr))
            log.info("bband w:  {} ".format(bband_width))
            log.info("bband p:  {} ".format(bband_b))
            qtrtime = datetime.now()
            self.app.cci1h.update(f"{cci:.02f}")
            self.app.cci1h_av.update(f"{avg:.02f}")
            self.app.bband1h_b.update(f"{bband_b:.04f}")
            self.app.bband1h_width.update(f"{bband_width:.04f}")
            self.app.atr1h.update(f"{atr:.02f}")
            
            log.info("requesting info for the following timeframe today: nextday: ".format(datetime_1d))
            bars_1d = self.get_bars_data(dataContract,"75 D","1 day",datetime_1d)
            log.info("1d min bars {}".format(bars_1d[-1]))
            cci, avg, cci_prior, averageh, cci3 = calculate_cci(bars_1d)
            atr, atrprior = calculate_atr(bars_1d)
            bband_width, bband_b,bband_width_prior, bband_b_prior = calculate_bbands(bars_1d)
            csv_row += ","+str(cci)+","+str(avg)+","+str(atr)+","+str(bband_width)+","+str(bband_b)
            print("csv row daily ",csv_row)
            csv_header += ",CCI1d,CCIA1d,ATR1d,BBB1d,BBW1d"
            key_arr[3] = categories.categorize_atr1d(atr)
            key_arr[7] = categories.categorize_cci_1d(avg)
            key_arr[12] = categories.categorize_BBW1d(bband_width)
            key_arr[13] = categories.categorize_BBb1d(bband_b)
            log.info("starting 1D ")
            log.info("CCIP      {} ".format(cci))
            log.info("CCIPA:    {} ".format(avg))
            log.info("ATR:      {} ".format(atr))
            log.info("bband w:  {} ".format(bband_width))
            log.info("bband p:  {} ".format(bband_b))
            qtrtime = datetime.now()
            qtrtime = datetime.now()
            self.app.cci1d.update(f"{cci:.02f}")
            self.app.cci1d_av.update(f"{avg:.02f}")
            self.app.bband1d_b.update(f"{bband_b:.04f}")
            self.app.bband1d_width.update(f"{bband_width:.04f}")
            self.app.atr1d.update(f"{atr:.02f}")
            print("tradenow: ",tradenow)
            if tradenow:
                print("Tradeing this bar ",(''.join(key_arr))," - ",''.join(key_arr[0:8]))
                csv_file1 = csv.reader(open('data/ccibb.csv', "rt"), delimiter = ",")
                for row1 in csv_file1:
                    print("ccibb row: ",row1[0])
                    if ((''.join(key_arr)) == row1[0]):
                            log.info("we have a match in ccibb.csv")
                            print("found a match in CCIBB ",row1[0])
                            ccibb_trade = True
                            tradenow = False
                            status_done = self.row_results(row1,cci_trade,ccibb_trade)
                            break
                csv_file2 = csv.reader(open('data/cci.csv', "rt"), delimiter = ",")
                for row2 in csv_file2:
                    print("cci row: ",row2[0])
                    if ((''.join(key_arr[0:8])) == row2[0]):
                            print("we have a match in cci.csv")
                            print("found a math in CCI ",row2[0])
                            cci_trade = True
                            tradenow = False
                            status_done = self.row_results(row2,cci_trade,ccibb_trade)
                            break
            print("did we find a match?  If true than no ",tradenow)
            csv_row += ","+(''.join(key_arr))+","+(''.join(key_arr[0:8]))+","+str(cci_trade)+","+str(ccibb_trade)+","+str(pendinglong)+","+str(pendingshort)
            csv_header += ",CCIbbKey,CCIKey,CCI Trade,CCIbbTrade,Pending Long, Pending Short"
            print("csv row right before csv write ",csv_row)
            with open('data/hist15.csv', mode='a') as hist15:
                histwriter = csv.writer(hist15, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
                #histwriter.writerow([csv_header])
                #histwriter.writerow([csv_row])
            tradenow = False
            cci_trade = False
            ccibb_trade = False
            print ("end of run self **********************************************************************************************")
예제 #17
0
    def roll_positions(self,
                       positions,
                       right,
                       account_summary,
                       portfolio_positions={}):
        for position in positions:
            try:
                symbol = position.contract.symbol
                strike_limit = get_strike_limit(self.config, symbol, right)
                if right.startswith("C"):
                    strike_limit = math.ceil(
                        max([strike_limit or 0] + [
                            p.averageCost for p in portfolio_positions[symbol]
                            if isinstance(p.contract, Stock)
                        ]))

                sell_ticker = self.find_eligible_contracts(
                    symbol,
                    self.get_primary_exchange(symbol),
                    right,
                    strike_limit,
                    exclude_expirations_before=position.contract.
                    lastTradeDateOrContractMonth,
                    exclude_first_exp_strike=position.contract.strike,
                )

                qty_to_roll = abs(position.position)
                maximum_new_contracts = self.get_maximum_new_contracts_for(
                    symbol,
                    self.get_primary_exchange(symbol),
                    account_summary,
                )
                from_dte = option_dte(
                    position.contract.lastTradeDateOrContractMonth)
                roll_when_dte = self.config["roll_when"]["dte"]
                if from_dte > roll_when_dte:
                    qty_to_roll = min([qty_to_roll, maximum_new_contracts])

                position.contract.exchange = "SMART"
                buy_ticker = self.get_ticker_for(position.contract,
                                                 midpoint=True)

                price = midpoint_or_market_price(
                    buy_ticker) - midpoint_or_market_price(sell_ticker)

                # Create combo legs
                comboLegs = [
                    ComboLeg(
                        conId=position.contract.conId,
                        ratio=1,
                        exchange="SMART",
                        action="BUY",
                    ),
                    ComboLeg(
                        conId=sell_ticker.contract.conId,
                        ratio=1,
                        exchange="SMART",
                        action="SELL",
                    ),
                ]

                # Create contract
                combo = Contract(
                    secType="BAG",
                    symbol=symbol,
                    currency="USD",
                    exchange="SMART",
                    comboLegs=comboLegs,
                )

                # Create order
                order = LimitOrder(
                    "BUY",
                    qty_to_roll,
                    round(price, 2),
                    algoStrategy="Adaptive",
                    algoParams=[TagValue("adaptivePriority", "Patient")],
                    tif="DAY",
                )

                to_dte = option_dte(
                    sell_ticker.contract.lastTradeDateOrContractMonth)
                from_strike = position.contract.strike
                to_strike = sell_ticker.contract.strike

                # Submit order
                trade = self.ib.placeOrder(combo, order)
                self.orders.append(trade)
                click.echo()
                click.secho(
                    f"Order submitted, current position={abs(position.position)}, qty_to_roll={qty_to_roll}, from_dte={from_dte}, to_dte={to_dte}, from_strike={from_strike}, to_strike={to_strike}, price={round(price,2)}, trade={trade}",
                    fg="green",
                )
            except RuntimeError as e:
                click.echo()
                click.secho(str(e), fg="red")
                click.secho(
                    "Error occurred when trying to roll position. Continuing anyway...",
                    fg="yellow",
                )
예제 #18
0
    def run(self):
        """ Execute the algorithm """
        # check for command line arguments
        # key_arr = ['blank','ATR15','ATR1','ATRD','CCI15','CCIA15','CCIA1h','CCIA1d','BBW15','BBb15','BBW1h','BBb1h','BBW1d','BBb1d']
        #log.info("Account values: {av}".format(av=self.ib.accountValues()))
        tradeNow, not_finished, pendingShort, pendingLong, pendingSkip, cci_trade, ccibb_trade, crossed, justStartedApp = False, True, False, False, False, False, False, False, True
        pendingCnt = 0
        # any variable that is used within the class will be defined with self
        if justStartedApp:
            pendingLong, pendingShort, pendingCnt = self.justStartedAppDirectionCheck(
            )
            #if not pendingLong and not pendingShort:
            #    pendingLong, pendingShort, pendingCnt = self.justStartedAppPendingCheck()
            justStartedApp = False
            # do we need to reset pending
            reviewIBTrades = orders.getListOfTrades(self.ib)
        while not_finished:
            log.info(
                "top of algo run self*************************************************"
            )

            #top of logic - want to check status as we enter a new bar/hour/day/contract
            contContract, contracthours = get_contract(
                self)  #basic information on continuious contact
            tradeContract = self.ib.qualifyContracts(contContract)[
                0]  # gives all the details of a contract so we can trade it
            open_long, open_short, long_position_qty, short_position_qty, account_qty = orders.countOpenPositions(
                self.ib, "")  # do we have an open position?
            self.app.shares.update(long_position_qty + short_position_qty)
            dataContract = Contract(exchange=config.EXCHANGE,
                                    secType="FUT",
                                    localSymbol=contContract.localSymbol)
            log.debug("Got Contract:{dc} local symbol {ls}".format(
                dc=dataContract, ls=dataContract.localSymbol))
            self.app.contract.update(dataContract.localSymbol)
            wait_time, self.datetime_15, self.datetime_1h, self.datetime_1d, self.log_time = self.define_times(
                self.ib)
            log.info(
                "next datetime for 15 minutes - should be 15 minutes ahead of desired nextqtr{wt} and current time {ct}"
                .format(wt=wait_time, ct=datetime.today()))
            # need to determine if this is normal trading hours or not
            dayNightProfileCCI, dayNightProfileCCIBB = self.duringOrAfterHours(
                self.ib, contracthours)
            #
            # debug
            #current_time = datetime.now()
            #wait_time = wait_time = current_time.replace(minute = 1,second=0)
            #
            #self.ib.disconnect()
            self.ib.waitUntil(wait_time)
            #self.ib.connect(config.HOST, config.PORT, clientId=config.CLIENTID,timeout=0)
            #log.debug("before loop start:{ls}".format(ls=datetime.now()))
            #self.ib.loopUntil(condition=self.ib.isConnected())   # rying to fix 1100 error on nightly reset
            #
            # first attempt at fix
            #try:
            #    logger.getLogger().info("Connecting...")
            #    self.ib.connect(config.HOST, config.PORT, clientId=config.CLIENTID,timeout=0)
            #    self.ib.reqMarketDataType(config.DATATYPE.value)
            #except NameError:    # got this block from https://groups.io/g/insync/message/4045
            #    self.num_disconnects += 1
            #    print(datetime.now(), 'Connection error exception', self.num_disconnects)
            #    self.ib.cancelHistoricalData(bars)
            #    log.info('Sleeping for 10sec...')
            #    self.ib.disconnect
            #    self.ib.sleep(10)
            #    self.ib.connect(config.HOST, config.PORT, clientId=config.CLIENTID,timeout=0)
            #
            if not self.backTest:
                stpSell, stpBuy = orders.countOpenOrders(
                    self.ib)  # don't want to execute covering
                log.info(
                    "we have the follow number of open stp orders for Sell: {sell} and Buy: {buy} "
                    .format(sell=stpSell, buy=stpBuy))
            #if datetime.now().hour == 0:
            #    log.info("0 hour and disconnecting".format(datetime.now(),datetime.now().hour))
            #    self.ib.disconnect()
            #    self.ib.sleep(500)
            #    self.ib.connect(config.HOST, config.PORT, clientId=config.CLIENTID)
            #    log.info("0 hour and re-connecting".format(datetime.now(),datetime.now().hour))
            #log.debug("after loop start:{ls}".format(ls=datetime.now()))
            #log.debug("requesting info for the following timeframe today: {} ".format(wait_time))
            bars_15m = calculations.Calculations(self.ib, dataContract, "2 D",
                                                 "15 mins", self.datetime_15,
                                                 False, 0)
            #rint("bars15m ",bars_15m)
            if bars_15m.atr < config.ATR_STOP_MIN:
                bars_1h = calculations.Calculations(self.ib, dataContract,
                                                    "5 D", "1 hour",
                                                    self.datetime_1h, True,
                                                    bars_15m.closePrice)
                modBuyStopLossPrice = bars_1h.buyStopLossPrice
                modSellStopLossPrice = bars_1h.sellStopLossPrice
                modTrailStopLoss = (bars_1h.sellStopLossPrice -
                                    bars_1h.buyStopLossPrice) / 2
            else:
                bars_1h = calculations.Calculations(self.ib, dataContract,
                                                    "5 D", "1 hour",
                                                    self.datetime_1h, False, 0)
                modBuyStopLossPrice = bars_15m.buyStopLossPrice
                modSellStopLossPrice = bars_15m.sellStopLossPrice
                modTrailStopLoss = (bars_1h.sellStopLossPrice -
                                    bars_1h.buyStopLossPrice) / 2
            bars_1d = calculations.Calculations(self.ib, dataContract, "75 D",
                                                "1 day", self.datetime_1d,
                                                False, 0)
            updated = self.update_tk(bars_15m, bars_1h, bars_1d)
            pendingLong, pendingShort, pendingCnt, pendingSkip, tradeNow, tradeAction, crossed = self.crossoverPending(
                bars_15m, pendingLong, pendingShort, pendingSkip, pendingCnt)
            cci_key, ccibb_key, summ_key = build_key_array(
                tradeAction, bars_15m, bars_1h, bars_1d)
            #setsum = self.setupsummary(summ_key)
            log.debug("tradeNow: {trade} pendingSkip {skip}".format(
                trade=tradeNow, skip=pendingSkip))
            log.debug(
                "going into tradenow: {tn}, backtest: {bt}, open long: {ol} and short: {os}"
                .format(tn=tradeNow,
                        bt=self.backTest,
                        ol=open_long,
                        os=open_long))
            #handeling existing position
            if crossed and (open_long or open_short) and not (
                    pendingLong
                    or pendingShort):  # need to close stp and open positions
                log.info(
                    "crossed and not pending so lets close stp and open positions.  Open Long: {ol} open short: {os} pending long: {pl} pending short: {ps}"
                    .format(ol=open_long,
                            os=open_short,
                            pl=pendingLong,
                            ps=pendingShort))
                allClosed = orders.closeOutMain(
                    self.ib, tradeContract,
                    False)  # we don't worry about whether we are long or short
            elif (not (pendingLong or
                       pendingShort)) and open_long and tradeAction == "Sell":
                log.info(
                    "Not pending we are open_long and tradeaction is sell so lets close out stp and open positions  Open Long: {ol} open short: {os} pending long: {pl} pending short: {ps}"
                    .format(ol=open_long,
                            os=open_short,
                            pl=pendingLong,
                            ps=pendingShort))
                allClosed = orders.closeOutMain(
                    self.ib, tradeContract,
                    False)  # we don't worry about whether we are long or short
            elif (not (pendingLong or
                       pendingShort)) and open_short and tradeAction == "Buy":
                log.info(
                    "Not pending we are open_short and tradeaction is buy so lets close out stp and open positions  Open Long: {ol} open short: {os} pending long: {pl} pending short: {ps}"
                    .format(ol=open_long,
                            os=open_short,
                            pl=pendingLong,
                            ps=pendingShort))
                allClosed = orders.closeOutMain(
                    self.ib, tradeContract,
                    False)  # we don't worry about whether we are long or short
            if tradeNow:
                log.info("tradeNow - Tradeing this bar {cci} - {ccibb}".format(
                    cci=cci_key, ccibb=ccibb_key))
                csv_file1 = csv.reader(open('data/ccibb.csv', "rt"),
                                       delimiter=",")
                #cci_key, ccibb_key = build_key_array(self, tradeAction, bars_15m, bars_1h, bars_1d)
                for row1 in csv_file1:
                    if ccibb_key == row1[0] and row1[
                            13] == "Y":  #13 is winrisk - whether we trade or not
                        #log.info("we have a match in ccibb.csv")
                        log.info(
                            "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
                        )
                        log.info(
                            " +++++++++++++++++++++++++++++++++++++++++++++++++ found a match in CCIBB "
                            .format(str(row1[0])))
                        log.info(
                            "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
                        )
                        ccibb_trade = True
                        quantity = 1
                        # do we need to close out current order
                        # do we need to close out current stop loss orders?
                        if not self.backTest:
                            fillStatus = orders.createOrdersMain(
                                self.ib, tradeContract, tradeAction, quantity,
                                dayNightProfileCCI, modBuyStopLossPrice,
                                modSellStopLossPrice, False, modTrailStopLoss,
                                bars_15m.closePrice)
                            log.info(
                                "logic.CCIbb: order placed, fillStatus: {fs}".
                                format(fs=fillStatus))
                        open_long, open_short, tradenow = False, False, False
                        status_done = self.row_results(row1, cci_trade,
                                                       ccibb_trade)
                        break
                    elif ccibb_key == row1[0] and row1[13] == "N":
                        log.info(
                            "Entry found in CCIBB but not traded.  See if this changes"
                        )
                        self.app.status1.update(
                            "Entry found in CCIBB but not traded.")
                        log.info("Profit  : {p}".format(p=row1[6]))
                        log.info("Orders  : {p}".format(p=row1[7]))
                        log.info("Wins $  : {p}".format(p=row1[10]))
                        log.info("Losses $: {p}".format(p=row1[11]))
                        log.info("Wins #  : {p}".format(p=row1[8]))
                        log.info("Losses #: {p}".format(p=row1[9]))
                        ccibb_trade = False
                csv_file2 = csv.reader(open('data/cci.csv', "rt"),
                                       delimiter=",")
                for row2 in csv_file2:
                    #rint("cci   row: ",row2[0],row2[13])
                    if cci_key == row2[0] and row2[13] == "Y":
                        log.info(
                            "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
                        )
                        log.info(
                            "+++++++++++++++++++++++++++++++++++++++++++++++++ we have a match in cci.csv - tradeAction"
                            .format(tradeAction))
                        log.info(
                            "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
                        )
                        cci_trade = True
                        quantity = 1
                        if not self.backTest:
                            fillStatus = orders.createOrdersMain(
                                self.ib, tradeContract, tradeAction, quantity,
                                dayNightProfileCCIBB, modBuyStopLossPrice,
                                modSellStopLossPrice, False, modTrailStopLoss,
                                bars_15m.closePrice)
                        open_long, open_short, tradenow = False, False, False
                        status_done = self.row_results(row2, cci_trade,
                                                       ccibb_trade)
                        break
                    elif cci_key == row2[0] and row2[13] == "N":
                        log.info(
                            "Entry found in CCI but not traded.  See if this changes"
                        )
                        self.app.status1.update(
                            "Entry found in CCI but not traded.")
                        log.info("Profit  : {p}".format(p=row2[6]))
                        log.info("Orders  : {p}".format(p=row2[7]))
                        log.info("Wins $  : {p}".format(p=row2[10]))
                        log.info("Losses $: {p}".format(p=row2[11]))
                        log.info("Wins #  : {p}".format(p=row2[8]))
                        log.info("Losses #: {p}".format(p=row2[9]))
                        cci_trade = True
                if tradeNow:
                    log.info(
                        "we did not find a match in CCI: {cci} or CCI BB: {ccib}"
                        .format(cci=cci_trade, ccib=ccibb_trade))
            #csv_row_add = helpers.build_csv_bars_row(","+(''.join(key_arr))+","+(''.join(key_arr[0:8]))+","+str(cci_trade)+","+str(ccibb_trade)+","+str(pendingLong)+","+str(pendingShort),True)
            wrote_bar_to_csv = helpers.build_csv_bars_row(
                self.log_time, tradeAction, bars_15m, bars_1h, bars_1d,
                pendingLong, pendingShort, pendingCnt, tradeNow, ccibb_trade,
                cci_trade, ccibb_key, cci_key)
            tradenow, cci_trade, ccibb_trade = False, False, False
            changed = orders.modifySTPOrder(self.ib, modBuyStopLossPrice,
                                            modSellStopLossPrice,
                                            bars_15m.closePrice)
예제 #19
0
    def roll_positions(self, positions, right, portfolio_positions={}):
        for position in positions:
            symbol = position.contract.symbol
            strike_limit = get_strike_limit(self.config, symbol, right)
            if right.startswith("C"):
                strike_limit = math.ceil(
                    max([strike_limit or 0] + [
                        p.averageCost for p in portfolio_positions[symbol]
                        if isinstance(p.contract, Stock)
                    ]))

            sell_ticker = self.find_eligible_contracts(
                symbol,
                self.get_primary_exchange(symbol),
                right,
                strike_limit,
                excluded_expirations=[
                    position.contract.lastTradeDateOrContractMonth
                ],
            )
            self.wait_for_midpoint_price(sell_ticker)

            quantity = abs(position.position)

            position.contract.exchange = "SMART"
            [buy_ticker] = self.ib.reqTickers(position.contract)
            self.wait_for_midpoint_price(buy_ticker)

            price = midpoint_or_market_price(
                buy_ticker) - midpoint_or_market_price(sell_ticker)

            # Create combo legs
            comboLegs = [
                ComboLeg(
                    conId=position.contract.conId,
                    ratio=1,
                    exchange="SMART",
                    action="BUY",
                ),
                ComboLeg(
                    conId=sell_ticker.contract.conId,
                    ratio=1,
                    exchange="SMART",
                    action="SELL",
                ),
            ]

            # Create contract
            combo = Contract(
                secType="BAG",
                symbol=symbol,
                currency="USD",
                exchange="SMART",
                comboLegs=comboLegs,
            )

            # Create order
            order = LimitOrder(
                "BUY",
                quantity,
                round(price, 2),
                algoStrategy="Adaptive",
                algoParams=[TagValue("adaptivePriority", "Patient")],
                tif="DAY",
            )

            # Submit order
            trade = self.ib.placeOrder(combo, order)
            self.orders.append(trade)
            click.echo()
            click.secho("Order submitted", fg="green")
            click.secho(f"{trade}", fg="green")
예제 #20
0
def justStartedAppDirectionCheck(self):
    log.debug(
        "justStartedAppDirectionCheck: Application just restarted.  Going through our checks"
    )
    # do we need to reverse positions?
    # first check to see if we have positions or open orders.  If not exit otherwise continue
    # Are we positioned in the wrong direction (i.e. long when we should be short?)  If so, we need to close STP and open open trades.
    # not going to take a position at this time.
    # the bars data is the current, not completed, bar so we have to go back to get closed bars.

    contContract, contracthours = logic.get_contract(
        self)  #basic information on continuious contact
    tradeContract = self.ib.qualifyContracts(contContract)[
        0]  # gives all the details of a contract so we can trade it
    open_long, open_short, long_position_qty, short_position_qty, account_qty = orders.countOpenPositions(
        self.ib, "")  # do we have an open position - not orders but positions?
    open_today, tradingDayRules = helpers.is_open_today(contracthours)
    wait_time, self.datetime_15, self.datetime_1h, self.datetime_1d, self.log_time = self.define_times(
        self.ib)
    dataContract = Contract(exchange=config.EXCHANGE,
                            secType="FUT",
                            localSymbol=contContract.localSymbol)
    bars_15m = calculations.Calculations(self.ib, dataContract, "2 D",
                                         "15 mins", self.datetime_15, False, 0)
    #rint("bars15 cci_third, ccia_third, cci_prior, ccia_prior, cci, ccia",bars_15m.cci_third,bars_15m.ccia_third,bars_15m.cci_prior, bars_15m.ccia_prior, bars_15m.cci, bars_15m.ccia)
    if (bars_15m.cci_prior > bars_15m.ccia_prior
            and open_short) or (bars_15m.cci_prior < bars_15m.ccia_prior
                                and open_long):
        log.debug(
            "justStartedAppDirectionCheck: we are in app start up and we need to reverse due to wrong direction"
        )
        allClosed = orders.closeOutMain(
            self.ib, tradeContract, True
        )  # we don't worry about whether we are long or short. just passing the contract, need to add order.  Second false is whether this is an opening order.  it is not
        log.debug(
            "justStartedAppDirectionCheck: crossed but not tradeNow so lets close stp and open positions"
        )
    else:
        log.debug(
            "justStartedAppDirectionCheck: we are in app start up and we DO NOT need to reverse due to wrong direction"
        )
    # now check if we should be pending on restart

    if (bars_15m.cci_four > bars_15m.ccia_four and bars_15m.cci_third < bars_15m.ccia_third and bars_15m.cci_prior < bars_15m.ccia_prior and \
    abs(bars_15m.cci_third - bars_15m.ccia_third) < config.SPREAD and abs(bars_15m.cci_prior - bars_15m.ccia_prior) < config.SPREAD) or \
    (bars_15m.cci_four < bars_15m.ccia_four and bars_15m.cci_third > bars_15m.ccia_third and bars_15m.cci_prior > bars_15m.ccia_prior and \
    abs(bars_15m.cci_third - bars_15m.ccia_third) < config.SPREAD and abs(bars_15m.cci_prior - bars_15m.ccia_prior) < config.SPREAD):
        log.debug(
            "justStartedAppDirectionCheck: we are in a second leg pending situation on start up"
        )
        if bars_15m.cci_prior > bars_15m.ccia_prior:
            return True, False, 2
        else:
            return False, True, 2
    elif (bars_15m.cci_third > bars_15m.ccia_third and bars_15m.cci_prior < bars_15m.ccia_prior and abs(bars_15m.cci_prior - bars_15m.ccia_prior) < config.SPREAD) or \
    (bars_15m.cci_third < bars_15m.ccia_third and bars_15m.cci_prior > bars_15m.ccia_prior and abs(bars_15m.cci_prior - bars_15m.ccia_prior) < config.SPREAD):
        log.debug(
            "justStartedAppDirectionCheck: we are in a first leg pending situation on start up"
        )
        if bars_15m.cci_prior > bars_15m.ccia_prior:
            return True, False, 1
        else:
            return False, True, 1
    else:
        log.debug(
            "justStartedAppDirectionCheck: we are not in an exiting pending pattern"
        )
        return False, False, 0
예제 #21
0
 def run(self):
     """ Execute the algorithm """
     key_arr = ['blank','ATR15','ATR1','ATRD','CCI15','CCIA15','CCIA1h','CCIA1d','BBW15','BBb15','BBW1h','BBb1h','BBW1d','BBb1d']
     tradenow = False
     not_finished = True
     pendingshort = False
     pendinglong = False      # this is when the cross over is not wide enough
     PendingLongCnt = 0
     PendingShortCnt = 0
     tradenow = False
     cci_trade = False
     ccibb_trade = False
     while not_finished:
         print ("top of algo run self*************************************************")
         #top of logic - want to check status as we enter a new bar/hour/day/contract
         crossed = False
         contContract, contracthours = get_contract(self) #basic information on continuious contact
         #i NEW
         tradeContract = self.ib.qualifyContracts(contContract)[0]   # gives all the details of a contract so we can trade it
         open_long, open_short, position_qty = self.have_position(self.ib.positions())   # do we have an open position?
         open_today = helpers.is_open_today(contracthours)
         dataContract = Contract(exchange=config.EXCHANGE, secType="FUT", localSymbol=contContract.localSymbol)
         log.debug("Got Contract: {}".format(dataContract.localSymbol))
         #pnl = self.ib.pnl()
         log.debug("account names: {}".format(self.ib.managedAccounts()))
         log.info("PNL : {PNL} ".format(PNL=self.ib.pnl("all")))
         self.app.contract.update(dataContract.localSymbol)
         wait_time, datetime_15, datetime_1h, datetime_1d = self.define_times()
         log.debug("next datetime for 15 minutes - should be 15 minutes ahead of desired nextqtr{}".format(wait_time))
         self.ib.waitUntil(wait_time)
         self.app.qtrhour.update(wait_time)
         log.debug("requesting info for the following timeframe today: {} ".format(wait_time))
         #
         #start of study
         #
         bars_15m = self.get_bars_data(dataContract,"2 D","15 mins",datetime_15)
         print("bar data close: ",bars_15m[-1].close)
         x = np.array(bars_15m)
         log.debug("15 min bars {}".format(str(bars_15m[-1])))
         cci, avg, cci_prior, averageh, cci3 = calculate_cci(bars_15m)
         atr, atrprior =  calculate_atr(bars_15m)
         bband_width, bband_b,bband_width_prior, bband_b_prior = calculate_bbands(bars_15m)
         logged_it = self.log_value("Starting 15 minutes", cci,avg,cci_prior, averageh,atr,bband_width,bband_b)
         qtrtime = datetime.now()
         print("stop loss = ",round((bars_15m[-1].close + (atr *2))*4,0)/4)
         if cci > avg and cci_prior < averageh:
             crossed = True
             tradenow = True
             csv_row = "'"+str(datetime.now())+",'long'"
             key_arr[0] = "long"
             tradeAction = "BUY"
             stoplossprice = round((bars_15m[-1].close - (atr * 2))*4,0)/4
         elif cci < avg and cci_prior > averageh:
             crossed = True
             tradenow = True
             csv_row = "'"+str(datetime.now())+",'short'"
             key_arr[0] = "short"
             tradeAction = "SELL"
             stoplossprice = round((bars_15m[-1].close + (atr * 2))*4,0)/4
         else:
             csv_row = "'"+str(datetime.now())+",'cash'"
             crossed = False
             tradenow = False
             stoplossprice = 0
             stoploss = 0
         if abs(cci - avg) > config.SPREAD:
             log.info("Pending ".format(cci-avg))
             pendinglong = True
             pendingshort = True
         csv_header = "Date,Status,Crossed,CCI15,CCIA15,CCI15P,CCIA15P,ATR15,BBw15,BBB15"
         csv_row += ",'"+str(crossed)+"',"+str(cci)+","+str(avg)+","+str(cci_prior)+","+str(averageh)+","+str(atr)+","+str(bband_width)+","+str(bband_b)
         key_arr[1] = categories.categorize_atr15(atr)
         key_arr[4] = categories.categorize_cci_15(cci)
         key_arr[5] = categories.categorize_cci_15_avg(avg)
         key_arr[8] = categories.categorize_BBW15(bband_width)
         key_arr[9] = categories.categorize_BBb15(bband_b)
         #
         #1 hour data 
         #
         log.debug("next datetime for 1 hour - should be 1 hour behind current hour {}".format(datetime_1h))
         bars_1h = self.get_bars_data(dataContract,"5 D","1 hour",datetime_1h)
         cci, avg, cci_prior, averageh, cci3 = calculate_cci(bars_1h)
         log.debug("bars_1h {}".format(str(bars_1h[-1])))
         atr,atrprior = calculate_atr(bars_1h)
         bband_width, bband_b,bband_width_prior, bband_b_prior = calculate_bbands(bars_1h)
         csv_row += ","+str(cci)+","+str(avg)+","+str(atr)+","+str(bband_width)+","+str(bband_b)
         csv_header += ",CCI1h,CCIA1h,ATR1h,BBW1h,BBB1h"
         key_arr[2] = categories.categorize_atr1h(atr)
         key_arr[6] = categories.categorize_cci_1h(avg)
         key_arr[10] = categories.categorize_BBW1h(bband_width)
         key_arr[11] = categories.categorize_BBb1h(bband_b)
         #logged_it = self.log_value("Starting 1 hour", cci,avg,cci_prior, averageh,atr,bband_width,bband_b)
         qtrtime = datetime.now()
         
         log.debug("requesting info for the following timeframe today: nextday: ".format(datetime_1d))
         bars_1d = self.get_bars_data(dataContract,"75 D","1 day",datetime_1d)
         log.debug("1d min bars {}".format(str(bars_1d[-1])))
         cci, avg, cci_prior, averageh, cci3 = calculate_cci(bars_1d)
         atr, atrprior = calculate_atr(bars_1d)
         bband_width, bband_b,bband_width_prior, bband_b_prior = calculate_bbands(bars_1d)
         csv_row += ","+str(cci)+","+str(avg)+","+str(atr)+","+str(bband_width)+","+str(bband_b)
         csv_header += ",CCI1d,CCIA1d,ATR1d,BBB1d,BBW1d"
         key_arr[3] = categories.categorize_atr1d(atr)
         key_arr[7] = categories.categorize_cci_1d(avg)
         key_arr[12] = categories.categorize_BBW1d(bband_width)
         key_arr[13] = categories.categorize_BBb1d(bband_b)
         #logged_it = self.log_value("Starting 1 Day", cci,avg,cci_prior, averageh,atr,bband_width,bband_b)
         qtrtime = datetime.now()
         setsum = self.setupsummary(key_arr)
         log.info("tradenow: {trade}".format(trade = tradenow))
         #
         # starting trade logic
         #
         # test buy
         if tradenow:
             log.info("Tradeing this bar {}".format(str(''.join(key_arr))," - ",''.join(key_arr[0:8])))
             csv_file1 = csv.reader(open('data/ccibb.csv', "rt"), delimiter = ",")
             for row1 in csv_file1:
                 print("ccibb row: ",row1[0],row1[13])
                 if ((''.join(key_arr)) == row1[0]) and row1[13] == "Y": #13 is winrisk - whether we trade or not
                         quantity = 2
                         log.info("we have a match in ccibb.csv")
                         log.info("found a match in CCIBB ".format(str(row1[0])))
                         ccibb_trade = True
                         if open_long or open_short:
                             quantity = 4
                         ParentOrderID = orders.buildOrders(self.ib,tradeContract,tradeAction,quantity,"ccibb_day",stoplossprice)
                         log.info("order placed, parentID: {}".format(ParentOrderID))
                         open_long = False
                         open_short = False
                         tradenow = False
                         status_done = self.row_results(row1,cci_trade,ccibb_trade)
                         break
             csv_file2 = csv.reader(open('data/cci.csv', "rt"), delimiter = ",")
             for row2 in csv_file2:
                 print("cci   row: ",row2[0],row2[13])
                 if ((''.join(key_arr[0:8])) == row2[0]) and row2[13] == "Y":
                         quantity = 2
                         log.info("we have a match in cci.csv - tradeAction".format(tradeAction))
                         log.info("found a math in CCI {}".format(str(row2[0])))
                         if open_long or open_short:
                             quantity = 4
                         ParentOrderID = orders.buildOrders(self.ib,tradeContract,tradeAction,quantity,"cci_day",stoplossprice)
                         open_long = False
                         open_short = False
                         tradenow = False
                         status_done = self.row_results(row2,cci_trade,ccibb_trade)
                         break
             log.info("did we find a match?  If true than no {match}".format(match = tradenow))
             if open_long or open_short:
                 quantity = 2
                 ParentOrderID = orders.buildOrders(self.ib,tradeContract,tradeAction,quantity,"ccibb_day",stoplossprice)
                 open_long =False
                 open_short = False
         csv_row += ","+(''.join(key_arr))+","+(''.join(key_arr[0:8]))+","+str(cci_trade)+","+str(ccibb_trade)+","+str(pendinglong)+","+str(pendingshort)
         csv_header += ",CCIbbKey,CCIKey,CCI Trade,CCIbbTrade,PendingLong, PendingShort"
         with open('data/hist15.csv', mode='a') as hist15:
             histwriter = csv.writer(hist15, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
             histwriter.writerow([csv_header])
             histwriter.writerow([csv_row])
         tradenow = False
         cci_trade = False
         ccibb_trade = False
예제 #22
0
def start(config):
    import toml

    with open(config, "r") as f:
        config = toml.load(f)

    validate_config(config)

    click.secho(f"Config:", fg="green")
    click.echo()

    click.secho(f"  Account details:", fg="green")
    click.secho(
        f"    Number                   = {config['account']['number']}",
        fg="cyan")
    click.secho(
        f"    Cancel existing orders   = {config['account']['cancel_orders']}",
        fg="cyan",
    )
    click.secho(
        f"    Margin usage             = {config['account']['margin_usage']} ({config['account']['margin_usage'] * 100}%)",
        fg="cyan",
    )
    click.secho(
        f"    Market data type         = {config['account']['market_data_type']}",
        fg="cyan",
    )
    click.echo()

    click.secho(f"  Roll options when either condition is true:", fg="green")
    click.secho(f"    Days to expiry          <= {config['roll_when']['dte']}",
                fg="cyan")
    click.secho(
        f"    P&L                     >= {config['roll_when']['pnl']} ({config['roll_when']['pnl'] * 100}%)",
        fg="cyan",
    )

    click.echo()
    click.secho(f"  Write options with targets of:", fg="green")
    click.secho(f"    Days to expiry          >= {config['target']['dte']}",
                fg="cyan")
    click.secho(f"    Delta                   <= {config['target']['delta']}",
                fg="cyan")
    click.secho(
        f"    Minimum open interest   >= {config['target']['minimum_open_interest']}",
        fg="cyan",
    )

    click.echo()
    click.secho(f"  Symbols:", fg="green")
    for s in config["symbols"].keys():
        click.secho(
            f"    {s}, weight = {config['symbols'][s]['weight']} ({config['symbols'][s]['weight'] * 100}%)",
            fg="cyan",
        )
    assert (sum([
        config["symbols"][s]["weight"] for s in config["symbols"].keys()
    ]) == 1.0)
    click.echo()

    if config.get("ib_insync", {}).get("logfile"):
        util.logToFile(config["ib_insync"]["logfile"])

    ibc = IBC(**config["ibc"])

    def onConnected():
        portfolio_manager.manage()

    ib = IB()
    ib.connectedEvent += onConnected

    completion_future = asyncio.Future()
    portfolio_manager = PortfolioManager(config, ib, completion_future)

    probeContractConfig = config["watchdog"]["probeContract"]
    watchdogConfig = config.get("watchdog")
    del watchdogConfig["probeContract"]
    probeContract = Contract(
        secType=probeContractConfig["secType"],
        symbol=probeContractConfig["symbol"],
        currency=probeContractConfig["currency"],
        exchange=probeContractConfig["exchange"],
    )

    watchdog = Watchdog(ibc, ib, probeContract=probeContract, **watchdogConfig)

    watchdog.start()
    ib.run(completion_future)
    watchdog.stop()
    ibc.terminate()
예제 #23
0
    def justStartedAppDirectionCheck(self):
        log.debug(
            "justStartedAppDirectionCheck: Application just restarted.  Going through our checks"
        )
        # do we need to reverse positions?
        # first check to see if we have positions or open orders.  If not exit otherwise continue
        # Are we positioned in the wrong direction (i.e. long when we should be short?)  If so, we need to close STP and open open trades.
        # not going to take a position at this time.
        # the bars data is the current, not completed, bar so we have to go back to get closed bars.
        #
        # checking for wrong direction
        contContract, contracthours = get_contract(
            self)  #basic information on continuious contact
        tradeContract = self.ib.qualifyContracts(contContract)[
            0]  # gives all the details of a contract so we can trade it
        open_long, open_short, long_position_qty, short_position_qty, account_qty = orders.countOpenPositions(
            self.ib,
            "")  # do we have an open position - not orders but positions?
        open_today, tradingDayRules, currentTimeFrame = helpers.is_open_today(
            contracthours)
        wait_time, self.datetime_15, self.datetime_1h, self.datetime_1d, self.log_time = self.define_times(
            self.ib)
        dataContract = Contract(exchange=config.EXCHANGE,
                                secType="FUT",
                                localSymbol=contContract.localSymbol)
        bars_15m = calculations.Calculations(self.ib, dataContract, "2 D",
                                             "15 mins", self.datetime_15,
                                             False, 0)

        #
        bars_1h = calculations.Calculations(self.ib, dataContract, "5 D",
                                            "1 hour", self.datetime_1h, True,
                                            bars_15m.closePrice)
        bars_1d = calculations.Calculations(self.ib, dataContract, "75 D",
                                            "1 day", self.datetime_1d, False,
                                            0)
        updated = self.update_tk(bars_15m, bars_1h, bars_1d)
        #
        #rint("bars15 cci_third, ccia_third, cci_prior, ccia_prior, cci, ccia",bars_15m.cci_third,bars_15m.ccia_third,bars_15m.cci_prior, bars_15m.ccia_prior, bars_15m.cci, bars_15m.ccia)
        if bars_15m.cci_prior > bars_15m.ccia_prior and open_short and abs(
                bars_15m.cci - bars_15m.ccia) > config.SPREAD:
            log.info(
                "justStartedAppDirectionCheck: we are in app start up and we need to reverse due to wrong direction"
            )
            allClosed = orders.closeOutMain(
                self.ib, tradeContract, True
            )  # we don't worry about whether we are long or short. just passing the contract, need to add order.  Second false is whether this is an opening order.  it is not
            log.info(
                "justStartedAppDirectionCheck: crossed but not tradeNow so lets close stp and open positions"
            )
        elif bars_15m.cci_prior > bars_15m.ccia_prior and open_short and abs(
                bars_15m.cci - bars_15m.ccia) <= config.SPREAD:
            return True, False, 1
            log.info(
                "justStartedAppDirectionCheck: we are in app start up and we crossed but not exceed the spread - going pending"
            )
        elif bars_15m.cci_prior < bars_15m.ccia_prior and open_long and abs(
                bars_15m.cci - bars_15m.ccia) > config.SPREAD:
            log.info(
                "justStartedAppDirectionCheck: we are in app start up and we need to reverse due to wrong direction. Came in long and crossed down > spread"
            )
            allClosed = orders.closeOutMain(
                self.ib, tradeContract, True
            )  # we don't worry about whether we are long or short. just passing the contract, need to add order.  Second false is whether this is an opening order.  it is not
            log.info(
                "justStartedAppDirectionCheck: crossed but not tradeNow so lets close stp and open positions"
            )
        elif bars_15m.cci_prior < bars_15m.ccia_prior and open_long and abs(
                bars_15m.cci - bars_15m.ccia) <= config.SPREAD:
            return False, True, 1
            log.info(
                "justStartedAppDirectionCheck: we are in app start up and we crossed but not exceed the spread - going pending"
            )
        else:
            log.info(
                "justStartedAppDirectionCheck: we are in app start up and we DO NOT need to reverse due to wrong direction - checking pending"
            )
            log.info(
                "justStartedAppPendingCheck:: bars_15m.prior {ccip} {cciap}, third {ccip3} {cciap3} open long and short {ol} {os}"
                .format(ccip=bars_15m.cci_prior,
                        cciap=bars_15m.ccia_prior,
                        ccip3=bars_15m.cci_third,
                        cciap3=bars_15m.ccia_third,
                        ol=open_long,
                        os=open_short))
            if bars_15m.cci_prior > bars_15m.ccia_prior and abs(bars_15m.cci_prior - bars_15m.ccia_prior) <= config.SPREAD and \
                bars_15m.cci_third < bars_15m.ccia_third and abs(bars_15m.cci_third - bars_15m.ccia_third) > config.SPREAD and \
                not open_long and not open_short:
                return True, False, 1
            elif bars_15m.cci_prior < bars_15m.ccia_prior and abs(bars_15m.cci_prior - bars_15m.ccia_prior) <= config.SPREAD and \
                bars_15m.cci_third > bars_15m.ccia_third and abs(bars_15m.cci_third - bars_15m.ccia_third) > config.SPREAD and \
                not open_long and not open_short:
                return False, True, 1
            else:
                log.info("not going into this session pending")
                return False, False, 0
예제 #24
0
def start(config):
    import toml

    import thetagang.config_defaults as config_defaults  # NOQA

    with open(config, "r") as f:
        config = toml.load(f)

    config = normalize_config(config)

    validate_config(config)

    click.secho("Config:", fg="green")
    click.echo()

    click.secho("  Account details:", fg="green")
    click.secho(
        f"    Number                   = {config['account']['number']}",
        fg="cyan")
    click.secho(
        f"    Cancel existing orders   = {config['account']['cancel_orders']}",
        fg="cyan",
    )
    click.secho(
        f"    Margin usage             = {config['account']['margin_usage']} ({config['account']['margin_usage'] * 100}%)",
        fg="cyan",
    )
    click.secho(
        f"    Market data type         = {config['account']['market_data_type']}",
        fg="cyan",
    )
    click.echo()

    click.secho("  Roll options when either condition is true:", fg="green")
    click.secho(
        f"    Days to expiry          <= {config['roll_when']['dte']} and P&L >= {config['roll_when']['min_pnl']} ({config['roll_when']['min_pnl'] * 100}%)",
        fg="cyan",
    )
    if "max_dte" in config["roll_when"]:
        click.secho(
            f"    P&L                     >= {config['roll_when']['pnl']} ({config['roll_when']['pnl'] * 100}%) and DTE < {config['roll_when']['max_dte']}",
            fg="cyan",
        )
    else:
        click.secho(
            f"    P&L                     >= {config['roll_when']['pnl']} ({config['roll_when']['pnl'] * 100}%)",
            fg="cyan",
        )

    click.echo()
    click.secho("  When contracts are ITM:", fg="green")
    click.secho(
        f"    Roll puts               = {config['roll_when']['puts']['itm']}",
        fg="cyan",
    )
    click.secho(
        f"    Roll calls              = {config['roll_when']['calls']['itm']}",
        fg="cyan",
    )

    click.echo()
    click.secho("  Write options with targets of:", fg="green")
    click.secho(f"    Days to expiry          >= {config['target']['dte']}",
                fg="cyan")
    click.secho(f"    Default delta           <= {config['target']['delta']}",
                fg="cyan")
    if "puts" in config["target"]:
        click.secho(
            f"    Delta for puts          <= {config['target']['puts']['delta']}",
            fg="cyan",
        )
    if "calls" in config["target"]:
        click.secho(
            f"    Delta for calls         <= {config['target']['calls']['delta']}",
            fg="cyan",
        )
    click.secho(
        f"    Maximum new contracts    = {config['target']['maximum_new_contracts_percent'] * 100}% of buying power",
        fg="cyan",
    )
    click.secho(
        f"    Minimum open interest    = {config['target']['minimum_open_interest']}",
        fg="cyan",
    )

    click.echo()
    click.secho("  Symbols:", fg="green")
    for s in config["symbols"].keys():
        c = config["symbols"][s]
        c_delta = f"{get_target_delta(config, s, 'C'):.2f}".rjust(4)
        p_delta = f"{get_target_delta(config, s, 'P'):.2f}".rjust(4)
        weight_p = f"{(c['weight'] * 100):.2f}".rjust(4)
        strike_limits = ""
        c_limit = get_strike_limit(config, s, "C")
        p_limit = get_strike_limit(config, s, "P")
        if c_limit:
            strike_limits += f", call strike >= ${c_limit:.2f}"
        if p_limit:
            strike_limits += f", put strike <= ${p_limit:.2f}"
        click.secho(
            f"    {s.rjust(5)} weight = {weight_p}%, delta = {p_delta}p, {c_delta}c{strike_limits}",
            fg="cyan",
        )
    assert (round(
        sum([config["symbols"][s]["weight"]
             for s in config["symbols"].keys()]), 5) == 1.00000)
    click.echo()

    if config.get("ib_insync", {}).get("logfile"):
        util.logToFile(config["ib_insync"]["logfile"])

    # TWS version is pinned to current stable
    ibc_config = config.get("ibc", {})
    # Remove any config params that aren't valid keywords for IBC
    ibc_keywords = {
        k: ibc_config[k]
        for k in ibc_config if k not in ["RaiseRequestErrors"]
    }
    ibc = IBC(981, **ibc_keywords)

    def onConnected():
        portfolio_manager.manage()

    ib = IB()
    ib.RaiseRequestErrors = ibc_config.get("RaiseRequestErrors", False)
    ib.connectedEvent += onConnected

    completion_future = asyncio.Future()
    portfolio_manager = PortfolioManager(config, ib, completion_future)

    probeContractConfig = config["watchdog"]["probeContract"]
    watchdogConfig = config.get("watchdog")
    del watchdogConfig["probeContract"]
    probeContract = Contract(
        secType=probeContractConfig["secType"],
        symbol=probeContractConfig["symbol"],
        currency=probeContractConfig["currency"],
        exchange=probeContractConfig["exchange"],
    )

    watchdog = Watchdog(ibc, ib, probeContract=probeContract, **watchdogConfig)

    watchdog.start()
    ib.run(completion_future)
    watchdog.stop()
    ibc.terminate()