def setup(self): """ Setup the investor to run """ print "\n///--------------------------- $$$ ---------------------------\\\\\\" print '| Welcome to the unofficial Lending Club investment tool |' print " ---------------------------------------------------------------- \n" if self.verbose: print 'VERBOSE OUTPUT IS ON\n' # Auth settings print 'To start, we need to log you into Lending Club (your password will never be saved)\n' while True: self.settings.get_auth_settings() print '\nAuthenticating...' try: self.authenticate() break except Exception as e: print '\nLogin failed: {0}'.format(str(e)) print "Please try again\n" print 'Success!\n' print 'You have ${0} in your account, free to invest\n'.format(self.get_cash_balance()) # Investment settings if self.authed: print 'Now that you\'re signed in, let\'s define what you want to do\n' # Use the settings from last time if self.settings.investing['minPercent'] is not False and self.settings.investing['maxPercent'] is not False: self.settings.show_summary('Prior Settings') if util.prompt_yn('Would you like to use these settings from last time?', 'y'): self.settings.save() # to save the email that was just entered else: self.settings.get_investment_settings() else: self.settings.get_investment_settings() # All ready to start running print '\nThat\'s all we need. Now, as long as this is running, your account will be checked every {0} minutes and invested if enough funds are available.\n'.format(self.settings['frequency'])
def test_prompt_yn(self): # Yes util.get_input = lambda msg: 'y' self.assertTrue(util.prompt_yn('msg')) util.get_input = lambda msg: 'Y' self.assertTrue(util.prompt_yn('msg')) util.get_input = lambda msg: 'Yes' self.assertTrue(util.prompt_yn('msg')) # No util.get_input = lambda msg: 'n' self.assertFalse(util.prompt_yn('msg')) util.get_input = lambda msg: 'N' self.assertFalse(util.prompt_yn('msg')) util.get_input = lambda msg: 'No' self.assertFalse(util.prompt_yn('msg')) # Invalid user input def get_input(msg): self.count += 1 return 'Hi' if self.count == 1 else 'Y' util.get_input = get_input self.assertTrue(util.prompt_yn('msg')) self.assertEqual(self.count, 2)
base_dir = os.path.dirname(os.path.realpath(__file__)) app_dir = os.path.join(base_dir, '.folio_picker_test') settings = Settings(settings_dir=app_dir) investor = LendingClubInvestor.AutoInvestor(settings=settings, verbose=True) investor.get_portfolio_list = lambda: ['apple', 'bar', 'foo'] """ With default option """ while True: chosen = settings.portfolio_picker('default') print 'You chose: {0}\n'.format(chosen) if not util.prompt_yn('Again?', 'y'): break """ No default option """ while True: chosen = settings.portfolio_picker() print 'You chose: {0}\n'.format(chosen) if not util.prompt_yn('Again?', 'y'): break class TestLogger(): """ A simple and incomplete replacement for logger for testing. All logs are added to arrays """
def test_prompt_yn_prefill(self): # User enters empty string, select prefill util.get_input = lambda msg: '' self.assertTrue(util.prompt_yn('msg', 'y')) self.assertFalse(util.prompt_yn('msg', 'n'))
def get_filter_settings(self): """ Setup the advanced portfolio filters (terms, grades, existing notes, etc.) """ filters = self.investing['filters'] if not filters: filters = self.filters print 'The following questions are from the filters section of the Invest page on LendingClub\n' # Existing loans filters['exclude_existing'] = util.prompt_yn('Exclude loans already invested in?', filters['exclude_existing']) # Funding progress rounded to the nearest tenth print '---------' print 'Funding progress' progress = util.prompt_float('Only include loans which already have at least __% funding (0 - 100)', filters['funding_progress']) filters['funding_progress'] = int(round(progress / 10) * 10) print '---------' print 'Choose term (36 - 60 month)' while(True): filters['term36month'] = util.prompt_yn('Include 36 month term loans?', filters['term36month']) filters['term60month'] = util.prompt_yn('Include 60 month term loans?', filters['term60month']) # Validate 1 was chosen if not filters['term36month'] and not filters['term60month']: print 'You have to AT LEAST choose one term length!' else: break print '---------' print 'Choose interest rate grades (7.4% - 24.84%)' while(True): if util.prompt_yn('Include ALL interest rate grades', filters['grades']['All']): filters['grades']['All'] = True else: filters['grades']['All'] = False filters['grades']['A'] = util.prompt_yn('A - ~7.41%', filters['grades']['A']) filters['grades']['B'] = util.prompt_yn('B - ~12.12%', filters['grades']['B']) filters['grades']['C'] = util.prompt_yn('C - ~15.80%', filters['grades']['C']) filters['grades']['D'] = util.prompt_yn('D - ~18.76%', filters['grades']['D']) filters['grades']['E'] = util.prompt_yn('E - ~21.49%', filters['grades']['E']) filters['grades']['F'] = util.prompt_yn('F - ~23.49%', filters['grades']['F']) filters['grades']['G'] = util.prompt_yn('G - ~24.84%', filters['grades']['G']) # Verify one was chosen gradeChosen = False for grade in filters['grades']: if filters['grades'][grade] is True: gradeChosen = True if not gradeChosen: print 'You have to AT LEAST choose one interest rate grade!' else: break self.investing['filters'] = filters
def get_investment_settings(self): """ Display a series of prompts to get how the user wants to invest their available cash. This fills out the investing dictionary. """ # Minimum cash print '---------' print 'The auto investor will automatically try to invest ALL available cash into a diversified portfolio' while(True): self.investing['minCash'] = util.prompt_int('What\'s the MINIMUM amount of cash you want to invest each round?', self.investing['minCash']) if self.investing['minCash'] < 25: print '\nYou cannot invest less than $25. Please try again.' else: break # Min/max percent print '---------' while(True): print 'When auto investing, the LendingClub API will provide us a list of possible investment portfolios available at that moment.' print 'To pick the appropriate one for you, it needs to know what the minimum and maximum AVERAGE interest rate value you will accept.' print 'The investment option closest to the maximum value will be chosen and all your available cash will be invested in it.\n' self.investing['minPercent'] = util.prompt_float('What\'s MININUM average interest rate portfolio that you will accept?', self.investing['minPercent']) # Max percent should default to being larger than the min percent if self.investing['maxPercent'] is False or self.investing['maxPercent'] < self.investing['minPercent']: self.investing['maxPercent'] = self.investing['minPercent'] + 1 self.investing['maxPercent'] = util.prompt_float('What\'s MAXIMUM average interest rate portfolio that you will accept?', self.investing['maxPercent']) # Validation if self.investing['maxPercent'] < self.investing['minPercent']: print 'The maximum value must be larger than, or equal to, the minimum value. Please try again.' elif self.investing['maxPercent'] == self.investing['minPercent']: print 'It\'s very uncommon to find an available portfolio that will match an exact percent.' if not util.prompt_yn('Would you like to specify a broader range?'): break else: break # Portfolio print '---------' folioOption = False if self.investing['portfolio']: # if saved settings has a portfolio set, default the prompt to 'Y' to choose folioOption = 'y' if util.prompt_yn('Do you want to put your new investments into a named portfolio?', folioOption): self.investing['portfolio'] = self.portfolio_picker(self.investing['portfolio']) else: self.investing['portfolio'] = False # Advanced filter settings print '\n---------' if util.prompt_yn('Would you like to set advanced filter settings?', self.investing['filters'] is not False): self.get_filter_settings() # Review summary self.show_summary() if util.prompt_yn('Would you like to continue with these settings?', 'y'): self.save() else: self.get_investment_settings() return True
def get_filter_settings(self): """ Setup the advanced portfolio filters (terms, grades, existing notes, etc.) """ filters = self.investing['filters'] if not filters: filters = { 'exclude_existing': True, 'term36month': True, 'term60month': True, 'grades': { 'All': True, 'A': True, 'B': True, 'C': True, 'D': True, 'E': True, 'F': True, 'G': True } } print 'The following questions are from the filters section of the Invest page on LendingClub\n' filters['exclude_existing'] = util.prompt_yn('Exclude loans already invested in?', filters['exclude_existing']) print '---------' print 'Choose term (36 - 60 month)' while(True): filters['term36month'] = util.prompt_yn('Include 36 month term loans?', filters['term36month']) filters['term60month'] = util.prompt_yn('Include 60 month term loans?', filters['term60month']) # Validate 1 was chosen if not filters['term36month'] and not filters['term60month']: print 'You have to AT LEAST choose one term length!' else: break print '---------' print 'Choose interest rate grades (7.4% - 24.84%)' while(True): if util.prompt_yn('Include ALL interest rate grades', filters['grades']['All']): filters['grades']['All'] = True else: filters['grades']['All'] = False filters['grades']['A'] = util.prompt_yn('A - ~7.41%', filters['grades']['A']) filters['grades']['B'] = util.prompt_yn('B - ~12.12%', filters['grades']['B']) filters['grades']['C'] = util.prompt_yn('C - ~15.80%', filters['grades']['C']) filters['grades']['D'] = util.prompt_yn('D - ~18.76%', filters['grades']['D']) filters['grades']['E'] = util.prompt_yn('E - ~21.49%', filters['grades']['E']) filters['grades']['F'] = util.prompt_yn('F - ~23.49%', filters['grades']['F']) filters['grades']['G'] = util.prompt_yn('G - ~24.84%', filters['grades']['G']) # Verify one was chosen gradeChosen = False for grade in filters['grades']: if filters['grades'][grade] is True: gradeChosen = True if not gradeChosen: print 'You have to AT LEAST choose one interest rate grade!' else: break self.investing['filters'] = filters