def pending_orders(request): p = APIINFO.objects.latest('id') apiKey = p.api_key accessToken = p.api_token kite = KiteConnect(api_key=apiKey) kite.set_access_token(accessToken) if request.method == "POST": KiteConnect.cancel_order(kite, request.POST["var"], request.POST["oid"]) kite.orders() print(datetime.now()) return render(request, 'trademsg/pending_orders.html', context={"orders": kite.orders()})
class Zerodha(Broker): """ Automated Trading class """ def __init__(self, api_key, secret, user_id, password, PIN, exchange='NSE', product='MIS'): self._api_key = api_key self._secret = secret self._user_id = user_id self._password = password self._pin = PIN self.exchange = exchange self.product = product self._store_access_token = True super(Zerodha, self).__init__() @property def isNilPositions(self): """ return True if there are no open positions else return False """ temp = pd.DataFrame(self.positions()['net']) if temp.quantity.abs().sum() == 0: return True else: return False @property def isNilPositionsDay(self): """ return True if there are no open positions for the day else return False """ temp = pd.DataFrame(self.positions()['day']) if temp.quantity.abs().sum() == 0: return True else: return False @property def isNilOrders(self): """ return True if there are no pending orders else return False """ pending = [ o for o in self.orders() if o.get('status', 'PENDING') == 'PENDING' ] if len(pending) == 0: return True else: return False def cancel_all_orders(self, retries=5): """ Cancel all existing orders """ for o in self.orders(): try: if o['status'] == 'PENDING': self.order_cancel(variety=o['variety'], order_id=o['order_id'], parent_order_id=o['parent_order_id']) except Exception as e: print(e) i = 0 while not (self.isNilOrders): print('Into the loop') i += 1 for o in self.orders(): try: if o['status'] == 'PENDING': self.order_cancel(variety=o['variety'], order_id=o['order_id'], parent_order_id=o['parent_order_id']) except Exception as e: print(e) if i > retries: print('Breaking out of loop without canceling all orders') break def _shortcuts(self): """ Provides shortcuts to kite functions by mapping functions. Instead of calling at.kite.quote, you would directly call at.quote Note ----- 1) Kite functions are initialized only after authentication 1) Not all functions are supported """ self.margins = self.kite.margins self.profile = self.kite.profile self.ltp = self.kite.ltp self.quote = self.kite.quote self.ohlc = self.kite.ohlc self.trades = self.kite.trades self.holdings = self.kite.holdings self._sides = {'BUY': 'SELL', 'SELL': 'BUY'} def authenticate(self): """ Authenticates a kite session if access token is already available Looks up token in token.tok file Useful for reconnecting instead of logging in again """ try: self.kite = KiteConnect(api_key=self._api_key) with open('token.tok') as f: access_token = f.read() self.kite.set_access_token(access_token) self.kite.profile() self.ticker = KiteTicker(api_key=self._api_key, access_token=self.kite.access_token) self._shortcuts() except TokenException: print('Into Exception') self._login() self._shortcuts() self.ticker = KiteTicker(api_key=self._api_key, access_token=self.kite.access_token) except: print('Unknown Exception') self._login() self._shortcuts() self.ticker = KiteTicker(api_key=self._api_key, access_token=self.kite.access_token) def _login(self): import time self.kite = KiteConnect(api_key=self._api_key) options = Options() options.add_argument('--headless') options.add_argument('--disable-gpu') driver = webdriver.Chrome(options=options) driver.get(self.kite.login_url()) login_form = WebDriverWait(driver, 45).until( EC.presence_of_element_located((By.CLASS_NAME, "login-form"))) login_form.find_elements_by_tag_name('input')[0].send_keys( self._user_id) login_form.find_elements_by_tag_name('input')[1].send_keys( self._password) WebDriverWait(driver, 45).until( EC.presence_of_element_located((By.CLASS_NAME, "button-orange"))) driver.find_element_by_xpath('//button[@type="submit"]').click() twofa_form = WebDriverWait(driver, 45).until( EC.presence_of_element_located((By.CLASS_NAME, "twofa-form"))) twofa_form.find_elements_by_tag_name('input')[0].send_keys(self._pin) WebDriverWait(driver, 45).until( EC.presence_of_element_located((By.CLASS_NAME, "button-orange"))) driver.find_element_by_xpath('//button[@type="submit"]').click() time.sleep(2) token = get_key(driver.current_url) access = self.kite.generate_session(request_token=token, api_secret=self._secret) self.kite.set_access_token(access['access_token']) with open("token.tok", "w") as f: f.write(access['access_token']) driver.close() def get_all_orders_and_positions(self, positions='day'): """ Get the summary of all orders and positions """ pos = pd.DataFrame(self.positions()[positions]) orders = pd.DataFrame(self.orders()) orders['qty'] = orders.eval('pending_quantity-cancelled_quantity') orders['typ'] = 'orders' pos['qty'] = pos['quantity'].abs() pos['transaction_type'] = [ 'SELL' if qty < 0 else 'BUY' for qty in pos.quantity ] pos['typ'] = 'positions' cols = ['tradingsymbol', 'transaction_type', 'qty', 'typ'] return pd.concat([pos, orders], sort=False)[cols] def uncovered(self): """ Return the list of uncovered positions A position is considered unconvered if there is no matching stop loss or target order. """ pass def get_order_type(self, price, ltp, order): if order == "BUY": return 'LIMIT' if price < ltp else 'SL' elif order == "SELL": return 'LIMIT' if price > ltp else 'SL' @post def orders(self): status_map = { 'OPEN': 'PENDING', 'COMPLETE': 'COMPLETE', 'CANCELLED': 'CANCELED', 'CANCELLED AMO': 'CANCELED', 'REJECTED': 'REJECTED', 'MODIFY_PENDING': 'PENDING', 'OPEN_PENDING': 'PENDING', 'CANCEL_PENDING': 'PENDING', 'AMO_REQ_RECEIVED': 'PENDING', 'TRIGGER_PENDING': 'PENDING' } ords = self.kite.orders() # Update status for o in ords: o['status'] = status_map.get(o['status'], 'PENDING') return ords @post def positions(self): """ Return only the positions for the day """ pos = self.kite.positions()['day'] for p in pos: if p['quantity'] > 0: p['side'] = 'BUY' else: p['side'] = 'SELL' return pos @pre def order_place(self, **kwargs): """ Place an order """ return self.kite.place_order(**kwargs) def order_cancel(self, order_id, variety='regular', parent_order_id=None): """ Cancel an existing order """ return self.kite.cancel_order(variety=variety, order_id=order_id, parent_order_id=parent_order_id) def order_modify(self, order_id, variety='regular', **kwargs): """ Modify an existing order Note ---- This is just a basic implementation So, all changes must be passed as keyword arguments """ return self.kite.modify_order(order_id=order_id, variety=variety, **kwargs) def _custom_orders(self, data, **kwargs): """ Generate custom orders. This is for customized usage data dataframe with the following columns open, symbol, price, side, quantity and stop_loss kwargs keyword arguments to be included in each order """ cols = ['open', 'symbol', 'price', 'quantity', 'side', 'stop_loss'] data = data[cols].to_dict(orient='records') exchange = kwargs.get('exchange', 'NSE') sym = ['{e}:{s}'.format(e=exchange, s=x['symbol']) for x in data] print(sym) ltps = self.ltp(sym) ltps = {k[4:]: v['last_price'] for k, v in ltps.items()} print(ltps) all_orders = [] replace = { 'symbol': 'tradingsymbol', 'side': 'transaction_type', } for d in data: dct = d.copy() del dct['stop_loss'] ltp = ltps.get(d['symbol']) order_type = self.get_order_type(price=dct['price'], ltp=ltp, order=dct['side']) dct['order_type'] = order_type dct['price'] = round(dct['price'], 2) # TO DO: Trigger greater if price is low to correct if order_type == "SL": dct['trigger_price'] = round(dct['open'] - 0.05, 2) dct.update(kwargs) del dct['open'] # Since its no longer needed all_orders.append(self.rename(dct, keys=replace)) # Second leg for covering orders for d in data: try: dct = d.copy() del dct['open'] # Since this is not needed here ltp = ltps.get(dct['symbol']) dct['side'] = self._sides[dct['side']] dct['stop_loss'] = round(dct['stop_loss'], 2) order_type = self.get_order_type(price=dct['stop_loss'], ltp=ltp, order=dct['side']) if order_type == 'SL': order_type = 'SL-M' dct['order_type'] = order_type dct.update(kwargs) replace.update({'stop_loss': 'trigger_price'}) all_orders.append(self.rename(dct, keys=replace)) except Exception as e: print(e, self.rename(dct)) return all_orders def _create_stop(self, **kwargs): sl = self._create_stop_loss_orders(percent=3, **kwargs) orders = [] for s in sl: try: dct = s.copy() dct.update({ 'exchange': 'NSE', 'product': 'MIS', 'validity': 'DAY', 'variety': 'regular' }) dct['trigger_price'] = s['price'] symbol = '{e}:{sym}'.format(e='NSE', sym=s['symbol']) ltp = self.ltp(symbol)[symbol]['last_price'] order_type = self.get_order_type(s['price'], ltp, s['side']) dct['order_type'] = order_type orders.append(dct) except Exception as e: print(e) return orders def cover_all(self, **kwargs): """ Place a stop loss for all uncovered orders """ orders = self._create_stop(**kwargs) for o in orders: try: print(self.order_place(**o)) except Exception as e: print(e) def close_all_positions(self, **kwargs): """ Close all existing positions """ positions = self.positions() if kwargs: positions = self.dict_filter(positions, **kwargs) if len(positions) > 0: for position in positions: qty = abs(position['quantity']) symbol = position['symbol'] side = self._sides[position['side']] exchange = position['exchange'] product = position['product'] if qty > 0: try: self.order_place(symbol=symbol, quantity=qty, order_type='MARKET', side=side, variety='regular', exchange=exchange, product=product) except Exception as e: print(e) def get_instrument_map(self, exchange='NSE', key='tradingsymbol', value='instrument_token'): """ Get the instrument map as a dictionary exchange exchange to fetch the symbols and tokens key dictionary key to be used as the key in the output value dictionary value to be used as the value in the output Note ----- 1) The instrument map is returned as a dictionary with key as the symbol and instrument token as value """ instruments = self.kite.instruments(exchange=exchange) inst_map = {inst[key]: inst[value] for inst in instruments} return inst_map
def start(name, access_token, lot_size): logging.basicConfig(filename=name + "_OMS.log", format='%(asctime)s %(message)s', filemode='w') # Creating an object logger = logging.getLogger() # Setting the threshold of logger to DEBUG logger.setLevel(logging.DEBUG) # Authenticate time.sleep(140) logger.debug("OMS started") path = '/home/ubuntu/APT/APT/Live_Trading' os.chdir(path) config = configparser.ConfigParser() config_path = path + '/config.ini' config.read(config_path) api_key = config['API']['API_KEY'] # Connect to kite kite = KiteConnect(api_key=api_key) kite.set_access_token(access_token) logger.debug("OMS Authenticated") # Bot API Link bot_link = "https://api.telegram.org/bot823468101:AAEqDCOXI3zBxxURkTgtleUvFvQ0S9a4TXA/sendMessage?chat_id=-383311990&text=" # Initialise variables first_order = 1 stoploss_modified = 0 local_order = 0 day_high = 0 day_low = 0 if lot_size < 100: quantity = 1 else: quantity = round(lot_size / 100) # Read previous day data file data = pd.read_csv(path + '/previous_day_data_' + name + '.csv') pivots = pivotpoints(data) # Local orders dataframes previous_strategy_orders = pd.DataFrame() # Create current order tracker dataframe current_order_parameters = [ 'order_id', 'order_type', 'transaction_type', 'parent_order_id', 'price', 'trigger_price', 'status' ] current_order = pd.DataFrame(columns=[ 'order_id', 'local_order_id', 'order_type', 'transaction_type', 'parent_order_id', 'price', 'trigger_price', 'status' ]) all_orders = pd.DataFrame(columns=[ 'order_id', 'local_order_id', 'order_type', 'transaction_type', 'parent_order_id', 'price', 'trigger_price', 'status' ]) # Get order update from KITE previous_kite_orders = pd.DataFrame(kite.orders()) kite_orders = pd.DataFrame(kite.orders()) print("Order Management Started") message = ("Order Management script started for: " + str(name)) requests.get(bot_link + message) # Start infinite loop while True: if datetime.now().second % 10 == 0: # Check if first order is placed if first_order == 0: try: kite_orders = pd.DataFrame(kite.orders()) except: logger.debug("Too many requests error from server") pass current_order = current_order.reset_index(drop=True) # Proceed if any new updates are there if not kite_orders.equals(previous_kite_orders): if len(current_order) == 1: # check if status of order is complete if kite_orders['status'][ kite_orders['order_id'] == current_order.at[ 0, 'order_id']].values[0] == 'COMPLETE': logger.debug("Order executed case block entered") # change current order status current_order = current_order.reset_index( drop=True) current_order.at[0, 'status'] = 'COMPLETE' # append stoploss and target orders current_order = current_order.append( kite_orders.loc[ kite_orders['parent_order_id'] == current_order.at[0, 'order_id'], current_order_parameters]) current_order = current_order.reset_index( drop=True) # append all orders to save all_orders = all_orders.append(current_order) all_orders.to_csv('LiveTrading_Output' + name + '.csv') logger.debug("Order file saved") # send message to telegram message = ( str(current_order.at[0, 'transaction_type']) + " order executed for " + name + " at " + str(current_order.at[0, 'price'])) requests.get(bot_link + message) logger.debug( "Order executed status case handled successfully" ) # if stoploss hits if len(current_order) > 1: if kite_orders['status'][ kite_orders['order_id'] == current_order['order_id'] [(current_order['trigger_price'] != 0) & (current_order['transaction_type'] != current_order.at[0, 'transaction_type'])]. values[0]].values[0] == 'COMPLETE': logger.debug("Stoploss hit case block entered") # order transaction type transaction_type = 'SELL' if current_order.at[ 0, 'transaction_type'] == 'BUY' else 'BUY' # entry price entry_price = current_order['trigger_price'][ current_order['trigger_price'] != 0].values[0] # stoploss stoploss_price = day_high if transaction_type == 'SELL' else day_low stoploss = round((day_high - entry_price) if transaction_type == 'SELL' else (entry_price - day_low), 1) # target target = get_target(pivots, entry_price, transaction_type, lot_size) target_price = round( (target + entry_price) if transaction_type == 'BUY' else (entry_price - target), 1) # update local order id local_order = local_order + 1 # clear previous orders current_order = current_order[0:0] try: # place first order at current market price order_id = kite.place_order( tradingsymbol=name, variety='bo', exchange=kite.EXCHANGE_NSE, transaction_type=transaction_type, quantity=quantity, price=entry_price, order_type=kite.ORDER_TYPE_LIMIT, product=kite.PRODUCT_MIS, stoploss=stoploss, squareoff=target) except Exception: message = "STOPLOSS HIT: Order cannot be placed." requests.get(bot_link + message) pass current_order = current_order.append( { 'order_id': order_id, 'local_order_id': local_order, 'order_type': 'LIMIT', 'transaction_type': transaction_type, 'parent_order_id': 'NA', 'price': entry_price, 'trigger_price': 0, 'status': 'OPEN' }, ignore_index=True) # send message to telegram message = ("STOPLOSS HIT: " + transaction_type + " order placed for " + str(quantity) + " stocks of " + name + " at " + str(entry_price) + " with stoploss at " + str(stoploss_price) + " and target at " + str(target_price)) requests.get(bot_link + message) # update stoploss status stoploss_modified = 0 logger.debug("Stoploss hit case handled") # if target hits if len(current_order) > 1: if kite_orders['status'][ kite_orders['order_id'] == current_order['order_id'] [(current_order['trigger_price'] == 0) & (current_order['transaction_type'] != current_order.at[0, 'transaction_type'])]. values[0]].values[0] == 'COMPLETE': logger.debug("Target hit case block entered") # order transaction type transaction_type = 'SELL' if current_order.at[ 0, 'transaction_type'] == 'BUY' else 'BUY' # entry price entry_price = day_low if transaction_type == 'SELL' else day_high # stoploss stoploss_price = day_high if transaction_type == 'SELL' else day_low stoploss = round((day_high - entry_price) if transaction_type == 'SELL' else (entry_price - day_low), 1) # target target = get_target(pivots, entry_price, transaction_type, lot_size) target_price = round( (target + entry_price) if transaction_type == 'BUY' else (entry_price - target), 1) # update local order id local_order = local_order + 1 # clear previous orders current_order = current_order[0:0] try: order_id = kite.place_order( tradingsymbol=name, variety='bo', exchange=kite.EXCHANGE_NSE, transaction_type=transaction_type, quantity=quantity, price=entry_price, trigger_price=entry_price, order_type=kite.ORDER_TYPE_SL, product=kite.PRODUCT_MIS, stoploss=stoploss, squareoff=target) except Exception: message = "TARGET HIT: Order cannnot be placed." requests.get(bot_link + message) pass current_order = current_order.append( { 'order_id': order_id, 'local_order_id': local_order, 'order_type': 'LIMIT', 'transaction_type': transaction_type, 'parent_order_id': 'NA', 'price': entry_price, 'trigger_price': 0, 'status': 'OPEN' }, ignore_index=True) # send message to telegram message = ("TARGET HIT: " + transaction_type + " order placed for " + str(quantity) + " stocks of " + name + " at " + str(entry_price) + " with stoploss at " + str(stoploss_price) + " and target at " + str(target_price)) requests.get(bot_link + message) # update stoploss status stoploss_modified = 0 logger.debug("Target hit case handled") # copy current orders to previous orders previous_kite_orders = kite_orders.copy(deep=True) time.sleep(1) else: time.sleep(1) else: time.sleep(1) elif datetime.now().minute % 5 == 0 and (datetime.now().second >= 7 and datetime.now().second <= 12): if os.path.isfile('live_order_' + name + '_' + str(datetime.now().date()) + '.csv'): strategy_orders = pd.read_csv('live_order_' + name + '_' + str(datetime.now().date()) + '.csv') strategy_orders = strategy_orders.reset_index(drop=True) kite_orders.to_csv('kite_orders_' + name + '_' + str(datetime.now().date()) + '.csv') current_order.to_csv('current_order_' + name + '_' + str(datetime.now().date()) + '.csv') # if orders present in strategy orders file if not strategy_orders.equals(previous_strategy_orders): # first order of the day if first_order == 1: logger.debug("First order block entered") # get order details local_order = strategy_orders.at[0, 'order_id'] transaction_type = strategy_orders.at[ 0, 'transaction_type'] entry_price = strategy_orders.at[0, 'price'] stoploss_price = strategy_orders.at[0, 'stoploss'] target_price = strategy_orders.at[0, 'target'] stoploss = round( (stoploss_price - entry_price) if transaction_type == 'SELL' else (entry_price - stoploss_price), 1) target = round( (entry_price - target_price) if transaction_type == 'SELL' else (target_price - entry_price), 1) # place first order at current market price try: order_id = kite.place_order( tradingsymbol=name, variety='bo', exchange=kite.EXCHANGE_NSE, transaction_type=transaction_type, quantity=quantity, price=entry_price, order_type=kite.ORDER_TYPE_LIMIT, product=kite.PRODUCT_MIS, stoploss=stoploss, squareoff=target) except Exception: message = "First order cannot be placed." requests.get(bot_link + message) pass current_order = current_order.append( { 'order_id': order_id, 'local_order_id': local_order, 'order_type': 'LIMIT', 'transaction_type': transaction_type, 'parent_order_id': 'NA', 'price': entry_price, 'trigger_price': 0, 'status': 'OPEN' }, ignore_index=True) # send message to telegram message = (transaction_type + " order placed for " + str(quantity) + " stocks of " + name + " at " + str(entry_price) + " with stoploss at " + str(stoploss_price) + " and target at " + str(target_price)) requests.get(bot_link + message) first_order = 0 logger.debug("First order placed for " + name) time.sleep(6) # update day high and day low day_high = strategy_orders.loc[( strategy_orders['order_id'] == current_order.at[ 0, 'local_order_id']), 'day_high'].values[0] day_low = strategy_orders.loc[( strategy_orders['order_id'] == current_order.at[ 0, 'local_order_id']), 'day_low'].values[0] message = (name + "\nDay high: " + str(day_high) + "\nDay low: " + str(day_low)) requests.get(bot_link + message) # modify stoploss if semi-target is hit if strategy_orders['semi-target_status'][ strategy_orders['order_id'] == current_order.at[ 0, 'local_order_id']].values[ 0] == 1 and stoploss_modified == 0: # if order is executed if current_order.at[0, 'status'] == 'COMPLETE' and len( current_order) <= 3: logger.debug( "Semi-target modification in executed order block entered" ) # fetch semi-target price modified_price = strategy_orders.loc[( strategy_orders['order_id'] == current_order. at[0, 'local_order_id']), 'semi_target'].values[0] try: order_id = kite.modify_order( variety='bo', parent_order_id=current_order.at[ 0, 'order_id'], order_id=current_order['order_id'][ current_order['trigger_price'] != 0]. values[0], order_type=kite.ORDER_TYPE_SL, trigger_price=modified_price) except Exception: message = ("Stoploss cannot be modified to " + str(modified_price) + " for " + name + " , trying again in 5 minutes...") requests.get(bot_link + message) continue # Replace the stoploss with the semi-target price current_order['trigger_price'][ current_order['trigger_price'] != 0] = modified_price # send message to telegram message = ("Stoploss modified to " + str(modified_price) + " for " + name) requests.get(bot_link + message) # update stoploss status stoploss_modified = 1 logger.debug( "Semi-target modification in executed order case handled" ) # if order is executed in partial chunks elif current_order.at[0, 'status'] == 'COMPLETE' and len( current_order) > 3: logger.debug( "Semi-target modification in partially filled orders block entered" ) # get all order ids' list of stoploss orders order_list = current_order['order_id'][ current_order['trigger_price'] != 0].tolist() # fetch semi-target price modified_price = strategy_orders.loc[( strategy_orders['order_id'] == current_order. at[0, 'local_order_id']), 'semi_target'].values[0] # iterate over all order ids for order_id in order_list: order_id = kite.modify_order( variety='bo', parent_order_id=current_order.at[ 0, 'order_id'], order_id=order_id, order_type=kite.ORDER_TYPE_SL, trigger_price=modified_price) time.sleep(2) # Replace the stoploss with the semi-target price current_order['trigger_price'][ current_order['trigger_price'] != 0] = modified_price # send message to telegram message = ("Stoploss modified to " + str(modified_price) + " for " + name) requests.get(bot_link + message) # update stoploss status stoploss_modified = 1 logger.debug( "Semi-target modification in executed order case handled" ) # if order was not executed elif current_order.at[0, 'status'] == 'OPEN': logger.debug( "Semi-target modification in open order block entered" ) # cancel last placed order kite.cancel_order(variety='bo', order_id=current_order.at[ 0, 'order_id'].values[0]) logger.debug("Order cancelled") # transaction type transaction_type = 'SELL' if current_order.at[ 0, 'transaction_type'] == 'BUY' else 'BUY' # entry price entry_price = strategy_orders.loc[( strategy_orders['order_id'] == current_order. at[0, 'local_order_id']), 'semi_target'].values[0] # stoploss stoploss_price = day_high if transaction_type == 'SELL' else day_low stoploss = round((day_high - entry_price) if transaction_type == 'SELL' else (entry_price - day_low), 1) # target target = get_target(pivots, entry_price, transaction_type, lot_size) target_price = round( (target + entry_price) if transaction_type == 'BUY' else (entry_price - target), 1) # empty dataframe current_order = current_order[0:0] # update local order id local_order = local_order + 1 try: # place new order order_id = kite.place_order( tradingsymbol=name, variety='bo', exchange=kite.EXCHANGE_NSE, transaction_type=transaction_type, quantity=quantity, price=entry_price, order_type=kite.ORDER_TYPE_LIMIT, product=kite.PRODUCT_MIS, stoploss=stoploss, squareoff=target) except Exception: message = "SEMI-TARGET HIT IN OPEN ORDER: Order cannot be placed." requests.get(bot_link + message) pass current_order = current_order.append( { 'order_id': order_id, 'local_order_id': local_order, 'order_type': 'LIMIT', 'transaction_type': transaction_type, 'parent_order_id': 'NA', 'price': entry_price, 'trigger_price': 0, 'status': 'OPEN' }, ignore_index=True) # send message to telegram message = ("SEMI-TARGET HIT IN OPEN ORDER: " + transaction_type + " order placed for " + str(quantity) + " stocks of " + name + " at " + str(entry_price) + " with stoploss at " + str(stoploss_price) + " and target at " + str(target_price)) requests.get(bot_link + message) # update stoploss status stoploss_modified = 0 logger.debug( "Semi-target modification in open order case handled" ) # if target is hit while order is open if strategy_orders['target_status'][ strategy_orders['order_id'] == current_order.at[ 0, 'local_order_id']].values[ 0] == 1 and current_order.at[ 0, 'status'] == 'OPEN': logger.debug("Target hit in open order case entered") # cancel last placed order kite.cancel_order( variety='bo', order_id=current_order.at[0, 'order_id'].values[0]) logger.debug("Order cancelled") # order transaction type transaction_type = 'SELL' if current_order.at[ 0, 'transaction_type'] == 'BUY' else 'BUY' # entry price entry_price = day_low if transaction_type == 'SELL' else day_high # stoploss stoploss_price = day_high if transaction_type == 'SELL' else day_low stoploss = round( (day_high - entry_price) if transaction_type == 'SELL' else (entry_price - day_low), 1) # target target = get_target(pivots, entry_price, transaction_type, lot_size) target_price = round( (target + entry_price) if transaction_type == 'BUY' else (entry_price - target), 1) # update local order id local_order = local_order + 1 # clear previous orders current_order = current_order[0:0] try: # place new order at day's high/low order_id = kite.place_order( tradingsymbol=name, variety='bo', exchange=kite.EXCHANGE_NSE, transaction_type=transaction_type, quantity=quantity, price=entry_price, trigger_price=entry_price, order_type=kite.ORDER_TYPE_SL, product=kite.PRODUCT_MIS, stoploss=stoploss, squareoff=target) except Exception: message = "TARGET HIT IN OPEN ORDER: Order cannot be placed." requests.get(bot_link + message) pass current_order = current_order.append( { 'order_id': order_id, 'local_order_id': local_order, 'order_type': 'LIMIT', 'transaction_type': transaction_type, 'parent_order_id': 'NA', 'price': entry_price, 'trigger_price': 0, 'status': 'OPEN' }, ignore_index=True) # send message to telegram message = ("TARGET HIT IN OPEN ORDER: " + transaction_type + " order placed for " + str(quantity) + " stocks of " + name + " at " + str(entry_price) + " with stoploss at " + str(stoploss_price) + " and target at " + str(target_price)) requests.get(bot_link + message) # update stoploss status stoploss_modified = 0 logger.debug("Target hit in open order case handled") previous_strategy_orders = strategy_orders.copy(deep=True) time.sleep(6) elif datetime.now().hour == 9 and datetime.now().minute >= 50: all_orders.to_csv('LiveTrading_Output' + name + '.csv') logger.debug("Order file saved") # send message to telegram message = ("Live orders file sent to mail") requests.get(bot_link + message) time.sleep(700) else: time.sleep(1)
class Zerodha(Broker): """ Automated Trading class """ def __init__( self, api_key, secret, user_id, password, PIN, exchange="NSE", product="MIS", totp=None, is_pin=False, ): self._api_key = api_key self._secret = secret self._user_id = user_id self._password = password self._pin = PIN self._totp = totp self.is_pin = is_pin self.exchange = exchange self.product = product self._store_access_token = True super(Zerodha, self).__init__() @property def isNilPositions(self): """ return True if there are no open positions else return False """ temp = pd.DataFrame(self.positions()["net"]) if temp.quantity.abs().sum() == 0: return True else: return False @property def isNilPositionsDay(self): """ return True if there are no open positions for the day else return False """ temp = pd.DataFrame(self.positions()["day"]) if temp.quantity.abs().sum() == 0: return True else: return False @property def isNilOrders(self): """ return True if there are no pending orders else return False """ pending = [ o for o in self.orders() if o.get("status", "PENDING") == "PENDING" ] if len(pending) == 0: return True else: return False def cancel_all_orders(self, retries=5): """ Cancel all existing orders """ for o in self.orders(): try: if o["status"] == "PENDING": self.order_cancel( variety=o["variety"], order_id=o["order_id"], parent_order_id=o["parent_order_id"], ) except Exception as e: print(e) i = 0 while not (self.isNilOrders): print("Into the loop") i += 1 for o in self.orders(): try: if o["status"] == "PENDING": self.order_cancel( variety=o["variety"], order_id=o["order_id"], parent_order_id=o["parent_order_id"], ) except Exception as e: print(e) if i > retries: print("Breaking out of loop without canceling all orders") break def _shortcuts(self): """ Provides shortcuts to kite functions by mapping functions. Instead of calling at.kite.quote, you would directly call at.quote Note ----- 1) Kite functions are initialized only after authentication 1) Not all functions are supported """ self.margins = self.kite.margins self.profile = self.kite.profile self.ltp = self.kite.ltp self.quote = self.kite.quote self.ohlc = self.kite.ohlc self.trades = self.kite.trades self.holdings = self.kite.holdings self._sides = {"BUY": "SELL", "SELL": "BUY"} def authenticate(self): """ Authenticates a kite session if access token is already available Looks up token in token.tok file Useful for reconnecting instead of logging in again """ try: self.kite = KiteConnect(api_key=self._api_key) with open("token.tok") as f: access_token = f.read() self.kite.set_access_token(access_token) self.kite.profile() self.ticker = KiteTicker(api_key=self._api_key, access_token=self.kite.access_token) self._shortcuts() except TokenException: print("Into Exception") self._login() self._shortcuts() self.ticker = KiteTicker(api_key=self._api_key, access_token=self.kite.access_token) except: print("Unknown Exception") self._login() self._shortcuts() self.ticker = KiteTicker(api_key=self._api_key, access_token=self.kite.access_token) def _login(self): import time self.kite = KiteConnect(api_key=self._api_key) options = Options() options.add_argument("--headless") options.add_argument("--disable-gpu") driver = webdriver.Chrome(options=options) driver.get(self.kite.login_url()) login_form = WebDriverWait(driver, 45).until( EC.presence_of_element_located((By.CLASS_NAME, "login-form"))) login_form.find_elements_by_tag_name("input")[0].send_keys( self._user_id) login_form.find_elements_by_tag_name("input")[1].send_keys( self._password) WebDriverWait(driver, 45).until( EC.presence_of_element_located((By.CLASS_NAME, "button-orange"))) driver.find_element_by_xpath('//button[@type="submit"]').click() totp_pass = pyotp.TOTP(self._totp).now() twofa_pass = self._pin if self.is_pin is True else totp_pass twofa_form = WebDriverWait(driver, 45).until( EC.presence_of_element_located((By.CLASS_NAME, "twofa-form"))) twofa_form.find_elements_by_tag_name("input")[0].send_keys(twofa_pass) WebDriverWait(driver, 45).until( EC.presence_of_element_located((By.CLASS_NAME, "button-orange"))) driver.find_element_by_xpath('//button[@type="submit"]').click() time.sleep(2) token = get_key(driver.current_url) access = self.kite.generate_session(request_token=token, api_secret=self._secret) self.kite.set_access_token(access["access_token"]) with open("token.tok", "w") as f: f.write(access["access_token"]) driver.close() def get_all_orders_and_positions(self, positions="day"): """ Get the summary of all orders and positions """ pos = pd.DataFrame(self.positions()[positions]) orders = pd.DataFrame(self.orders()) orders["qty"] = orders.eval("pending_quantity-cancelled_quantity") orders["typ"] = "orders" pos["qty"] = pos["quantity"].abs() pos["transaction_type"] = [ "SELL" if qty < 0 else "BUY" for qty in pos.quantity ] pos["typ"] = "positions" cols = ["tradingsymbol", "transaction_type", "qty", "typ"] return pd.concat([pos, orders], sort=False)[cols] def uncovered(self): """ Return the list of uncovered positions A position is considered unconvered if there is no matching stop loss or target order. """ pass def get_order_type(self, price, ltp, order): if order == "BUY": return "LIMIT" if price < ltp else "SL" elif order == "SELL": return "LIMIT" if price > ltp else "SL" @post def orders(self): status_map = { "OPEN": "PENDING", "COMPLETE": "COMPLETE", "CANCELLED": "CANCELED", "CANCELLED AMO": "CANCELED", "REJECTED": "REJECTED", "MODIFY_PENDING": "PENDING", "OPEN_PENDING": "PENDING", "CANCEL_PENDING": "PENDING", "AMO_REQ_RECEIVED": "PENDING", "TRIGGER_PENDING": "PENDING", } ords = self.kite.orders() # Update status for o in ords: o["status"] = status_map.get(o["status"], "PENDING") return ords @post def positions(self): """ Return only the positions for the day """ pos = self.kite.positions()["day"] for p in pos: if p["quantity"] > 0: p["side"] = "BUY" else: p["side"] = "SELL" return pos @pre def order_place(self, **kwargs): """ Place an order """ return self.kite.place_order(**kwargs) def order_cancel(self, order_id, variety="regular", parent_order_id=None): """ Cancel an existing order """ return self.kite.cancel_order(variety=variety, order_id=order_id, parent_order_id=parent_order_id) def order_modify(self, order_id, variety="regular", **kwargs): """ Modify an existing order Note ---- This is just a basic implementation So, all changes must be passed as keyword arguments """ return self.kite.modify_order(order_id=order_id, variety=variety, **kwargs) def _custom_orders(self, data, **kwargs): """ Generate custom orders. This is for customized usage data dataframe with the following columns open, symbol, price, side, quantity and stop_loss kwargs keyword arguments to be included in each order """ cols = ["open", "symbol", "price", "quantity", "side", "stop_loss"] data = data[cols].to_dict(orient="records") exchange = kwargs.get("exchange", "NSE") sym = ["{e}:{s}".format(e=exchange, s=x["symbol"]) for x in data] ltps = self.ltp(sym) ltps = {k[4:]: v["last_price"] for k, v in ltps.items()} all_orders = [] replace = { "symbol": "tradingsymbol", "side": "transaction_type", } for d in data: dct = d.copy() del dct["stop_loss"] ltp = ltps.get(d["symbol"]) order_type = self.get_order_type(price=dct["price"], ltp=ltp, order=dct["side"]) dct["order_type"] = order_type dct["price"] = round(dct["price"], 2) # TO DO: Trigger greater if price is low to correct if order_type == "SL": dct["trigger_price"] = round(dct["open"] - 0.05, 2) dct.update(kwargs) del dct["open"] # Since its no longer needed all_orders.append(self.rename(dct, keys=replace)) # Second leg for covering orders for d in data: try: dct = d.copy() del dct["open"] # Since this is not needed here ltp = ltps.get(dct["symbol"]) dct["side"] = self._sides[dct["side"]] dct["stop_loss"] = round(dct["stop_loss"], 2) order_type = self.get_order_type(price=dct["stop_loss"], ltp=ltp, order=dct["side"]) if order_type == "SL": order_type = "SL-M" dct["order_type"] = order_type dct.update(kwargs) replace.update({"stop_loss": "trigger_price"}) all_orders.append(self.rename(dct, keys=replace)) except Exception as e: print(e, self.rename(dct)) return all_orders def _create_stop(self, **kwargs): sl = self._create_stop_loss_orders(percent=3, **kwargs) orders = [] for s in sl: try: dct = s.copy() dct.update({ "exchange": "NSE", "product": "MIS", "validity": "DAY", "variety": "regular", }) dct["trigger_price"] = s["price"] symbol = "{e}:{sym}".format(e="NSE", sym=s["symbol"]) ltp = self.ltp(symbol)[symbol]["last_price"] order_type = self.get_order_type(s["price"], ltp, s["side"]) dct["order_type"] = order_type orders.append(dct) except Exception as e: print(e) return orders def cover_all(self, **kwargs): """ Place a stop loss for all uncovered orders """ orders = self._create_stop(**kwargs) for o in orders: try: print(self.order_place(**o)) except Exception as e: print(e) def close_all_positions(self, **kwargs): """ Close all existing positions """ positions = self.positions() if kwargs: positions = self.dict_filter(positions, **kwargs) if len(positions) > 0: for position in positions: qty = abs(position["quantity"]) symbol = position["symbol"] side = self._sides[position["side"]] exchange = position["exchange"] product = position["product"] if qty > 0: try: self.order_place( symbol=symbol, quantity=qty, order_type="MARKET", side=side, variety="regular", exchange=exchange, product=product, ) except Exception as e: print(e) def get_instrument_map(self, exchange="NSE", key="tradingsymbol", value="instrument_token"): """ Get the instrument map as a dictionary exchange exchange to fetch the symbols and tokens key dictionary key to be used as the key in the output value dictionary value to be used as the value in the output Note ----- 1) The instrument map is returned as a dictionary with key as the symbol and instrument token as value """ instruments = self.kite.instruments(exchange=exchange) inst_map = {inst[key]: inst[value] for inst in instruments} return inst_map
# Cancel that order (immidiate and orders function) # kite.cancel_order(variety='regular', # order_id=order_id) # trade_list = pd.concat([trade_list,pd.DataFrame(kite.trades())],axis=0) # order_list = pd.concat([order_list,pd.DataFrame(kite.orders())],axis=0) # Place an Execuatable Limit Order # Market Order # Bracket Order order_id = kite.place_order(tradingsymbol="ADANIPORTS", variety= 'bo', exchange=kite.EXCHANGE_NSE, transaction_type=kite.TRANSACTION_TYPE_BUY, quantity=1, price= 365.90, order_type=kite.ORDER_TYPE_LIMIT, product=kite.PRODUCT_MIS,stoploss=3,squareoff=5) orders = pd.DataFrame(kite.orders()) # Automated Bracket Order Modify order_id = kite.modify_order(variety='bo',order_id=order_id,quantity=1,price=366.0) orders = pd.DataFrame(kite.orders()) orders.to_csv('F:\DevAPT\APT\Simulation\Sample_Order_Response.csv') # cancel BO kite.cancel_order(variety='bo', order_id=order_id)
def start(name, access_token, lot_size): logging.basicConfig(filename=name + "_OMS.log", format='%(asctime)s %(message)s', filemode='w') # Creating an object logger = logging.getLogger() # Setting the threshold of logger to DEBUG logger.setLevel(logging.DEBUG) # Authenticate time.sleep(140) logger.debug("OMS started") path = '/home/ubuntu/APT/APT/Live_Trading' os.chdir(path) config = configparser.ConfigParser() config_path = path + '/config.ini' config.read(config_path) api_key = config['API']['API_KEY'] # Connect to kite kite = KiteConnect(api_key=api_key) kite.set_access_token(access_token) logger.debug("OMS Authenticated") # Initialise variables first_order = 1 stoploss_modified = 0 local_order = 0 day_high = 0 day_low = 0 quantity = 5 # Read previous day data file data = pd.read_csv(path + '/previous_day_data_' + name + '.csv') pivots = pivotpoints(data) # Local orders dataframes previous_strategy_orders = pd.DataFrame() # Create current order tracker dataframe current_order_parameters = [ 'order_id', 'order_type', 'transaction_type', 'parent_order_id', 'price', 'status' ] current_order = pd.DataFrame(columns=current_order_parameters) all_orders = pd.DataFrame(columns=current_order_parameters) # Get order update from KITE previous_kite_orders = pd.DataFrame(kite.orders()) print("Order Management Started") message = ("Order Management script started for: " + str(name)) requests.get( "https://api.telegram.org/bot823468101:AAEqDCOXI3zBxxURkTgtleUvFvQ0S9a4TXA/sendMessage?chat_id=-383311990&text=" + message) # Start infinite loop while True: if datetime.now().second % 10 == 0: kite_orders = pd.DataFrame(kite.orders()) current_order = current_order.reset_index(drop=True) # Proceed if any new updates are there if not kite_orders.equals(previous_kite_orders): if len(current_order) == 1: # check if status of order is complete if kite_orders['status'][ kite_orders['order_id'] == current_order.at[ 0, 'order_id']].values[0] == 'COMPLETE': # change current order status current_order = current_order.reset_index(drop=True) current_order.at[0, 'status'] = 'COMPLETE' # append executed order to all orders all_orders = all_orders.append(current_order) # append stoploss and target orders current_order = current_order.append( kite_orders.loc[kite_orders['parent_order_id'] == current_order.at[0, 'order_id'], current_order_parameters]) current_order = current_order.reset_index(drop=True) # send message to telegram message = ( str(current_order.at[0, 'transaction_type']) + " order executed for " + name + " at " + str(current_order.at[0, 'price'])) requests.get( "https://api.telegram.org/bot823468101:AAEqDCOXI3zBxxURkTgtleUvFvQ0S9a4TXA/sendMessage?chat_id=-383311990&text=" + message) logger.debug( "Complete status case handled successfully") if len(current_order) == 2: # cancel secondary order on execution of primary order and vice-versa if kite_orders['status'][ kite_orders['order_id'] == current_order.at[ 0, 'order_id']].values[0] == 'COMPLETE': kite.cancel_order( variety='bo', order_id=current_order.at[1, 'order_id'].values[0]) # drop cancelled order row current_order = current_order.drop( current_order.index[1]) first_order = 0 # change current order status current_order = current_order.reset_index(drop=True) current_order.at[0, 'status'] = 'COMPLETE' # append executed order to all orders all_orders = all_orders.append(current_order) # append stoploss and target orders current_order = current_order.append( kite_orders.loc[kite_orders['parent_order_id'] == current_order.at[0, 'order_id'], current_order_parameters]) current_order = current_order.reset_index(drop=True) # send message to telegram message = ( str(current_order.at[0, 'transaction_type']) + " order executed for " + name + " at " + str(current_order.at[0, 'price'])) requests.get( "https://api.telegram.org/bot823468101:AAEqDCOXI3zBxxURkTgtleUvFvQ0S9a4TXA/sendMessage?chat_id=-383311990&text=" + message) logger.debug("Secondary order cancelled") elif kite_orders['status'][ kite_orders['order_id'] == current_order.at[ 1, 'order_id']].values[0] == 'COMPLETE': kite.cancel_order( variety='bo', order_id=current_order.at[0, 'order_id'].values[0]) # drop cancelled order row current_order = current_order.drop( current_order.index[0]) first_order = 0 # change current order status current_order = current_order.reset_index(drop=True) current_order.at[0, 'status'] = 'COMPLETE' # append stoploss and target orders current_order = current_order.append( kite_orders.loc[kite_orders['parent_order_id'] == current_order.at[0, 'order_id'], current_order_parameters]) current_order = current_order.reset_index(drop=True) # append executed order to all orders all_orders = all_orders.append(current_order) # send message to telegram message = ( str(current_order.at[0, 'transaction_type']) + " order executed for " + name + " at " + str(current_order.at[0, 'price'])) requests.get( "https://api.telegram.org/bot823468101:AAEqDCOXI3zBxxURkTgtleUvFvQ0S9a4TXA/sendMessage?chat_id=-383311990&text=" + message) logger.debug("Primary order cancelled") # if stoploss hits if len(current_order) == 3: if kite_orders['status'][ kite_orders['order_id'] == current_order['order_id'][ current_order['order_type'] == 'SL'].values[0]].values[0] == 'COMPLETE': # order transaction type primary_transaction_type = 'SELL' if current_order.at[ 0, 'transaction_type'] == 'BUY' else 'BUY' secondary_transaction_type = current_order.at[ 0, 'transaction_type'] # entry price primary_entry_price = current_order['price'][ current_order['order_type'] == 'SL'] secondary_entry_price = day_high if primary_transaction_type == 'SELL' else day_low # update local order id local_order = local_order + 1 # clear previous orders current_order = current_order[0:0] # place first order at current market price order_id = kite.place_order( tradingsymbol=name, variety='bo', exchange=kite.EXCHANGE_NSE, transaction_type=primary_transaction_type, quantity=quantity, price=primary_entry_price, trigger_price=primary_entry_price, order_type=kite.ORDER_TYPE_SL, product=kite.PRODUCT_MIS, stoploss=(day_high - primary_entry_price) if primary_transaction_type == 'SELL' else (primary_entry_price - day_low), squareoff=get_target(pivots, primary_entry_price, primary_transaction_type, lot_size)) current_order = current_order.append( { 'order_id': order_id, 'local_order_id': local_order, 'order_type': 'LIMIT', 'transaction_type': primary_transaction_type, 'parent_order_id': 'NA', 'price': primary_entry_price, 'status': 'OPEN' }, ignore_index=True) # send message to telegram message = (primary_transaction_type + " order placed for " + name + " at " + str(primary_entry_price)) requests.get( "https://api.telegram.org/bot823468101:AAEqDCOXI3zBxxURkTgtleUvFvQ0S9a4TXA/sendMessage?chat_id=-383311990&text=" + message) # place second order at stoploss order_id = kite.place_order( tradingsymbol=name, variety='bo', exchange=kite.EXCHANGE_NSE, transaction_type=secondary_transaction_type, quantity=quantity, price=secondary_entry_price, trigger_price=secondary_entry_price, order_type=kite.ORDER_TYPE_SL, product=kite.PRODUCT_MIS, stoploss=(day_high - secondary_entry_price) if secondary_transaction_type == 'SELL' else (secondary_entry_price - day_low), squareoff=get_target(pivots, secondary_entry_price, secondary_transaction_type, lot_size)) current_order = current_order.append( { 'order_id': order_id, 'local_order_id': local_order + 1, 'order_type': 'LIMIT', 'transaction_type': secondary_transaction_type, 'parent_order_id': 'NA', 'price': secondary_entry_price, 'status': 'OPEN' }, ignore_index=True) # send message to telegram message = (secondary_transaction_type + " order placed for " + name + " at " + str(secondary_entry_price)) requests.get( "https://api.telegram.org/bot823468101:AAEqDCOXI3zBxxURkTgtleUvFvQ0S9a4TXA/sendMessage?chat_id=-383311990&text=" + message) # update stoploss status stoploss_modified = 0 logger.debug("Stoploss hit case handled") # if target hits if len(current_order) == 3: if kite_orders['status'][ kite_orders['order_id'] == current_order['order_id'][ (current_order['order_type'] == 'LIMIT') & (current_order['transaction_type'] != current_order.at[0, 'transaction_type'])]. values[0]].values[0] == 'COMPLETE': # order transaction type transaction_type = 'SELL' if current_order.at[ 0, 'transaction_type'] == 'BUY' else 'BUY' # entry price entry_price = day_low if transaction_type == 'SELL' else day_high # update local order id local_order = local_order + 1 # clear previous orders current_order = current_order[0:0] order_id = kite.place_order( tradingsymbol=name, variety='bo', exchange=kite.EXCHANGE_NSE, transaction_type=transaction_type, quantity=quantity, price=entry_price, trigger_price=entry_price, order_type=kite.ORDER_TYPE_SL, product=kite.PRODUCT_MIS, stoploss=(day_high - entry_price) if transaction_type == 'SELL' else (entry_price - day_low), squareoff=get_target(pivots, entry_price, transaction_type, lot_size)) current_order = current_order.append( { 'order_id': order_id, 'local_order_id': local_order, 'order_type': 'LIMIT', 'transaction_type': transaction_type, 'parent_order_id': 'NA', 'price': entry_price, 'status': 'OPEN' }, ignore_index=True) # send message to telegram message = (transaction_type + " order placed for " + name + " at " + str(entry_price)) requests.get( "https://api.telegram.org/bot823468101:AAEqDCOXI3zBxxURkTgtleUvFvQ0S9a4TXA/sendMessage?chat_id=-383311990&text=" + message) # update stoploss status stoploss_modified = 0 logger.debug("Target hit case handled") # copy current orders to previous orders previous_kite_orders = kite_orders.copy(deep=True) time.sleep(1) elif datetime.now().minute % 5 == 0 and datetime.now( ).second >= 15 and datetime.now().second <= 17: if os.path.isfile('live_order_' + name + '_' + str(datetime.now().date()) + '.csv'): strategy_orders = pd.read_csv('live_order_' + name + '_' + str(datetime.now().date()) + '.csv') # if orders present in strategy orders file if not strategy_orders.equals(previous_strategy_orders): # first order of the day if first_order == 1: # get day high and day low day_high = strategy_orders.at[0, 'day_high'] day_low = strategy_orders.at[0, 'day_low'] local_order = strategy_orders.at[0, 'order_id'] # place first order at current market price transaction_type = strategy_orders.at[ 0, 'transaction_type'] entry_price = strategy_orders.at[0, 'price'] order_id = kite.place_order( tradingsymbol=name, variety='bo', exchange=kite.EXCHANGE_NSE, transaction_type=transaction_type, quantity=quantity, price=entry_price, trigger_price=entry_price, order_type=kite.ORDER_TYPE_SL, product=kite.PRODUCT_MIS, stoploss=(strategy_orders.at[0, 'stoploss'] - entry_price) if transaction_type == 'SELL' else (entry_price - strategy_orders.at[0, 'stoploss']), squareoff=(entry_price - strategy_orders.at[0, 'target']) if transaction_type == 'SELL' else (strategy_orders.at[0, 'target'] - entry_price)) current_order = current_order.append( { 'order_id': order_id, 'local_order_id': local_order, 'order_type': 'LIMIT', 'transaction_type': transaction_type, 'parent_order_id': 'NA', 'price': entry_price, 'status': 'OPEN' }, ignore_index=True) # send message to telegram message = (transaction_type + " order placed for " + name + " at " + str(entry_price)) requests.get( "https://api.telegram.org/bot823468101:AAEqDCOXI3zBxxURkTgtleUvFvQ0S9a4TXA/sendMessage?chat_id=-383311990&text=" + message) # place second order at stoploss transaction_type = 'SELL' if strategy_orders.at[ 0, 'transaction_type'] == 'BUY' else 'BUY' entry_price = strategy_orders.at[0, 'stoploss'] order_id = kite.place_order( tradingsymbol=name, variety='bo', exchange=kite.EXCHANGE_NSE, transaction_type=transaction_type, quantity=quantity, price=entry_price, trigger_price=entry_price, order_type=kite.ORDER_TYPE_SL, product=kite.PRODUCT_MIS, stoploss=(day_high - entry_price) if strategy_orders.at[0, 'transaction_type'] == 'SELL' else (entry_price - day_low), squareoff=get_target(pivots, entry_price, transaction_type, lot_size)) current_order = current_order.append( { 'order_id': order_id, 'local_order_id': local_order + 1, 'order_type': 'LIMIT', 'transaction_type': transaction_type, 'parent_order_id': 'NA', 'price': entry_price, 'status': 'OPEN' }, ignore_index=True) # send message to telegram message = (str(transaction_type) + " order placed for " + name + " at " + str(entry_price)) requests.get( "https://api.telegram.org/bot823468101:AAEqDCOXI3zBxxURkTgtleUvFvQ0S9a4TXA/sendMessage?chat_id=-383311990&text=" + message) first_order = 0 local_order = local_order + 1 logger.debug("First order placed for " + name) # update day high and day low day_high = strategy_orders.loc[( strategy_orders['order_id'] == current_order.at[ 0, 'local_order_id']), 'day_high'] day_low = strategy_orders.loc[( strategy_orders['order_id'] == current_order.at[ 0, 'local_order_id']), 'day_low'] logger.debug("Day high updated") logger.debug("Day low updated") # modify stoploss if semi-target is hit if strategy_orders['semi-target_status'][ strategy_orders['order_id'] == current_order.at[ 0, 'local_order_id']].values[ 0] == 1 and stoploss_modified == 0: # if order is executed if current_order.at[0, 'status'] == 'COMPLETE': # modify stoploss modified_price = strategy_orders['semi-target'][ strategy_orders['order_id'] == current_order.at[0, 'local_order_id']].values[0] order_id = kite.modify_order( variety='bo', order_id=current_order.at[0, 'order_id'], quantity=quantity, price=modified_price) # send message to telegram message = ("Stoploss modified to " + str(modified_price) + " for " + name) requests.get( "https://api.telegram.org/bot823468101:AAEqDCOXI3zBxxURkTgtleUvFvQ0S9a4TXA/sendMessage?chat_id=-383311990&text=" + message) # update stoploss status stoploss_modified = 1 logger.debug("Stoploss modified to semi-target: ", modified_price) # if order was not executed elif current_order.at[ 0, 'status'] == 'OPEN' and current_order.at[ 1, 'status'] == 'OPEN': transaction_type = 'SELL' if current_order.at[ 0, 'transaction_type'] == 'BUY' else 'BUY' entry_price = current_order.at[1, 'semi-target'] # cancel both pending orders kite.cancel_order(variety='bo', order_id=current_order.at[ 0, 'order_id'].values[0]) kite.cancel_order(variety='bo', order_id=current_order.at[ 1, 'order_id'].values[0]) # empty dataframe current_order = current_order[0:0] # place new order order_id = kite.place_order( tradingsymbol=name, variety='bo', exchange=kite.EXCHANGE_NSE, transaction_type=transaction_type, quantity=quantity, price=entry_price, trigger_price=entry_price, order_type=kite.ORDER_TYPE_SL, product=kite.PRODUCT_MIS, stoploss=(day_high - entry_price) if transaction_type == 'SELL' else (entry_price - day_low), squareoff=get_target(pivots, entry_price, transaction_type, lot_size)) current_order = current_order.append( { 'order_id': order_id, 'local_order_id': local_order + 1, 'order_type': 'LIMIT', 'transaction_type': transaction_type, 'parent_order_id': 'NA', 'price': entry_price, 'status': 'OPEN' }, ignore_index=True) # send message to telegram message = (str(transaction_type) + " order placed for " + name + " at " + str(entry_price)) requests.get( "https://api.telegram.org/bot823468101:AAEqDCOXI3zBxxURkTgtleUvFvQ0S9a4TXA/sendMessage?chat_id=-383311990&text=" + message) # update stoploss status stoploss_modified = 0 local_order = local_order + 1 logger.debug("Exception case handled") previous_strategy_orders = strategy_orders.copy(deep=True) time.sleep(1) elif datetime.now().hour == 9 and datetime.now().minute >= 59: all_orders.to_csv('LiveTrading_Output' + name + '.csv') logger.debug("Order file saved") # send message to telegram message = ("Live orders file sent to mail") requests.get( "https://api.telegram.org/bot823468101:AAEqDCOXI3zBxxURkTgtleUvFvQ0S9a4TXA/sendMessage?chat_id=-383311990&text=" + message) time.sleep(120) else: time.sleep(1)
]) previous_local_all_orders = pd.read_csv('filename') while True: if datetime.now().second % 10 == 0: if order_punched == 1: kite_all_orders = pd.DataFrame(kite.orders()) # update order status # order_id_list = dict(zip(data.order_id, data.status)) # cancel second order if first order got executed order_id_list = list( kite_all_orders.loc[kite_all_orders['status'] == 'OPEN', 'parent_order_id'].items()) if kite_all_orders.at[order_id_list[0], 'status'] == 'Complete': kite.cancel_order(variety='bo', order_id=order_id_list[1]) if kite_all_orders.at[order_id_list[1], 'status'] == 'Complete': kite.cancel_order(variety='bo', order_id=order_id_list[0]) # place reverse entry if stoploss executed # if kite_all_orders elif datetime.now().minute % 5 == 0: local_all_orders = pd.read_csv('filename') if len(local_all_orders) > 0: if order_punched == 0 and len(local_all_orders) > 0: order_punched = 1 order_index = len(local_all_orders) - 1 # update day high and day low if local_all_orders != previous_local_all_orders: