Exemplo n.º 1
0
    def quote_response(self,quote_req_id,quote_id,quote_resp_type,symbol,product,side,dealer_id,price=None,currency = None,quantity = None):

        #HEADER
        quote_resp = fix50sp2.QuoteRequest()
        quote_resp.getHeader().setField(fix.StringField(8,'FIXT.1.1')) #BeginMessage
        quote_resp.getHeader().setField(fix.StringField(35,'AJ'))#MessageType
        quote_resp.getHeader().setField(fix.StringField(1128,'9'))  #ApplVerID - FIX50SP2
        quote_resp.getHeader().setField(fix.StringField(49,'ORP_RESZ_B'))
        quote_resp.getHeader().setField(fix.StringField(56,'BLPORPBETA'))
        quote_resp.getHeader().setField(fix.StringField(128,'DOR'))
        quote_resp.getHeader().setField(fix.SendingTime(1))#52
        quote_resp.getHeader().setField(fix.StringField(1156,'208'))#ApplExtID
        quote_resp.getHeader().setField(fix.StringField(1129,'1.5'))#CstmApplVerID
        quote_resp.getHeader().setField(fix.SendingTime(1))
        #BODY
        quote_resp.setField(fix.QuoteRespID(quote_req_id[:-4] + 'RESP' + self.genOrderID()))#693
        quote_resp.setField(fix.QuoteReqID(quote_req_id))  #131
        quote_resp.setField(fix.QuoteRespType(quote_resp_type))#694
        quote_resp.setField(fix.Symbol(symbol))#55
        quote_resp.setField(fix.Product(int(product)))#460
        quote_resp.setField(fix.Side(side))#54

        quote_resp.setField(fix.StringField(167,'FXSPOT'))
        print(datetime.datetime.utcnow().strftime('%Y%m%d-%H:%M:%S'))
        quote_resp.setField(fix.StringField(60,datetime.datetime.utcnow().strftime('%Y%m%d-%H:%M:%S')))#60
        # quote_resp.setField(fix.TransactTime(1))#60
        quote_resp.setField(fix.SettlType('0'))#63
        settl_date = datetime.datetime.utcnow()+BDay(n=2)
        quote_resp.setField(fix.SettlDate(settl_date.strftime('%Y%m%d')))#64

        if quote_resp_type == 1:
            # quote_resp.setField(fix.Price(float(price)))
            quote_resp.setField(fix.OfferPx(float(price)))
            quote_resp.setField(fix.OfferSpotRate(float(price)))
            quote_resp.setField(fix.StringField(15, str(currency)))  # Currency
            # quote_resp.setField(fix.BidPx(float(price)))
            quote_resp.setField(fix.QuoteID(quote_id))  # 117
            quote_resp.setField(fix.OrderQty(quantity)) #38
            quote_resp.setField(fix.ClOrdID(quote_resp.getField(693)+self.genOrderID()))  # 11

        group_453 = fix50sp2.QuoteRequest().NoRelatedSym().NoPartyIDs()

        group_453.setField(fix.StringField(448,'7613723'))#PartyID
        group_453.setField(fix.StringField(447,'D'))#PartyIDSource
        group_453.setField(fix.PartyRole(11))#452 - PartyRole
        quote_resp.addGroup(group_453)

        group_453.setField(fix.StringField(448,dealer_id))#PartyID
        group_453.setField(fix.StringField(447,'D'))#PartyIDSource
        group_453.setField(fix.PartyRole(1))#452 - PartyRole.
        quote_resp.addGroup(group_453)

        quote_resp.setField(fix.StringField(1300,'XOFF'))#market segment id

        print(f'SENDING QUOTE RESPONSE MESSAGE:\n ')
        # print(f'SENDING QUOTE RESPONSE MESSAGE:\n {quote_resp.toString()}')
        fix.Session.sendToTarget(quote_resp, self.sessionID)
