def on_md_publish(self, publish_msg): """" on_md_publish. """ topic = publish_msg[0] raw_message = publish_msg[1] msg = JsonMessage(raw_message) if msg.type == 'W': # Full Refresh self.on_md_full_refresh(msg) elif msg.type == 'X': # Incremental self.on_md_incremental(msg)
def sendString(self, string_msg): if not self.isConnected() and self.reopen: self.connect() self.trade_in_socket.send_unicode("REQ," + self.connection_id + ',' + string_msg) response_message = self.trade_in_socket.recv() raw_resp_message_header = response_message[:3] raw_resp_message = response_message[4:].strip() rep_msg = None if raw_resp_message: try: rep_msg = JsonMessage(raw_resp_message) except Exception: pass if raw_resp_message_header == 'CLS' and rep_msg and not rep_msg.isErrorMessage( ): self.close() if self.reopen: self.connect() return rep_msg if raw_resp_message_header != 'REP': self.close() if self.reopen: self.connect() if rep_msg and rep_msg.isErrorMessage(): raise TradeClientException(rep_msg.get('Description'), rep_msg.get('Detail')) raise TradeClientException('Invalid request: ' + raw_resp_message) if rep_msg and rep_msg.isUserResponse(): if rep_msg.get("UserStatus") == 1: self.user_id = rep_msg.get("UserID") self.is_logged = True if self.trade_pub_socket: self.trade_pub_socket.setsockopt( zmq.SUBSCRIBE, '^' + str(self.user_id) + '$') return rep_msg
def sendString(self, string_msg): if not self.isConnected() and self.reopen: self.connect() self.trade_in_socket.send_unicode( "REQ," + self.connection_id + ',' + string_msg) response_message = self.trade_in_socket.recv() raw_resp_message_header = response_message[:3] raw_resp_message = response_message[4:].strip() rep_msg = None if raw_resp_message: try: rep_msg = JsonMessage(raw_resp_message) except Exception: pass if raw_resp_message_header == 'CLS' and rep_msg and not rep_msg.isErrorMessage(): self.close() if self.reopen: self.connect() return rep_msg if raw_resp_message_header != 'REP': self.close() if self.reopen: self.connect() if rep_msg and rep_msg.isErrorMessage(): raise TradeClientException(rep_msg.get('Description'), rep_msg.get('Detail')) raise TradeClientException('Invalid request: ' + raw_resp_message ) if rep_msg and rep_msg.isUserResponse(): if rep_msg.get("UserStatus") == 1: self.user_id = rep_msg.get("UserID") self.is_logged = True if self.trade_pub_socket: self.trade_pub_socket.setsockopt(zmq.SUBSCRIBE, str(self.user_id)) return rep_msg
def on_md_publish(self, publish_msg): """" on_md_publish. """ start = datetime.datetime.now() topic = publish_msg[0] raw_message = publish_msg[1] msg = JsonMessage(raw_message) if msg.type == 'W': # Full Refresh self.on_md_full_refresh(msg) elif msg.type == 'X': # Incremental self.on_md_incremental(msg) finish = datetime.datetime.now() self.application.log( "DEBUG", "PERF", str([(finish - start).total_seconds(), "MarketDataSubscriber.on_md_publish", "1", [topic, raw_message]]))
def on_message(self, raw_message): if not self.trade_client.isConnected(): return try: req_msg = JsonMessage(raw_message) except InvalidMessageException as e: self.write_message( '{"MsgType":"ERROR", "Description":"Invalid message", "Detail": "' + str(e) + '"}') self.application.unregister_connection(self) self.trade_client.close() self.close() return if req_msg.isUserRequest(): if req_msg.has('Password'): raw_message = raw_message.replace(req_msg.get('Password'), '*') if req_msg.has('NewPassword'): raw_message = raw_message.replace(req_msg.get('NewPassword'), '*') self.application.log('IN', self.trade_client.connection_id ,raw_message ) else: self.application.log('IN', self.trade_client.connection_id, raw_message ) if req_msg.isTestRequest() or req_msg.isHeartbeat(): dt = datetime.datetime.now() response_msg = { 'MsgType' : '0', 'TestReqID' : req_msg.get('TestReqID'), 'ServerTimestamp' : int(mktime(dt.timetuple()) + dt.microsecond/1000.0 ) } sendTime = req_msg.get('SendTime') if sendTime: response_msg['SendTime'] = sendTime self.write_message(str(json.dumps(response_msg, cls=JsonEncoder))) return if req_msg.isTradeHistoryRequest(): # Trade History request self.on_trade_history_request(req_msg) return if req_msg.isMarketDataRequest(): # Market Data Request self.on_market_data_request(req_msg) if not self.trade_client.isConnected(): self.application.log('DEBUG', self.trade_client.connection_id, 'not self.trade_client.isConnected()' ) self.application.unregister_connection(self) self.trade_client.close() self.close() return if req_msg.isSecurityStatusRequest(): self.on_security_status_request(req_msg) return if req_msg.isDepositRequest(): if not req_msg.get('DepositMethodID') and not req_msg.get('DepositID'): currency = req_msg.get('Currency') secret = uuid.uuid4().hex callback_url = self.application.options.callback_url + secret hot_wallet = self.get_broker_wallet('hot', currency) cold_wallet = self.get_broker_wallet('cold', currency) if not hot_wallet and not cold_wallet: return if not hot_wallet and cold_wallet: dest_wallet = cold_wallet elif hot_wallet and not cold_wallet: dest_wallet = hot_wallet else: # 62.5% of all deposits go to the cold wallet, and 37.5% go to the hot wallet dest_wallet = hot_wallet if secret[0] in ('0','1','2','3','4','5','6','7','8','9'): dest_wallet = cold_wallet if not dest_wallet: return parameters = urllib.urlencode({ 'method': 'create', 'address': dest_wallet, 'callback': callback_url, 'currency': currency }) try: url_payment_processor = self.application.options.url_payment_processor + '?' + parameters self.application.log('DEBUG', self.trade_client.connection_id, "invoking..." + url_payment_processor ) response = urllib2.urlopen(url_payment_processor) data = json.load(response) self.application.log('DEBUG', self.trade_client.connection_id, str(data) ) req_msg.set('InputAddress', data['input_address']) req_msg.set('Destination', data['destination']) req_msg.set('Secret', secret) except urllib2.HTTPError as e: out_message = json.dumps({ 'MsgType': 'ERROR', 'ReqID': req_msg.get('DepositReqID'), 'Description': 'Blockchain.info is not available at this moment, please try again within few minutes', 'Detail': str(e) }) self.write_message(out_message) return except Exception as e: out_message = json.dumps({ 'MsgType': 'ERROR', 'ReqID': req_msg.get('DepositReqID'), 'Description': 'Error retrieving a new deposit address from Blockchain.info. Please, try again', 'Detail': str(e) }) self.write_message(out_message) return try: resp_message = self.trade_client.sendMessage(req_msg) if resp_message: self.write_message(resp_message.raw_message) if resp_message and resp_message.isUserResponse(): self.user_response = resp_message if not self.trade_client.isConnected(): self.application.log('DEBUG', self.trade_client.connection_id, 'not self.trade_client.isConnected()' ) self.application.unregister_connection(self) self.trade_client.close() self.close() except TradeClientException as e: exception_message = { 'MsgType': 'ERROR', 'Description': 'Invalid message', 'Detail': str(e) } self.write_message(json.dumps(exception_message)) self.application.unregister_connection(self) self.trade_client.close() self.close()
def on_message(self, raw_message): if self.honey_pot_connection: self.application.log('INFO', "HONEY_POT", raw_message) if self.trade_client is None or not self.trade_client.isConnected(): return self.last_message_datetime.append(datetime.now()) message_time_last_second = self.last_message_datetime[-1] - timedelta( seconds=1) for x in xrange(0, len(self.last_message_datetime)): if self.last_message_datetime[x] > message_time_last_second: self.last_message_datetime = self.last_message_datetime[x:] break if len(self.last_message_datetime ) > 15: # higher than 15 messages per second self.application.log( "ERROR", "TOO_MANY_MESSAGES", "Exceed 15 messages per second. [ip=" + self.remote_ip + ",'" + raw_message + "']") self.write_message( '{"MsgType":"ERROR", "Description":"Too many messages per second", "Detail": "16 messages in the last second"}' ) self.application.unregister_connection(self) self.trade_client.close() self.close() return try: req_msg = JsonMessage(raw_message) except InvalidMessageException as e: self.write_message( '{"MsgType":"ERROR", "Description":"Invalid message", "Detail": "' + str(e) + '"}') self.application.unregister_connection(self) self.trade_client.close() self.close() return req_msg.set('RemoteIP', self.remote_ip) if req_msg.isUserRequest(): if req_msg.has('Password'): raw_message = raw_message.replace(req_msg.get('Password'), '*') if req_msg.has('NewPassword'): raw_message = raw_message.replace(req_msg.get('NewPassword'), '*') self.application.log('IN', self.trade_client.connection_id, raw_message) if req_msg.isTestRequest() or req_msg.isHeartbeat(): dt = datetime.now() response_msg = { 'MsgType': '0', 'TestReqID': req_msg.get('TestReqID'), 'ServerTimestamp': int(mktime(dt.timetuple()) + dt.microsecond / 1000.0) } sendTime = req_msg.get('SendTime') if sendTime: response_msg['SendTime'] = sendTime self.write_message(str(json.dumps(response_msg, cls=JsonEncoder))) return if req_msg.isTradeHistoryRequest(): # Trade History request self.on_trade_history_request(req_msg) return if req_msg.isMarketDataRequest(): # Market Data Request self.on_market_data_request(req_msg) if not self.trade_client.isConnected(): self.application.log('DEBUG', self.trade_client.connection_id, 'not self.trade_client.isConnected()') self.application.unregister_connection(self) self.trade_client.close() self.close() return if req_msg.isSecurityStatusRequest(): self.on_security_status_request(req_msg) return if req_msg.isDepositRequest(): if not req_msg.get('DepositMethodID') and not req_msg.get( 'DepositID'): currency = req_msg.get('Currency') secret = uuid.uuid4().hex callback_url = self.application.options.callback_url + secret hot_wallet = self.get_broker_wallet('hot', currency) cold_wallet = self.get_broker_wallet('cold', currency) if not hot_wallet and not cold_wallet: return if not hot_wallet and cold_wallet: dest_wallet = cold_wallet elif hot_wallet and not cold_wallet: dest_wallet = hot_wallet else: # 62.5% of all deposits go to the cold wallet, and 37.5% go to the hot wallet dest_wallet = hot_wallet if secret[0] in ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'): dest_wallet = cold_wallet if not dest_wallet: return parameters = urllib.urlencode({ 'method': 'create', 'address': dest_wallet, 'callback': callback_url, 'currency': currency }) try: url_payment_processor = self.application.options.url_payment_processor + '?' + parameters self.application.log('DEBUG', self.trade_client.connection_id, "invoking..." + url_payment_processor) response = urllib2.urlopen(url_payment_processor) data = json.load(response) self.application.log('DEBUG', self.trade_client.connection_id, str(data)) req_msg.set('InputAddress', data['input_address']) req_msg.set('Destination', data['destination']) req_msg.set('Secret', secret) except urllib2.HTTPError as e: out_message = json.dumps({ 'MsgType': 'ERROR', 'ReqID': req_msg.get('DepositReqID'), 'Description': 'Blockchain.info is not available at this moment, please try again within few minutes', 'Detail': str(e) }) self.write_message(out_message) return except Exception as e: out_message = json.dumps({ 'MsgType': 'ERROR', 'ReqID': req_msg.get('DepositReqID'), 'Description': 'Error retrieving a new deposit address from Blockchain.info. Please, try again', 'Detail': str(e) }) self.write_message(out_message) return try: resp_message = self.trade_client.sendMessage(req_msg) if resp_message: self.write_message(resp_message.raw_message) if resp_message and resp_message.isUserResponse(): self.user_response = resp_message if self.is_user_logged(): self.application.log('LOGIN_OK', self.trade_client.connection_id, raw_message) #TODO: Request open order list #self.trade_client. else: self.application.log('LOGIN_FAILED', self.trade_client.connection_id, raw_message) if not self.trade_client.isConnected(): self.application.log('DEBUG', self.trade_client.connection_id, 'not self.trade_client.isConnected()') self.application.unregister_connection(self) self.trade_client.close() self.close() except TradeClientException as e: exception_message = { 'MsgType': 'ERROR', 'Description': 'Invalid message', 'Detail': str(e) } self.write_message(json.dumps(exception_message)) self.application.unregister_connection(self) self.trade_client.close() self.close()
def run_application(options, instance_name): input_log_file_handler = logging.handlers.TimedRotatingFileHandler( os.path.expanduser(options.mailer_log), when='MIDNIGHT') input_log_file_handler.setFormatter(logging.Formatter(u"%(asctime)s - %(message)s")) app_logger = logging.getLogger(instance_name) app_logger.setLevel(logging.INFO) app_logger.addHandler(input_log_file_handler) ch = logging.StreamHandler(sys.stdout) ch.setLevel(logging.DEBUG) ch.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')) app_logger.addHandler(ch) app_logger.info('START') def log(command, key, value=None): log_msg = u'%s, %s, %s' %(command, key, value if value else None) app_logger.info(unicode(log_msg)) log('PARAM', 'BEGIN') log('PARAM', 'trade_in', options.trade_in) log('PARAM', 'trade_pub', options.trade_pub) log('PARAM', 'app_log', options.app_log) log('PARAM', 'maxmind_license_key', options.maxmind_license_key) log('PARAM', 'END') context = zmq.Context() socket = context.socket(zmq.SUB) socket.connect(options.trade_pub) socket.setsockopt(zmq.SUBSCRIBE, "^FRAUDER$") trade_in_socket = context.socket(zmq.REQ) trade_in_socket.connect(options.trade_in) application_trade_client = TradeClient( context, trade_in_socket) application_trade_client.connect() login_response = application_trade_client.sendJSON( MessageBuilder.login( 8999999, options.frauder_username, options.frauder_password)) if login_response.get('UserStatus') != 1: raise RuntimeError("Invalid user id") brokers = {} broker_list, broker_list_columns = application_trade_client.getBrokerList(['1']) for b in broker_list: brokers[b[0]] = { "params": b } while True: try: raw_email_message = socket.recv() log('IN', 'TRADE_IN_PUB', raw_email_message) msg = JsonMessage(raw_email_message) if not msg.isAccessLog(): continue try: broker_id = msg.get('BrokerID') except Exception as ex: traceback.print_exc() log('ERROR', 'EXCEPTION', str(ex)) time.sleep(1) except KeyboardInterrupt: app_logger.info('END') break except Exception as ex: time.sleep(1)
def onMessage(self, payload, isBinary): if isBinary: print("Binary message received: {0} bytes".format(len(payload))) reactor.stop() return if self.factory.verbose: print 'rx:', payload msg = JsonMessage(payload.decode('utf8')) if msg.isHeartbeat(): return if msg.isUserResponse(): # login response if msg.get('UserStatus') != 1: reactor.stop() raise RuntimeError('Wrong login') profile = msg.get('Profile') if profile['Type'] != 'BROKER': reactor.stop() raise RuntimeError('It is not a brokerage account') self.factory.broker_username = msg.get('Username') self.factory.broker_id = msg.get('UserID') self.factory.profile = profile return if msg.isWithdrawRefresh(): if msg.get('BrokerID') != self.factory.broker_id: return # received a message from a different broker msg.set('BrokerUsername', self.factory.broker_username) if msg.get('Status') == '1'\ and (self.factory.methods[0] == '*' or msg.get('Method') in self.factory.methods) \ and (self.factory.currencies[0] == '*' or msg.get('Currency') in self.factory.currencies): withdraw_record = Withdraw.process_withdrawal_refresh_message( self.factory.db_session, msg) if withdraw_record: process_withdraw_message = MessageBuilder.processWithdraw( action='PROGRESS', withdrawId=msg.get('WithdrawID'), data=msg.get('Data'), percent_fee=msg.get('PercentFee'), fixed_fee=msg.get('FixedFee')) withdraw_record.process_req_id = process_withdraw_message[ 'ProcessWithdrawReqID'] # sent a B6 self.sendJSON(process_withdraw_message) self.factory.db_session.commit() if msg.isProcessWithdrawResponse(): if not msg.get('Result'): return process_req_id = msg.get('ProcessWithdrawReqID') withdraw_record = Withdraw.get_withdraw_by_process_req_id( self.factory.db_session, process_req_id) should_transfer = False if withdraw_record: if withdraw_record.status == '1' and msg.get('Status') == '2'\ and (self.factory.methods[0] == '*' or withdraw_record.method in self.factory.methods)\ and (self.factory.currencies[0] == '*' or withdraw_record.currency in self.factory.currencies): if withdraw_record.account_id not in self.factory.blocked_accounts: should_transfer = True withdraw_record.status = msg.get('Status') withdraw_record.reason = msg.get('Reason') withdraw_record.reason_id = msg.get('ReasonID') self.factory.db_session.add(withdraw_record) self.factory.db_session.commit() if should_transfer: self.factory.reactor.callLater( 0, partial(self.initiateTransfer, process_req_id))
def run_application(options, instance_name): input_log_file_handler = logging.handlers.TimedRotatingFileHandler( os.path.expanduser(options.mailer_log), when='MIDNIGHT') input_log_file_handler.setFormatter(logging.Formatter(u"%(asctime)s - %(message)s")) mail_logger = logging.getLogger(instance_name) mail_logger.setLevel(logging.INFO) mail_logger.addHandler(input_log_file_handler) ch = logging.StreamHandler(sys.stdout) ch.setLevel(logging.DEBUG) ch.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')) mail_logger.addHandler(ch) mail_logger.info('START') def log(command, key, value=None): log_msg = u'%s, %s, %s' %(command, key, value if value else None) mail_logger.info(unicode(log_msg)) log('PARAM', 'BEGIN') log('PARAM', 'trade_in', options.trade_in) log('PARAM', 'trade_pub', options.trade_pub) log('PARAM', 'mailer_log', options.mailer_log) log('PARAM', 'mailchimp_apikey', options.mailchimp_apikey) log('PARAM', 'mandrill_apikey', options.mandrill_apikey) log('PARAM', 'mailer_username', options.mailer_username) log('PARAM', 'mailchimp_newsletter_list_id', options.mailchimp_newsletter_list_id) log('PARAM', 'END') context = zmq.Context() socket = context.socket(zmq.SUB) socket.connect(options.trade_pub) socket.setsockopt(zmq.SUBSCRIBE, "^EMAIL$") trade_in_socket = context.socket(zmq.REQ) trade_in_socket.connect(options.trade_in) application_trade_client = TradeClient( context, trade_in_socket) application_trade_client.connect() login_response = application_trade_client.sendJSON( MessageBuilder.login( 8999999, options.mailer_username, options.mailer_password)) if login_response.get('UserStatus') != 1: raise RuntimeError("Invalid user id") brokers = {} broker_list, broker_list_columns = application_trade_client.getBrokerList(['1']) for b in broker_list: brokers[b[0]] = { "params": b } broker_mandrill_column_index = None try: broker_mandrill_column_index = broker_list_columns.index('MandrillApiKey') except ValueError: pass for broker_id, broker_data in brokers.iteritems(): if broker_mandrill_column_index and broker_data['params'][ broker_mandrill_column_index ]: broker_data['MandrillApiKey'] = broker_data['params'][ broker_mandrill_column_index ] else: broker_data['MandrillApiKey'] = options.mandrill_apikey for broker_id, broker_data in brokers.iteritems(): print broker_id, broker_data['MandrillApiKey'] # [u'BrokerID', u'ShortName', u'BusinessName', u'Address', u'City', u'State', # u'ZipCode', u'Country', u'PhoneNumber1', u'PhoneNumber2', u'Skype', u'Currencies', # u'TosUrl', u'FeeStructure', u'TransactionFeeBuy', u'TransactionFeeSell', u'Status', # u'ranking', u'Email', u'CountryCode', u'CryptoCurrencies', u'WithdrawStructure', # u'SupportURL', u'SignupLabel', u'AcceptCustomersFrom', u'IsBrokerHub'] mailchimp_api = mailchimp.Mailchimp(options.mailchimp_apikey) try: mailchimp_api.helper.ping() except mailchimp.Error: raise RuntimeError("Invalid MailChimp API key") mandrill_api = mandrill.Mandrill(options.mandrill_apikey) try: mandrill_api.users.ping() except mandrill.Error: raise RuntimeError("Invalid Mandrill API key") while True: try: raw_email_message = socket.recv() log('IN', 'TRADE_IN_PUB', raw_email_message) msg = JsonMessage(raw_email_message) if not msg.isEmail(): log('ERROR', 'EXCEPTION', 'Received message is not an email message') continue try: broker_id = msg.get('BrokerID') sender = brokers[broker_id]['params'][broker_list_columns.index('MailerFromName')] + \ '<' + brokers[broker_id]['params'][broker_list_columns.index('MailerFromEmail')] + '>' body = "" msg_to = msg.get('To') subject = msg.get('Subject') language = msg.get('Language') content_type = 'plain' if msg.has('Template') and msg.get('Template'): params = {} if msg.has('Params') and msg.get('Params'): params = json.loads(msg.get('Params')) template_name = msg.get('Template') if template_name == 'welcome': # user signup .... let's register him on mailchimp newsletter try: mailchimp_api.lists.subscribe( id = brokers[broker_id]['params'][broker_list_columns.index('MailchimpListID')], email = {'email': params['email'] }, merge_vars = {'EMAIL' : params['email'], 'FNAME': params['username'] } ) except mailchimp.ListAlreadySubscribedError: log('ERROR', 'EXCEPTION', params['email'] + ' mailchimp.ListAlreadySubscribedError' ) except mailchimp.Error, e: log('ERROR', 'EXCEPTION', str(e)) template_content = [] for k,v in params.iteritems(): template_content.append( { 'name': k, 'content': v } ) for broker_column_key in broker_list_columns: broker_column_value = brokers[broker_id]['params'][broker_list_columns.index(broker_column_key)] template_content.append( { 'name': 'broker_' + convertCamelCase2Underscore(broker_column_key), 'content': broker_column_value } ) message = { 'from_email': brokers[broker_id]['params'][broker_list_columns.index('MailerFromEmail')], 'from_name': brokers[broker_id]['params'][broker_list_columns.index('MailerFromName')], 'to': [{'email': msg_to, 'name': params['username'],'type': 'to' }], 'metadata': {'website': 'www.blinktrade.com'}, 'global_merge_vars': template_content } result = mandrill_api.messages.send_template( template_name= (template_name + '-' + language.replace('_','-') ).lower(), template_content=template_content, message=message) log('INFO', 'SUCCESS', str(result)) continue elif msg.has('RawData') and msg.get('RawData'): body = msg.get('RawData') log('DEBUG', 'EMAIL', u'{"Sender":"%s","To":"%s","Subject":"%s", "Body":"%s" }' % (sender, msg_to, subject, body)) send_email(sender, msg_to, subject, body, content_type) log('IN', 'SENT', "") log('INFO', 'SUCCESS', msg.get('EmailThreadID')) except Exception as ex: traceback.print_exc() log('ERROR', 'EXCEPTION', str(ex)) time.sleep(1) except KeyboardInterrupt: mail_logger.info('END') break
def onMessage(self, payload, isBinary): if isBinary: print("Binary message received: {0} bytes".format(len(payload))) reactor.stop() return if self.factory.verbose: print 'rx:',payload msg = JsonMessage(payload.decode('utf8')) if msg.isHeartbeat(): return if msg.isUserResponse(): # login response if msg.get('UserStatus') != 1: reactor.stop() raise RuntimeError('Wrong login') profile = msg.get('Profile') if profile['Type'] != 'BROKER': reactor.stop() raise RuntimeError('It is not a brokerage account') self.factory.broker_username = msg.get('Username') self.factory.broker_id = msg.get('UserID') self.factory.profile = profile return if msg.isVerifyCustomerRefresh(): broker_id = msg.get('BrokerID') if broker_id != self.factory.broker_id: return # received a message from a different broker verified = msg.get('Verified') if verified != 1: return user_id = msg.get('ClientID') username = msg.get('Username') verification_data = msg.get('VerificationData') if verification_data: verification_data = json.loads(verification_data) edentiti_status = get_verification_data(verification_data, 'edentiti_status') if edentiti_status == "IN_PROGRESS": return street_address = get_verification_data(verification_data, 'address')['street1'] flat_number = '' if '/' in street_address: flat_number = street_address[:street_address.find('/') ] street_address = street_address[street_address.find('/')+1: ] street_address_parts = street_address.split(" ") street_type = "" if len(street_address_parts) > 1: street_type = street_address_parts[-1] street_address = ' '.join(street_address_parts[:-1]) street_address_parts = street_address.split(" ") street_number = "" if street_address_parts and street_address_parts[0].isdigit(): street_number = street_address_parts[0] street_address = ' '.join(street_address_parts[1:]) street_name = street_address try: res = self.factory.wsdl_client.registerUser( customerId=self.factory.edentiti_customer_id, password=self.factory.edentiti_password, ruleId='default', name={ 'givenName': get_verification_data(verification_data, 'name')['first'], 'middleNames': get_verification_data(verification_data, 'name')['middle'], 'surname': get_verification_data(verification_data, 'name')['last'] }, currentResidentialAddress={ 'country':get_verification_data(verification_data, 'address')['country_code'], 'flatNumber': flat_number, 'postcode': get_verification_data(verification_data, 'address')['postal_code'], 'propertyName':'', 'state':get_verification_data(verification_data, 'address')['state'], 'streetName':street_name, 'streetNumber': street_number , 'streetType': street_type.upper(), 'suburb':get_verification_data(verification_data, 'address')['city'] }, homePhone=get_verification_data(verification_data, 'phone_number'), dob=datetime.datetime.strptime( get_verification_data(verification_data, 'date_of_birth') ,"%Y-%m-%d")) dt = datetime.datetime.now() createdAt = int(mktime(dt.timetuple()) + dt.microsecond/1000000.0) edentiti_verification_data = { "service_provider":"edentiti", "edentiti_status": res['return']['outcome'], "id": res['return']['transactionId'], "user_id": res['return']['userId'], "status": res['return']['outcome'], "created_at": createdAt, "updated_at": createdAt } if res['return']['outcome'] == "IN_PROGRESS": edentiti_verification_data["status"] = "progress" verified = 2 if edentiti_verification_data["status"] == "valid": verified = 3 self.sendJSON( MessageBuilder.verifyCustomer(user_id, verified, json.dumps(edentiti_verification_data))) except Exception: pass
def run(self): from pyblinktrade.message import JsonMessage, InvalidMessageException from market_data_publisher import MarketDataPublisher from execution import OrderMatcher from models import Order orders = self.db_session.query(Order).filter(Order.status.in_(("0", "1"))).order_by(Order.created) for order in orders: OrderMatcher.get(order.symbol).match(self.db_session, order, self.order_matcher_disabled) while True: raw_message = self.input_socket.recv() msg_header = raw_message[:3] session_id = raw_message[4:20] json_raw_message = raw_message[21:].strip() try: msg = None if json_raw_message: try: msg = JsonMessage(json_raw_message) except InvalidMessageException, e: self.log("IN", "TRADE_IN_REQ_ERROR", raw_message) raise InvalidMessageError() # never write passwords in the log file if msg.has("Password"): raw_message = raw_message.replace(msg.get("Password"), "*") if msg.has("NewPassword"): raw_message = raw_message.replace(msg.get("NewPassword"), "*") self.log("IN", "TRADE_IN_REQ", raw_message) if msg: if msg.isMarketDataRequest(): # Market Data Request req_id = msg.get("MDReqID") market_depth = msg.get("MarketDepth") instruments = msg.get("Instruments") entries = msg.get("MDEntryTypes") transact_time = msg.get("TransactTime") timestamp = None if transact_time: timestamp = transact_time else: trade_date = msg.get("TradeDate") if not trade_date: trade_date = time.strftime("%Y%m%d", time.localtime()) self.log("OUT", "TRADEDATE", trade_date) timestamp = datetime.datetime.strptime(trade_date, "%Y%m%d") self.log("OUT", "TIMESTAMP", timestamp) if len(instruments) > 1: raise InvalidMessageError() instrument = instruments[0] om = OrderMatcher.get(instrument) response_message = MarketDataPublisher.generate_md_full_refresh( self.db_session, instrument, market_depth, om, entries, req_id, timestamp ) response_message = "REP," + json.dumps(response_message, cls=JsonEncoder) elif msg.isTradeHistoryRequest(): page = msg.get("Page", 0) page_size = msg.get("PageSize", 100) offset = page * page_size columns = [ "TradeID", "Market", "Side", "Price", "Size", "BuyerID", "SellerID", "BuyerUsername", "SellerUsername", "Created", "OrderId", "CounterOrderID", ] trade_list = MarketDataPublisher.generate_trade_history(self.db_session, page_size, offset) response_message = "REP," + json.dumps( { "MsgType": "U33", # TradeHistoryResponse "TradeHistoryReqID": -1, "Page": page, "PageSize": page_size, "Columns": columns, "TradeHistoryGrp": trade_list, }, cls=JsonEncoder, ) else: response_message = self.session_manager.process_message(msg_header, session_id, msg) else: response_message = self.session_manager.process_message(msg_header, session_id, msg) except TradeRuntimeError, e: self.db_session.rollback() self.session_manager.close_session(session_id) response_message = ( 'ERR,{"MsgType":"ERROR", "Description":"' + e.error_description.replace("'", "") + '", "Detail": ""}' )
def onMessage(self, payload, isBinary): if isBinary: print("Binary message received: {0} bytes".format(len(payload))) reactor.stop() return if self.factory.verbose: print 'rx:', payload msg = JsonMessage(payload.decode('utf8')) if msg.isHeartbeat(): return if msg.isUserResponse(): # login response if msg.get('UserStatus') != 1: reactor.stop() raise RuntimeError('Wrong login') profile = msg.get('Profile') if profile['Type'] != 'BROKER': reactor.stop() raise RuntimeError('It is not a brokerage account') self.factory.broker_username = msg.get('Username') self.factory.broker_id = msg.get('UserID') self.factory.profile = profile return if msg.isVerifyCustomerRefresh(): broker_id = msg.get('BrokerID') if broker_id != self.factory.broker_id: return # received a message from a different broker verified = msg.get('Verified') if verified != 1: return user_id = msg.get('ClientID') username = msg.get('Username') verification_data = msg.get('VerificationData') if verification_data: verification_data = json.loads(verification_data) edentiti_status = get_verification_data(verification_data, 'edentiti_status') if edentiti_status == "IN_PROGRESS": return street_address = get_verification_data(verification_data, 'address')['street1'] flat_number = '' if '/' in street_address: flat_number = street_address[:street_address.find('/')] street_address = street_address[street_address.find('/') + 1:] street_address_parts = street_address.split(" ") street_type = "" if len(street_address_parts) > 1: street_type = street_address_parts[-1] street_address = ' '.join(street_address_parts[:-1]) street_address_parts = street_address.split(" ") street_number = "" if street_address_parts and street_address_parts[0].isdigit(): street_number = street_address_parts[0] street_address = ' '.join(street_address_parts[1:]) street_name = street_address try: res = self.factory.wsdl_client.registerUser( customerId=self.factory.edentiti_customer_id, password=self.factory.edentiti_password, ruleId='default', name={ 'givenName': get_verification_data(verification_data, 'name')['first'], 'middleNames': get_verification_data(verification_data, 'name')['middle'], 'surname': get_verification_data(verification_data, 'name')['last'] }, currentResidentialAddress={ 'country': get_verification_data(verification_data, 'address')['country_code'], 'flatNumber': flat_number, 'postcode': get_verification_data(verification_data, 'address')['postal_code'], 'propertyName': '', 'state': get_verification_data(verification_data, 'address')['state'], 'streetName': street_name, 'streetNumber': street_number, 'streetType': street_type.upper(), 'suburb': get_verification_data(verification_data, 'address')['city'] }, homePhone=get_verification_data(verification_data, 'phone_number'), dob=datetime.datetime.strptime( get_verification_data(verification_data, 'date_of_birth'), "%Y-%m-%d")) dt = datetime.datetime.now() createdAt = int( mktime(dt.timetuple()) + dt.microsecond / 1000000.0) edentiti_verification_data = { "service_provider": "edentiti", "edentiti_status": res['return']['outcome'], "id": res['return']['transactionId'], "user_id": res['return']['userId'], "status": res['return']['outcome'], "created_at": createdAt, "updated_at": createdAt } if res['return']['outcome'] == "IN_PROGRESS": edentiti_verification_data["status"] = "progress" verified = 2 if edentiti_verification_data["status"] == "valid": verified = 3 self.sendJSON( MessageBuilder.verifyCustomer( user_id, verified, json.dumps(edentiti_verification_data))) except Exception: pass
def onMessage(self, payload, isBinary): if isBinary: print("Binary message received: {0} bytes".format(len(payload))) reactor.stop() return if self.factory.verbose: print 'rx:',payload msg = JsonMessage(payload.decode('utf8')) if msg.isHeartbeat(): return if msg.isUserResponse(): # login response if msg.get('UserStatus') != 1: reactor.stop() raise RuntimeError('Wrong login') profile = msg.get('Profile') if profile['Type'] != 'BROKER': reactor.stop() raise RuntimeError('It is not a brokerage account') self.factory.broker_username = msg.get('Username') self.factory.broker_id = msg.get('UserID') self.factory.profile = profile return if msg.isWithdrawRefresh(): if msg.get('BrokerID') != self.factory.broker_id: return # received a message from a different broker msg.set('BrokerUsername', self.factory.broker_username ) if msg.get('Status') == '1'\ and (self.factory.methods[0] == '*' or msg.get('Method') in self.factory.methods) \ and (self.factory.currencies[0] == '*' or msg.get('Currency') in self.factory.currencies): withdraw_record = Withdraw.process_withdrawal_refresh_message( self.factory.db_session , msg) if withdraw_record: process_withdraw_message = MessageBuilder.processWithdraw(action = 'PROGRESS', withdrawId = msg.get('WithdrawID'), data = msg.get('Data') , percent_fee = msg.get('PercentFee'), fixed_fee = msg.get('FixedFee') ) withdraw_record.process_req_id = process_withdraw_message['ProcessWithdrawReqID'] # sent a B6 self.sendJSON( process_withdraw_message ) self.factory.db_session.commit() if msg.isProcessWithdrawResponse(): if not msg.get('Result'): return process_req_id = msg.get('ProcessWithdrawReqID') withdraw_record = Withdraw.get_withdraw_by_process_req_id(self.factory.db_session, process_req_id) should_transfer = False if withdraw_record: if withdraw_record.status == '1' and msg.get('Status') == '2'\ and (self.factory.methods[0] == '*' or withdraw_record.method in self.factory.methods)\ and (self.factory.currencies[0] == '*' or withdraw_record.currency in self.factory.currencies): if withdraw_record.account_id not in self.factory.blocked_accounts: should_transfer = True withdraw_record.status = msg.get('Status') withdraw_record.reason = msg.get('Reason') withdraw_record.reason_id = msg.get('ReasonID') self.factory.db_session.add(withdraw_record) self.factory.db_session.commit() if should_transfer: self.factory.reactor.callLater(0, partial(self.initiateTransfer, process_req_id) )
def run_application(options, instance_name): input_log_file_handler = logging.handlers.TimedRotatingFileHandler( os.path.expanduser(options.mailer_log), when='MIDNIGHT') input_log_file_handler.setFormatter( logging.Formatter(u"%(asctime)s - %(message)s")) mail_logger = logging.getLogger(instance_name) mail_logger.setLevel(logging.INFO) mail_logger.addHandler(input_log_file_handler) ch = logging.StreamHandler(sys.stdout) ch.setLevel(logging.DEBUG) ch.setFormatter( logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s')) mail_logger.addHandler(ch) mail_logger.info('START') def log(command, key, value=None): log_msg = u'%s, %s, %s' % (command, key, value if value else None) mail_logger.info(unicode(log_msg)) log('PARAM', 'BEGIN') log('PARAM', 'trade_in', options.trade_in) log('PARAM', 'trade_pub', options.trade_pub) log('PARAM', 'mailer_log', options.mailer_log) log('PARAM', 'mailchimp_apikey', options.mailchimp_apikey) log('PARAM', 'mandrill_apikey', options.mandrill_apikey) log('PARAM', 'mailer_username', options.mailer_username) log('PARAM', 'mailchimp_newsletter_list_id', options.mailchimp_newsletter_list_id) log('PARAM', 'END') context = zmq.Context() socket = context.socket(zmq.SUB) socket.connect(options.trade_pub) socket.setsockopt(zmq.SUBSCRIBE, "^EMAIL$") trade_in_socket = context.socket(zmq.REQ) trade_in_socket.connect(options.trade_in) application_trade_client = TradeClient(context, trade_in_socket) application_trade_client.connect() login_response = application_trade_client.sendJSON( MessageBuilder.login(8999999, options.mailer_username, options.mailer_password)) if login_response.get('UserStatus') != 1: raise RuntimeError("Invalid user id") brokers = {} broker_list, broker_list_columns = application_trade_client.getBrokerList( ['1']) for b in broker_list: brokers[b[0]] = {"params": b} broker_mandrill_column_index = None try: broker_mandrill_column_index = broker_list_columns.index( 'MandrillApiKey') except ValueError: pass for broker_id, broker_data in brokers.iteritems(): if broker_mandrill_column_index and broker_data['params'][ broker_mandrill_column_index]: broker_data['MandrillApiKey'] = broker_data['params'][ broker_mandrill_column_index] else: broker_data['MandrillApiKey'] = options.mandrill_apikey for broker_id, broker_data in brokers.iteritems(): print broker_id, broker_data['MandrillApiKey'] # [u'BrokerID', u'ShortName', u'BusinessName', u'Address', u'City', u'State', # u'ZipCode', u'Country', u'PhoneNumber1', u'PhoneNumber2', u'Skype', u'Currencies', # u'TosUrl', u'FeeStructure', u'TransactionFeeBuy', u'TransactionFeeSell', u'Status', # u'ranking', u'Email', u'CountryCode', u'CryptoCurrencies', u'WithdrawStructure', # u'SupportURL', u'SignupLabel', u'AcceptCustomersFrom', u'IsBrokerHub'] mailchimp_api = mailchimp.Mailchimp(options.mailchimp_apikey) try: mailchimp_api.helper.ping() except mailchimp.Error: raise RuntimeError("Invalid MailChimp API key") mandrill_api = mandrill.Mandrill(options.mandrill_apikey) try: mandrill_api.users.ping() except mandrill.Error: raise RuntimeError("Invalid Mandrill API key") while True: try: raw_email_message = socket.recv() log('IN', 'TRADE_IN_PUB', raw_email_message) msg = JsonMessage(raw_email_message) if not msg.isEmail(): log('ERROR', 'EXCEPTION', 'Received message is not an email message') continue try: broker_id = msg.get('BrokerID') sender = brokers[broker_id]['params'][broker_list_columns.index('MailerFromName')] + \ '<' + brokers[broker_id]['params'][broker_list_columns.index('MailerFromEmail')] + '>' body = "" msg_to = msg.get('To') subject = msg.get('Subject') language = msg.get('Language') content_type = 'plain' if msg.has('Template') and msg.get('Template'): params = {} if msg.has('Params') and msg.get('Params'): params = json.loads(msg.get('Params')) template_name = msg.get('Template') if template_name == 'welcome': # user signup .... let's register him on mailchimp newsletter try: mailchimp_api.lists.subscribe( id=brokers[broker_id]['params'] [broker_list_columns.index('MailchimpListID')], email={'email': params['email']}, merge_vars={ 'EMAIL': params['email'], 'FNAME': params['username'] }) except mailchimp.ListAlreadySubscribedError: log( 'ERROR', 'EXCEPTION', params['email'] + ' mailchimp.ListAlreadySubscribedError') except mailchimp.Error, e: log('ERROR', 'EXCEPTION', str(e)) template_content = [] for k, v in params.iteritems(): template_content.append({'name': k, 'content': v}) for broker_column_key in broker_list_columns: broker_column_value = brokers[broker_id]['params'][ broker_list_columns.index(broker_column_key)] template_content.append({ 'name': 'broker_' + convertCamelCase2Underscore(broker_column_key), 'content': broker_column_value }) message = { 'from_email': brokers[broker_id]['params'][broker_list_columns.index( 'MailerFromEmail')], 'from_name': brokers[broker_id]['params'][broker_list_columns.index( 'MailerFromName')], 'to': [{ 'email': msg_to, 'name': params['username'], 'type': 'to' }], 'metadata': { 'website': 'www.blinktrade.com' }, 'global_merge_vars': template_content } result = mandrill_api.messages.send_template( template_name=(template_name + '-' + language.replace('_', '-')).lower(), template_content=template_content, message=message) log('INFO', 'SUCCESS', str(result)) continue elif msg.has('RawData') and msg.get('RawData'): body = msg.get('RawData') log( 'DEBUG', 'EMAIL', u'{"Sender":"%s","To":"%s","Subject":"%s", "Body":"%s" }' % (sender, msg_to, subject, body)) send_email(sender, msg_to, subject, body, content_type) log('IN', 'SENT', "") log('INFO', 'SUCCESS', msg.get('EmailThreadID')) except Exception as ex: traceback.print_exc() log('ERROR', 'EXCEPTION', str(ex)) time.sleep(1) except KeyboardInterrupt: mail_logger.info('END') break
def run(self): from pyblinktrade.message import JsonMessage, InvalidMessageException from market_data_publisher import MarketDataPublisher from execution import OrderMatcher from models import Order orders = self.db_session.query(Order).filter( Order.status.in_(("0", "1"))).order_by(Order.created) for order in orders: OrderMatcher.get(order.symbol).match(self.db_session, order, self.order_matcher_disabled) while True: raw_message = self.input_socket.recv() msg_header = raw_message[:3] session_id = raw_message[4:20] json_raw_message = raw_message[21:].strip() try: msg = None if json_raw_message: try: msg = JsonMessage(json_raw_message) except InvalidMessageException, e: self.log('IN', 'TRADE_IN_REQ_ERROR', raw_message) raise InvalidMessageError() # never write passwords in the log file if msg.has('Password'): raw_message = raw_message.replace( msg.get('Password'), '*') if msg.has('NewPassword'): raw_message = raw_message.replace( msg.get('NewPassword'), '*') self.log('IN', 'TRADE_IN_REQ', raw_message) if msg: if msg.isMarketDataRequest(): # Market Data Request req_id = msg.get('MDReqID') market_depth = msg.get('MarketDepth') instruments = msg.get('Instruments') entries = msg.get('MDEntryTypes') transact_time = msg.get('TransactTime') timestamp = None if transact_time: timestamp = transact_time else: trade_date = msg.get('TradeDate') if not trade_date: trade_date = time.strftime( "%Y%m%d", time.localtime()) self.log('OUT', 'TRADEDATE', trade_date) timestamp = datetime.datetime.strptime( trade_date, "%Y%m%d") self.log('OUT', 'TIMESTAMP', timestamp) if len(instruments) > 1: raise InvalidMessageError() instrument = instruments[0] om = OrderMatcher.get(instrument) response_message = MarketDataPublisher.generate_md_full_refresh( self.db_session, instrument, market_depth, om, entries, req_id, timestamp) response_message = 'REP,' + json.dumps( response_message, cls=JsonEncoder) elif msg.isTradeHistoryRequest(): page = msg.get('Page', 0) page_size = msg.get('PageSize', 100) offset = page * page_size columns = [ 'TradeID', 'Market', 'Side', 'Price', 'Size', 'BuyerID', 'SellerID', 'BuyerUsername', 'SellerUsername', 'Created', 'OrderId', 'CounterOrderID' ] trade_list = MarketDataPublisher.generate_trade_history( self.db_session, page_size, offset) response_message = 'REP,' + json.dumps( { 'MsgType': 'U33', # TradeHistoryResponse 'TradeHistoryReqID': -1, 'Page': page, 'PageSize': page_size, 'Columns': columns, 'TradeHistoryGrp': trade_list }, cls=JsonEncoder) else: response_message = self.session_manager.process_message( msg_header, session_id, msg) else: response_message = self.session_manager.process_message( msg_header, session_id, msg) except TradeRuntimeError, e: self.db_session.rollback() self.session_manager.close_session(session_id) response_message = 'ERR,{"MsgType":"ERROR", "Description":"' + e.error_description.replace( "'", "") + '", "Detail": ""}'
def run(self): from pyblinktrade.message import JsonMessage, InvalidMessageException from market_data_publisher import MarketDataPublisher from execution import OrderMatcher from models import Order orders = self.db_session.query(Order).filter(Order.status.in_(("0", "1"))).order_by(Order.created) for order in orders: OrderMatcher.get( order.symbol ).match(self.db_session, order, self.order_matcher_disabled) while True: raw_message = self.input_socket.recv() msg_header = raw_message[:3] session_id = raw_message[4:20] json_raw_message = raw_message[21:].strip() try: msg = None if json_raw_message: try: msg = JsonMessage(json_raw_message) except InvalidMessageException, e: self.log('IN', 'TRADE_IN_REQ_ERROR', raw_message) raise InvalidMessageError() # never write passwords in the log file if msg.has('Password'): raw_message = raw_message.replace(msg.get('Password'), '*') if msg.has('NewPassword'): raw_message = raw_message.replace(msg.get('NewPassword'), '*') self.log('IN', 'TRADE_IN_REQ' ,raw_message ) if msg: if msg.isMarketDataRequest(): # Market Data Request req_id = msg.get('MDReqID') market_depth = msg.get('MarketDepth') instruments = msg.get('Instruments') entries = msg.get('MDEntryTypes') transact_time = msg.get('TransactTime') timestamp = None if transact_time: timestamp = transact_time else: trade_date = msg.get('TradeDate') if not trade_date: trade_date = time.strftime("%Y%m%d", time.localtime()) self.log('OUT', 'TRADEDATE', trade_date) timestamp = datetime.datetime.strptime(trade_date, "%Y%m%d") self.log('OUT', 'TIMESTAMP', timestamp ) if len(instruments) > 1: raise InvalidMessageError() instrument = instruments[0] om = OrderMatcher.get(instrument) response_message = MarketDataPublisher.generate_md_full_refresh( self.db_session, instrument, market_depth, om, entries, req_id, timestamp ) response_message = 'REP,' + json.dumps( response_message , cls=JsonEncoder) elif msg.isTradeHistoryRequest(): page = msg.get('Page', 0) page_size = msg.get('PageSize', 100) offset = page * page_size columns = [ 'TradeID' , 'Market', 'Side', 'Price', 'Size', 'BuyerID' , 'SellerID', 'BuyerUsername' ,'SellerUsername', 'Created', 'OrderId' , 'CounterOrderID'] trade_list = MarketDataPublisher.generate_trade_history(self.db_session, page_size, offset ) response_message = 'REP,' + json.dumps({ 'MsgType' : 'U33', # TradeHistoryResponse 'TradeHistoryReqID' : -1, 'Page' : page, 'PageSize' : page_size, 'Columns' : columns, 'TradeHistoryGrp' : trade_list }, cls=JsonEncoder) else: response_message = self.session_manager.process_message( msg_header, session_id, msg ) else: response_message = self.session_manager.process_message( msg_header, session_id, msg ) except TradeRuntimeError, e: self.db_session.rollback() self.session_manager.close_session(session_id) response_message = 'ERR,{"MsgType":"ERROR", "Description":"' + e.error_description.replace("'", "") + '", "Detail": ""}'
def on_message(self, raw_message): if not self.trade_client.isConnected(): return try: req_msg = JsonMessage(raw_message) except InvalidMessageException as e: self.write_message( '{"MsgType":"ERROR", "Description":"Invalid message", "Detail": "' + str(e) + '"}') self.application.unregister_connection(self) self.trade_client.close() self.close() return req_msg.set('RemoteIP', self.remote_ip) if req_msg.isUserRequest(): if req_msg.has('Password'): raw_message = raw_message.replace(req_msg.get('Password'), '*') if req_msg.has('NewPassword'): raw_message = raw_message.replace(req_msg.get('NewPassword'), '*') self.application.log('IN', self.trade_client.connection_id, raw_message) if req_msg.isTestRequest() or req_msg.isHeartbeat(): dt = datetime.now() response_msg = { 'MsgType': '0', 'TestReqID': req_msg.get('TestReqID'), 'ServerTimestamp': int(mktime(dt.timetuple()) + dt.microsecond / 1000.0) } sendTime = req_msg.get('SendTime') if sendTime: response_msg['SendTime'] = sendTime self.write_message(str(json.dumps(response_msg, cls=JsonEncoder))) return if req_msg.isTradeHistoryRequest(): # Trade History request self.on_trade_history_request(req_msg) return if req_msg.isMarketDataRequest(): # Market Data Request self.on_market_data_request(req_msg) if not self.trade_client.isConnected(): self.application.log('DEBUG', self.trade_client.connection_id, 'not self.trade_client.isConnected()') self.application.unregister_connection(self) self.trade_client.close() self.close() return if req_msg.isSecurityStatusRequest(): self.on_security_status_request(req_msg) return if req_msg.isNewOrderSingle(): if self.last_order_datetime: order_time = datetime.now() order_time_less_one_second = order_time - timedelta( milliseconds=200) # max of 5 orders per second if self.last_order_datetime > order_time_less_one_second: #self.application.log('ORDER_REJECT', self.trade_client.connection_id, raw_message ) reject_message = { "MsgType": "8", "OrderID": None, "ExecID": None, "ExecType": "8", "OrdStatus": "8", "CumQty": 0, "Symbol": req_msg.get("Symbol"), "OrderQty": req_msg.get("Qty"), "LastShares": 0, "LastPx": 0, "Price": req_msg.get("Price"), "TimeInForce": "1", "LeavesQty": 0, "ExecSide": req_msg.get("Side"), "Side": req_msg.get("Side"), "OrdType": req_msg.get("OrdType"), "CxlQty": req_msg.get("Qty"), "ClOrdID": req_msg.get("ClOrdID"), "AvgPx": 0, "OrdRejReason": "Exceeded the maximum number of orders sent per second.", "Volume": 0 } #self.write_message(str(json.dumps(reject_message, cls=JsonEncoder))) #return self.last_order_datetime = datetime.now() if req_msg.isDepositRequest(): if not req_msg.get('DepositMethodID') and not req_msg.get( 'DepositID'): currency = req_msg.get('Currency') secret = uuid.uuid4().hex callback_url = self.application.options.callback_url + secret hot_wallet = self.get_broker_wallet('hot', currency) cold_wallet = self.get_broker_wallet('cold', currency) if not hot_wallet and not cold_wallet: return if not hot_wallet and cold_wallet: dest_wallet = cold_wallet elif hot_wallet and not cold_wallet: dest_wallet = hot_wallet else: # 62.5% of all deposits go to the cold wallet, and 37.5% go to the hot wallet dest_wallet = hot_wallet if secret[0] in ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'): dest_wallet = cold_wallet if not dest_wallet: return parameters = urllib.urlencode({ 'method': 'create', 'address': dest_wallet, 'callback': callback_url, 'currency': currency }) try: url_payment_processor = self.application.options.url_payment_processor + '?' + parameters self.application.log('DEBUG', self.trade_client.connection_id, "invoking..." + url_payment_processor) response = urllib2.urlopen(url_payment_processor) data = json.load(response) self.application.log('DEBUG', self.trade_client.connection_id, str(data)) req_msg.set('InputAddress', data['input_address']) req_msg.set('Destination', data['destination']) req_msg.set('Secret', secret) except urllib2.HTTPError as e: out_message = json.dumps({ 'MsgType': 'ERROR', 'ReqID': req_msg.get('DepositReqID'), 'Description': 'Blockchain.info is not available at this moment, please try again within few minutes', 'Detail': str(e) }) self.write_message(out_message) return except Exception as e: out_message = json.dumps({ 'MsgType': 'ERROR', 'ReqID': req_msg.get('DepositReqID'), 'Description': 'Error retrieving a new deposit address from Blockchain.info. Please, try again', 'Detail': str(e) }) self.write_message(out_message) return try: resp_message = self.trade_client.sendMessage(req_msg) if resp_message: self.write_message(resp_message.raw_message) if resp_message and resp_message.isUserResponse(): self.user_response = resp_message if self.is_user_logged(): self.application.log('LOGIN_OK', self.trade_client.connection_id, raw_message) #TODO: Request open order list #self.trade_client. else: self.application.log('LOGIN_FAILED', self.trade_client.connection_id, raw_message) if not self.trade_client.isConnected(): self.application.log('DEBUG', self.trade_client.connection_id, 'not self.trade_client.isConnected()') self.application.unregister_connection(self) self.trade_client.close() self.close() except TradeClientException as e: exception_message = { 'MsgType': 'ERROR', 'Description': 'Invalid message', 'Detail': str(e) } self.write_message(json.dumps(exception_message)) self.application.unregister_connection(self) self.trade_client.close() self.close()
def onMessage(self, payload, isBinary): if isBinary: print ("Binary message received: {0} bytes".format(len(payload))) reactor.stop() return if self.factory.verbose: print "rx:", payload msg = JsonMessage(payload.decode("utf8")) if msg.isHeartbeat(): return if msg.isUserResponse(): # login response if msg.get("UserStatus") != 1: reactor.stop() raise RuntimeError("Wrong login") profile = msg.get("Profile") if profile["Type"] != "BROKER": reactor.stop() raise RuntimeError("It is not a brokerage account") self.factory.broker_username = msg.get("Username") self.factory.broker_id = msg.get("UserID") self.factory.profile = profile return if msg.isWithdrawRefresh(): if msg.get("BrokerID") != self.factory.broker_id: return # received a message from a different broker msg.set("BrokerUsername", self.factory.broker_username) if ( msg.get("Status") == "1" and (self.factory.methods[0] == "*" or msg.get("Method") in self.factory.methods) and (self.factory.currencies[0] == "*" or msg.get("Currency") in self.factory.currencies) ): withdraw_record = Withdraw.process_withdrawal_refresh_message(self.factory.db_session, msg) if withdraw_record: process_withdraw_message = MessageBuilder.processWithdraw( action="PROGRESS", withdrawId=msg.get("WithdrawID"), data=msg.get("Data"), percent_fee=msg.get("PercentFee"), fixed_fee=msg.get("FixedFee"), ) withdraw_record.process_req_id = process_withdraw_message["ProcessWithdrawReqID"] # sent a B6 self.sendJSON(process_withdraw_message) self.factory.db_session.commit() if msg.isProcessWithdrawResponse(): if not msg.get("Result"): return process_req_id = msg.get("ProcessWithdrawReqID") withdraw_record = Withdraw.get_withdraw_by_process_req_id(self.factory.db_session, process_req_id) should_transfer = False if withdraw_record: if ( withdraw_record.status == "1" and msg.get("Status") == "2" and (self.factory.methods[0] == "*" or withdraw_record.method in self.factory.methods) and (self.factory.currencies[0] == "*" or withdraw_record.currency in self.factory.currencies) ): if withdraw_record.account_id not in self.factory.blocked_accounts: should_transfer = True withdraw_record.status = msg.get("Status") withdraw_record.reason = msg.get("Reason") withdraw_record.reason_id = msg.get("ReasonID") self.factory.db_session.add(withdraw_record) self.factory.db_session.commit() if should_transfer: self.factory.reactor.callLater(0, partial(self.initiateTransfer, process_req_id))