Exemplo n.º 2
0
    def quote_request(self,symbol,currency,quantity,side,order_type,price=None):

        #HEADER
        trade = fix50sp2.QuoteRequest()
        trade.getHeader().setField(fix.StringField(8,'FIXT.1.1')) #BeginMessage
        trade.getHeader().setField(fix.StringField(35,'R'))#MessageType
        trade.getHeader().setField(fix.StringField(1128,'9'))  #ApplVerID - FIX50SP2
        trade.getHeader().setField(fix.StringField(49,'ORP_RESZ_B'))
        trade.getHeader().setField(fix.StringField(56,'BLPORPBETA'))
        trade.getHeader().setField(fix.StringField(128,'DOR'))
        trade.getHeader().setField(fix.SendingTime(1))#52
        trade.getHeader().setField(fix.StringField(1156,'208'))#ApplExtID
        trade.getHeader().setField(fix.StringField(1129,'1.5'))#CstmApplVerID

        #BODY
        trade.setField(fix.QuoteReqID(datetime.datetime.utcnow().strftime('%Y%m%d%H%M%S') + symbol + 'RFQ' + str(side)))  # 131

        group_146 = fix50sp2.QuoteRequest().NoRelatedSym()

        # group_146 = fix.Group(146,1)
        if '/' not in symbol:
            group_146.setField(fix.StringField(55,str(symbol[:3]+'/'+symbol[3:])))
        else:
            group_146.setField(fix.StringField(55, str(symbol)))
        group_146.setField(fix.StringField(167,'FXSPOT'))
        group_146.setField(fix.IntField(460,4))
        group_146.setField(fix.SettlType('0'))#SettlType
        # group_146.setField(fix.StringField(63,'0'))#SettlType
        settl_date = datetime.datetime.utcnow()+BDay(n=2)

        group_146.setField(fix.SettlDate(settl_date.strftime('%Y%m%d')))#SettlDate

        group_146.setField(fix.OrderQty(quantity))#38 - Qty
        group_146.setField(fix.StringField(15,str(currency)))#Currency
        group_146.setField(fix.StringField(54,str(side)))


        # trade.setField(fix.NoPartyIDs(4))#453 - NumberOfParties

        group_453 = fix50sp2.QuoteRequest().NoRelatedSym().NoPartyIDs()
        # group_453 = fix.Group(453,1)
        group_453.setField(fix.StringField(448,'7613723'))#PartyID
        group_453.setField(fix.StringField(447,'D'))#PartyIDSource
        group_453.setField(fix.PartyRole(11))#452 - PartyRole
        group_146.addGroup(group_453)

        group_453.setField(fix.StringField(448,'BGD1'))#PartyID
        group_453.setField(fix.StringField(447,'D'))#PartyIDSource
        group_453.setField(fix.PartyRole(1))#452 - PartyRole.
        group_146.addGroup(group_453)

        group_453.setField(fix.StringField(448,'DOR1'))#PartyID
        group_453.setField(fix.StringField(447,'D'))#PartyIDSource
        group_453.setField(fix.PartyRole(1))#452 - PartyRole.
        group_146.addGroup(group_453)

        group_453.setField(fix.StringField(448,'DOR2'))#PartyID
        group_453.setField(fix.StringField(447,'D'))#PartyIDSource
        group_453.setField(fix.PartyRole(1))#452 - PartyRole.
        group_146.addGroup(group_453)

        trade.addGroup(group_146)
        trade.setField(fix.StringField(1300,'XOFF'))#market segment id
        # trade.setField(fix.StringField(21,'z'))#HandlInst

        if order_type == '2':  # limit
            trade.setField(fix.Price(float(price)))  # if market, this tag  should be absent
        else:
            price = None

        print(f'CREATING THE FOLLOWING ORDER:\n ')
        # print(f'CREATING THE FOLLOWING ORDER:\n {trade.toString()}')
        fix.Session.sendToTarget(trade, self.sessionID)
    def fromApp(self, message, sessionID):

        print(f'<-APP: {message.toString()}')

        msg_type = message.getHeader().getField(35)
        # global offer_prices
        # global bid_prices

        #Quotes message
        if msg_type == 'S': #QUOTES

            #decompose Quotes message
            dealer_no = 0
            parties_no = int(message.getField(453))
            quote_req_id = message.getField(131)
            side = quote_req_id[-1]
            group_453 = fix50sp2.QuoteRequest().NoRelatedSym().NoPartyIDs()
            quote_id = message.getField(117)
            symbol = message.getField(55)
            product = message.getField(460)
            quantity = int(message.getField(38))
            currency = message.getField(15)

            #get prices from providers
            #PartyRole (452) == 1
            for party_id in range(1, parties_no + 1):
                message.getGroup(party_id, group_453)
                if group_453.getField(452) == '1':  # dealer
                    dealer_no += 1
                    dealer_id = group_453.getField(448)
                    # print(f'Dealer ID : {dealer_id} and Party ID {party_id}')
                    if message.isSetField(188):
                        self.quotes[symbol]['bid_prices'][dealer_id] = float(message.getField(188))
                        # bid_px = float(message.getField(188))
                    elif message.isSetField(132):
                        self.quotes[symbol]['bid_prices'][dealer_id] = float(message.getField(132))
                        # bid_px = float(message.getField(132))
                    else:
                        self.quotes[symbol]['bid_prices'][dealer_id] = 999
                        # bid_px = 999
                    # self.bid_prices[dealer_id] = bid_px

                    # self.quotes[symbol]['bid_prices'][dealer_id] = bid_px

                    if message.isSetField(190):
                        self.quotes[symbol]['offer_prices'][dealer_id] = float(message.getField(190))
                        # offer_px = float(message.getField(190))
                    elif message.isSetField(133):
                        self.quotes[symbol]['offer_prices'][dealer_id] = float(message.getField(133))
                        # offer_px = float(message.getField(133))
                    else:
                        self.quotes[symbol]['offer_prices'][dealer_id] = 999
                        # offer_px = 999
                    # self.offer_prices[dealer_id] = offer_px

                    # self.quotes[symbol]['offer_prices'][dealer_id] = offer_px

                    print(f'QUOTES FROM DEALER: {dealer_id}')
                    print(f'BID:{self.quotes[symbol]["bid_prices"][dealer_id]} - OFFER:{self.quotes[symbol]["offer_prices"][dealer_id]}')

                if (len(self.quotes[symbol]['offer_prices']) == DEALERS_NO or len(self.quotes[symbol]['offer_prices']) == DEALERS_NO):
                # if (len(self.offer_prices) == DEALERS_NO or len(self.bid_prices) == DEALERS_NO):

                    # #sort offer and bid quotes by best price
                    # self.offer_prices = sorted(self.offer_prices.items(), key=lambda kv: kv[1], reverse=False)
                    # self.bid_prices = sorted(self.bid_prices.items(), key=lambda kv: kv[1], reverse=True)
                    # print(f'Offer Prices:{self.offer_prices}, Bid Prices:{self.bid_prices}')
                    # print(f'Requesting Limit Price :{self.limit_price}')
                    # print(f'Position for {symbol} is {self.symbol_positions[symbol]["position"]}')

                    self.quotes[symbol]['offer_prices'] = sorted(self.quotes[symbol]['offer_prices'].items(), key=lambda kv: kv[1], reverse=False)
                    self.quotes[symbol]['bid_prices'] = sorted(self.quotes[symbol]['bid_prices'].items(), key=lambda kv: kv[1], reverse=True)
                    print(f'{symbol} - Offer Prices:{self.quotes[symbol]["offer_prices"]}, Bid Prices:{self.quotes[symbol]["bid_prices"]}')
                    print(f'{symbol} - Requesting Limit Price :{self.limit_price[symbol]}')
                    print(f'Position for {symbol} is {self.symbol_positions[symbol]["position"]}')

                    #case where trade in base currency
                    if symbol[:3] == currency:

                        #choose action -hit/pass
                        if side == '1':  # long - sort offer prices ascending
                            # offer_px = self.offer_prices[0][1]
                            # dealer_id = self.offer_prices[0][0]
                            # self.offer_prices = {}
                            # self.bid_prices = {}

                            if self.no_trade[symbol]:
                                self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=6,
                                                    symbol=symbol, product=product, side=side, dealer_id=self.quotes[symbol]['offer_prices'][0][0])
                                print(f'PASSED QUOTES BECAUSE "NO TRADE" ')
                                # time.sleep(1)
                                # continue
                            else:
                                if np.logical_or(self.quotes[symbol]['offer_prices'][0][1] <= self.limit_price[symbol], self.limit_price[symbol] is None):
                                # if np.logical_or(offer_px <= self.limit_price, self.limit_price is None):

                                    self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=1,
                                               symbol=symbol, product=product, side=side, dealer_id=self.quotes[symbol]['offer_prices'][0][0],
                                               price=self.quotes[symbol]['offer_prices'][0][1],currency=currency,quantity=quantity)
                                    print(f'BUY at {self.quotes[symbol]["offer_prices"][0][1]} from {self.quotes[symbol]["offer_prices"][0][0]}')
                                    # continue
                            self.quotes[symbol]['offer_prices'] = {}
                            self.quotes[symbol]['bid_prices'] = {}

                        elif side == '2':  # short
                            # bid_px = self.bid_prices[0][1]
                            # dealer_id = self.bid_prices[0][0]
                            # self.offer_prices = {}
                            # self.bid_prices = {}

                            if self.no_trade[symbol]:
                                self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=6,
                                                    symbol=symbol, product=product, side=side, dealer_id=self.quotes[symbol]['bid_prices'][0][0])
                                print(f'PASSED QUOTES BECAUSE "NO TRADE" ')
                                # time.sleep(10)
                                # continue
                            else:
                                if np.logical_or(self.quotes[symbol]['bid_prices'][0][1] >= self.limit_price[symbol], self.limit_price[symbol] is None):
                                    self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=1,
                                                   symbol=symbol, product=product, side=side, dealer_id=self.quotes[symbol]['bid_prices'][0][0],
                                                   price=self.quotes[symbol]['bid_prices'][0][1],currency=currency,quantity=quantity)
                                    print(f'SELL at {self.quotes[symbol]["bid_prices"][0][1]} from {self.quotes[symbol]["bid_prices"][0][0]}')
                                # continue
                            self.quotes[symbol]['offer_prices'] = {}
                            self.quotes[symbol]['bid_prices'] = {}

                        elif side == '0':
                            offer_px = self.offer_prices[0][1]
                            best_offer_dealer_id = self.offer_prices[0][0]
                            self.offer_prices = {}

                            bid_px = self.bid_prices[0][1]
                            best_bid_dealer_id = self.bid_prices[0][0]
                            self.bid_prices = {}
                            self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=1,
                                                symbol=symbol, product=product, side='1', dealer_id=best_offer_dealer_id,
                                                price=offer_px, currency=currency, quantity=quantity)
                            print(f'BUY at {offer_px} from {best_offer_dealer_id} - RANDOM TWO WAY QUOTES')

                            continue

                        # time.sleep(1)

                    #case where trade in secondary currency
                    elif symbol[-3:] == currency:
                        print('TRADING WITH SECONDARY CURRENCY')

                        #change side because Quotes and opposite to RFQ to take decision
                        if side == '1':
                            side = '2'
                        elif side == '2':
                            side = '1'

                        #choose action (hit/pass) - set side according to RFQ
                        if side == '1':  # long - sort offer prices ascending
                            # offer_px = self.offer_prices[0][1]
                            # dealer_id = self.offer_prices[0][0]
                            # self.offer_prices = {}
                            # self.bid_prices = {}

                            if self.no_trade[symbol]:
                                self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=6,
                                                    symbol=symbol, product=product, side='2', dealer_id=self.quotes[symbol]['offer_prices'][0][0])
                                print(f'PASSED QUOTES BECAUSE "NO TRADE" ')
                                # time.sleep(1)
                                # continue
                            else:
                                if np.logical_or(self.quotes[symbol]['offer_prices'][0][1] <= self.limit_price[symbol], self.limit_price[symbol] is None):
                                    self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=1,
                                                        symbol=symbol, product=product, side='2', dealer_id=self.quotes[symbol]['offer_prices'][0][0],
                                                        price=self.quotes[symbol]['offer_prices'][0][1], currency=currency, quantity=quantity)

                                    print(f'BUY at {self.quotes[symbol]["offer_prices"][0][1]} from {self.quotes[symbol]["offer_prices"][0][0]}')
                                    # continue
                            self.quotes[symbol]['offer_prices'] = {}
                            self.quotes[symbol]['bid_prices'] = {}

                        elif side == '2':  # short
                            # bid_px = self.bid_prices[0][1]
                            # dealer_id = self.bid_prices[0][0]
                            # self.offer_prices = {}
                            # self.bid_prices = {}

                            if self.no_trade[symbol]:
                                self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=6,
                                                    symbol=symbol, product=product, side='1', dealer_id=self.quotes[symbol]['bid_prices'][0][0])
                                print(f'PASSED QUOTES BECAUSE "NO TRADE" ')
                                # time.sleep(10)
                                # continue
                            else:
                                if np.logical_or(self.quotes[symbol]['bid_prices'][0][1] >= self.limit_price[symbol], self.limit_price[symbol] is None):
                                    self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=1,
                                                        symbol=symbol, product=product, side='1', dealer_id=self.quotes[symbol]['bid_prices'][0][0],
                                                        price=self.quotes[symbol]['bid_prices'][0][1], currency=currency, quantity=quantity)
                                    print(f'SELL at {self.quotes[symbol]["bid_prices"][0][1]} from {self.quotes[symbol]["bid_prices"][0][0]}')
                                # continue
                            self.quotes[symbol]['offer_prices'] = {}
                            self.quotes[symbol]['bid_prices'] = {}
                        elif side == '0':
                            offer_px = self.offer_prices[0][1]
                            best_offer_dealer_id = self.offer_prices[0][0]
                            self.offer_prices = {}

                            bid_px = self.bid_prices[0][1]
                            best_bid_dealer_id = self.bid_prices[0][0]
                            self.bid_prices = {}
                            self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=1,
                                                symbol=symbol, product=product, side='1', dealer_id=best_offer_dealer_id,
                                                price=offer_px, currency=currency, quantity=quantity)
                            print(f'BUY at {offer_px} from {best_offer_dealer_id} - RANDOM TWO WAY QUOTES')

                            continue

                            # time.sleep(1)


        #QuoteStatusReport message
        if msg_type == 'AI':
            quote_status = message.getField(297)
            if quote_status == str(101):
                print(f'RECEIVED QuoteStatusReport - CANCELLED BY CLIENT ')
            if quote_status == str(11):
                print(f'RECEIVED QuoteStatusReport - DEALER REJECTS LAST LOOK ')
            if quote_status == str(100):
                print(f'RECEIVED QuoteStatusReport - LP TIMEOUT ')
            if quote_status == str(4):
                print(f'RECEIVED QuoteStatusReport - LP CANCEL ALL QUOTES ')
            if quote_status == str(5):
                print(f'RECEIVED QuoteStatusReport - TRADE REQUEST REJECTION ')
                # print (message.getField(58))
                # contract = message.getField(55)
                # self.no_trade[f'{contract[:3]}/{contract[3:]}'] = 1


        #QuoteRequestReject
        if msg_type == 'AG':
            self.warnings[message.getField(131)] = message.getField(58)
            with open('warnings.pickle','wb') as f:
                pickle.dump(self.warnings, f, pickle.HIGHEST_PROTOCOL)
            print('RECEIVED QuoteRequestReject - LPs REJECTED QUOTE REQUEST')

        #Execution report
        if msg_type == '8':
            print(f'RECEIVED EXECUTION REPORT')

            #decompose message
            ord_status = message.getField(39) #0->NEW,1->PARTIALLY FILLED,2->FILLED,8->REJECTED
            quantity = message.getField(14)
            avg_px = message.getField(6)
            order_id = message.getField(17)
            side = message.getField(54)
            symbol = message.getField(55)
            exec_time = message.getField(60)
            exec_time = exec_time[:17].replace('-','').replace(':','')
            # exec_time = message.getField(11)
            side = message.getField(54)

            #update symbols_position_dict for keeping track of orders
            if ord_status == fix.OrdStatus_FILLED:

                #update current position and save to symbol_positions_dict
                if side == '1':
                    self.symbol_positions[symbol]['position'] = int(quantity) + self.symbol_positions[symbol]['position']
                elif side == '2':
                    self.symbol_positions[symbol]['position'] = -int(quantity) + self.symbol_positions[symbol]['position']
                if len(self.symbol_positions[symbol]['trades']) == 0:
                    pnl = 100000
                else:
                    previous_pnl = self.symbol_positions[symbol]['trades'][-1]['pnl']
                    price_diff = (float(avg_px) - float(self.symbol_positions[symbol]['trades'][-1]['price'])) *\
                                 float(self.symbol_positions[symbol]['trades'][-1]['quantity'])
                    if 'JPY' in symbol:
                        price_diff = (float(avg_px) - float(self.symbol_positions[symbol]['trades'][-1]['price'])) * \
                                     float(self.symbol_positions[symbol]['trades'][-1]['quantity']/100)
                    pnl = round(price_diff + previous_pnl, 2)

                order_dict = dict(price=avg_px,quantity=self.symbol_positions[symbol]['position'],side=side,
                                  order_id=order_id,time=exec_time, pnl=pnl)
                # order_dict = dict(price=avg_px,quantity=self.symbol_positions[symbol]['position'],side=side,
                #                   order_id=order_id,time=exec_time[3:17],pnl=pnl)
                self.symbol_positions[symbol]['trades'].append(order_dict)

                #save updated symbol_positions_dict
                with open('positions.pickle', 'wb') as f:
                    pickle.dump(self.symbol_positions, f, pickle.HIGHEST_PROTOCOL)

                with open('positions.pickle', 'rb') as f:
                    now = datetime.datetime.now().strftime('%Y%m%d')
                    tmp_orders = pickle.load(f)
                    tmp_orders = pd.DataFrame.from_dict(tmp_orders[symbol]['trades'], dtype=str)
                    tmp_orders.to_csv(f'{WRITE_PATH}/FIXtrades{now}{symbol.replace("/","")}.csv')
                # if os.path.exists(f'd:/fix_bloomberg/FIXtrades{now}{symbol.replace("/","")}.csv'):
                #     tmp_csv = pd.read_csv(f'd:/fix_bloomberg/FIXtrades{now}{symbol.replace("/","")}.csv')
                #     tmp_csv = pd.concat([tmp_csv,tmp_orders],axis=0,ignore_index=True)
                #     tmp_csv.to_csv(f'd:/fix_bloomberg/FIXtrades{now}{symbol.replace("/","")}.csv')
                # else:
                #     tmp_orders.to_csv(f'd:/fix_bloomberg/FIXtrades{now}{symbol.replace("/","")}.csv')


            print(f'New position of {symbol} is {self.symbol_positions[symbol]["position"]}')

        return
Exemplo n.º 4
0
    def fromApp(self, message, sessionID):

        print(f'<-APP: {message.toString()}')

        msg_type = message.getHeader().getField(35)
        global prices
        if msg_type == 'S': #QUOTES
            dealer_no = 0
            hit = False
            parties_no = int(message.getField(453))
            quote_req_id = message.getField(131)
            side = quote_req_id[-1]
            print(f'REQUESTING LIMIT PRICE :{self.limit_price} - {side} ')
            group_453 = fix50sp2.QuoteRequest().NoRelatedSym().NoPartyIDs()
            quote_id = message.getField(117)
            symbol = message.getField(55)
            product = message.getField(460)
            quantity = int(message.getField(38))
            currency = message.getField(15)

            for party_id in range(1, parties_no + 1):
                message.getGroup(party_id, group_453)
                if group_453.getField(452) == '1':  # dealer
                    dealer_no += 1
                    dealer_id = group_453.getField(448)
                    print(f'Dealer ID : {dealer_id} and Party ID {party_id}')
                    try:
                        bid_px = float(message.getField(132))
                    except:
                        bid_px = 999
                    try:
                        offer_px = float(message.getField(133))
                    except:
                        offer_px = 999

                    # if hit:
                    #     self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=6,
                    #                         symbol=symbol, product=product, side=side, dealer_id=dealer_id)
                    #     print(f'PRICE FILLED FROM PREVIOUS DEALER - PASS QUOTES FROM {dealer_id}')
                    #     continue
                    print(f'CHECKING QUOTES FROM DEALER: {dealer_id}')
                    print(f'BID PX:{bid_px} - OFFER PX:{offer_px}')
                    prices.append(offer_px)

                if len(prices)==dealers_no:
                    print(prices)

                    offer_px = prices[0]
                    prices=[]
                    if side == '1':  # long
                       if offer_px <= self.limit_price:
                           self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=1,
                                               symbol=symbol, product=product, side=side, dealer_id=dealer_id,
                                               price=offer_px,currency=currency,quantity=quantity)
                           print(f'BUY at {offer_px} from {dealer_id} - PASS QUOTES FROM OTHER DEALERS')
                           hit = True
                           # time.sleep(10)
                           continue
                       else:
                           self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=6,
                                               symbol=symbol, product=product, side=side, dealer_id=dealer_id)
                           print(f'PASSED QUOTES FROM {dealer_id} ')
                           time.sleep(1)
                           continue
                           # if party_id == parties_no:
                           #     self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=6,
                           #                         symbol=symbol, product=product, side=side, dealer_id=dealer_id) #check other dealers
                           #     print(f'CURRENT QuoteRequestPassed - REQUEST NEW QUOTES')
                           #     self.quote_request(symbol=symbol,currency=currency,quantity=quantity,side=side,order_type=1)
                           #
                           # else: #pass current request - send new
                           #     continue
                           #     # self.quote_request(symbol=symbol,currency=currency,quantity=quantity,side=side,order_type=1,)

                    if side == '2':  # long
                       if bid_px >= self.limit_price:
                           self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=1,
                                               symbol=symbol, product=product, side=side, dealer_id=dealer_id,
                                               price=self.limit_price,currency=currency,quantity=quantity)
                           print(f'SELL at {bid_px} from {dealer_id} - PASS QUOTES FROM OTHER DEALERS')
                           hit = True
                           continue
                       else:
                           self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=6,
                                               symbol=symbol, product=product, side=side, dealer_id=dealer_id)
                           print(f'PASSED QUOTES FROM {dealer_id} ')
                           # time.sleep(10)
                           continue

                        # if party_id == parties_no:
                        #     self.quote_response(quote_req_id=quote_req_id, quote_id=quote_id, quote_resp_type=6,
                        #                         symbol=symbol, product=product, side=side, dealer_id=dealer_id) #check other dealers
                        #     print(f'CURRENT QuoteRequestPassed - REQUEST NEW QUOTES')
                        #     self.quote_request(symbol=symbol,currency=currency,quantity=quantity,side=side,order_type=1)
                        #
                        # else: #pass current request - send new
                        #     continue
                        #     # self.quote_request(symbol=symbol,currency=currency,quantity=quantity,side=side,order_type=1,)

                    # if (not hit) and party_id == parties_no: # checked all and did not get the price - send again request
                    #     self.quote_request(symbol=symbol, currency=currency, quantity=quantity, side=side, order_type=1)
                    #     print(f'COULD NOT GET PRICE FROM {dealer_no} DEALERS - SEND NEW QUOTE REQUEST ')

                    # bid_spot_rate = message.getField(188)
                    # offer_spot_rate = message.getField(190)

                    # self.quote_response(quote_req_id=quote_req_id,quote_id=quote_id,quote_resp_type=1,symbol=symbol,
                    #                     product=product,dealer_id=dealer_id,side=side)
                    time.sleep(1)

                else:
                    continue
        # print(f'PRICE : {prices}')
        if msg_type == 'AI':
            print(f'RECEIVED AI message')
        if msg_type == '8':
            print(f'RECEIVED EXECUTION REPORT')
            ord_status = message.getField(39) #0->NEW,1->PARTIALLY FILLED,2->FILLED,8->REJECTED
            quantity = message.getField(14)
            avg_px = message.getField(6)

        return
    def quote_request(self,symbol,currency,quantity,side,order_type,dealers_dict):

        '''
        send QuoteRequest message to Liquidity Providers
        build the message according to ORP_v1.5_QuickFIX
        '''

        #HEADER
        trade = fix50sp2.QuoteRequest()
        trade.getHeader().setField(fix.StringField(8,'FIXT.1.1')) #BeginMessage
        trade.getHeader().setField(fix.StringField(35,'R'))#MessageType
        trade.getHeader().setField(fix.StringField(1128,'9'))  #ApplVerID - FIX50SP2
        trade.getHeader().setField(fix.StringField(49,'ORP_RESZ_B'))
        trade.getHeader().setField(fix.StringField(56,'BLPORPBETA'))
        trade.getHeader().setField(fix.StringField(128,'DOR'))
        trade.getHeader().setField(fix.SendingTime(1))#52
        trade.getHeader().setField(fix.StringField(1156,'208'))#ApplExtID
        trade.getHeader().setField(fix.StringField(1129,'1.5'))#CstmApplVerID

        #BODY
        #QuoteReqID (131) --> RFQ+datetime+symbol+side
        quote_request_id =  'RFQ' + datetime.datetime.utcnow().strftime('%Y%m%d%H%M%S') + symbol + str(side)
        trade.setField(fix.QuoteReqID(quote_request_id))  # 131

        group_146 = fix50sp2.QuoteRequest().NoRelatedSym()

        if '/' not in symbol:
            group_146.setField(fix.StringField(55,str(symbol[:3]+'/'+symbol[3:6])))
        else:
            group_146.setField(fix.StringField(55, str(symbol)))
        group_146.setField(fix.StringField(167,'FXSPOT'))
        group_146.setField(fix.IntField(460,4))
        group_146.setField(fix.SettlType('0'))#SettlType
        # settl_date = datetime.datetime.utcnow()+BDay(n=2)
        if ((datetime.datetime.utcnow() - datetime.timedelta(hours = 4)).hour < 17) or ((datetime.datetime.utcnow() - datetime.timedelta(hours = 4)).weekday() == 6):
            settl_date = datetime.datetime.utcnow()+BDay(n=2)
        else:
            settl_date = datetime.datetime.utcnow() + BDay(n=3)
        while (settl_date.strftime('%Y%m%d') in HOLIDAYS_DICT[symbol[:3]]) or (settl_date.strftime('%Y%m%d') in HOLIDAYS_DICT[symbol[-3:]]):
            settl_date +=  BDay(n=1)
        group_146.setField(fix.SettlDate(settl_date.strftime('%Y%m%d')))#SettlDate
        group_146.setField(fix.OrderQty(quantity))#38 - Qty
        group_146.setField(fix.StringField(15,str(currency)))#Currency

        #if side == 0, get two way quotes (omit tag 54)
        if side != 0:
            group_146.setField(fix.StringField(54,str(side)))

        group_453 = fix50sp2.QuoteRequest().NoRelatedSym().NoPartyIDs()
        for dealer, party_role in dealers_dict.items():
            group_453.setField(fix.StringField(448,dealer))#PartyID
            group_453.setField(fix.StringField(447,'D'))#PartyIDSource
            group_453.setField(fix.PartyRole(party_role))#452 - PartyRole.
            group_146.addGroup(group_453)

        trade.addGroup(group_146)
        trade.setField(fix.StringField(1300,'XOFF'))#market segment id
        # trade.setField(fix.StringField(21,'z'))#HandlInst

        if order_type == '2':  # limit
            trade.setField(fix.Price(float(self.limit_price)))  # if market, this tag  should be absent

        print(f'CREATING THE FOLLOWING ORDER:\n {trade.toString()}')
        fix.Session.sendToTarget(trade, self.sessionID)