Warning: base64_decode() expects parameter 1 to be string, array given in /home/teamgillett/rateladder.com/wp-content/plugins/askapache-google-404/askapache-google-404.php on line 156
Bidding With the Prosper API Code Example QuickSnipe.java | P2P Lending, Peer to Peer Lending, People to People Lending | P2P Lending News, Information, Borrowing and Lending Strategy

Bidding With the Prosper API Code Example QuickSnipe.java

For my ProsperDays presentation this year I will demonstrating bidding with the Prosper API…  I have built a quick and dirty bid snipping java program.  (This program is not ready for primetime as bid sniping tool, but it is very close and a very effective demo.  The reason I say it is not ready is that it lacks memory, meaning that it would bid on the same listing on subsequent passes.)

I think API bidding is the 1st step in a brave new world of Prosper Lending.  For one, it easily allows custom models.

So what does this 126 line program do?

It queries the active AA-C credit grade listings…  If a listing passes my extended credit filters (hard coded) AND the minimum Prosper calculated ROI values (generated by Prosper and the floor is passed in as a parameter) AND the minimum time remaining in the auction it will place a validation test bid or a real bid.

What are the extended credit requirements of this code? Short answer… very tight.

  • 0 current DQ
  • 0-1 inquires in the last 6 months
  • 0 public records in last 10 years
  • 0 DQ in last 7 years
  • Bankcard utilization between 3% and 80%

Here is the java code (I have contributed this code to the SourceForge Prosper API project).  It requires the API classes generated by the Java2WSDL and open source tool by Apache foundation.

package prosper.api;   

import java.math.BigDecimal;
import java.math.MathContext;
import java.rmi.RemoteException;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Iterator;
import java.util.TreeMap;   

import javax.xml.rpc.ServiceException;   

import com.prosper.services.ProsperAPI.DefinitionResult;
import com.prosper.services.ProsperAPI.Field;
import com.prosper.services.ProsperAPI.Listing;
import com.prosper.services.ProsperAPI.ProsperAPILocator;
import com.prosper.services.ProsperAPI.ProsperAPISoap;
import com.prosper.services.ProsperAPI.ProsperObject;
import com.prosper.services.ProsperAPI.ProsperObjectResult;   

public class QuickSnipe
{
	private String m_Username;
	private String m_Password;
	private double m_MinROI;
	private int m_HoursToGo;
	private boolean m_PlaceBids;
	private ProsperAPISoap m_APISoap;   

	public QuickSnipe(String username, String password, double minROI, int hoursToGo, boolean placeBids) throws ServiceException
	{
		m_Username = username;
		m_Password = password;
		m_MinROI = minROI;
		m_PlaceBids = placeBids;
		m_HoursToGo = hoursToGo;
		m_APISoap = (new ProsperAPILocator()).getProsperAPISoap();
	}
	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		if (args.length!=5)
		{
			System.err.println("Usage: QuickSnipe username password minROI hoursToGo PlaceBids");
			return;
		}
		try
		{
			QuickSnipe qs = new QuickSnipe(args[0], args[1], Double.parseDouble(args[2]), Integer.parseInt(args[3]), Boolean.parseBoolean(args[4]));
			qs.snipe();
		}
		catch (Exception e)
		{
			e.printStackTrace(System.err);
		}
	}   

	private void snipe() throws Exception
	{
		DefinitionResult res = m_APISoap.login(m_Username,m_Password);
		String token = res.getMessage();
		ProsperObjectResult por = m_APISoap.query(token, "listing", getFieldsString("listing",true), "status=2 and (creditgrade=7 or creditgrade=6 or creditgrade=5 or creditgrade=4)");
		ProsperObject[] pos = por.getProsperObjects();
		TreeMap<Calendar,Listing> timeLeftListings = new TreeMap<Calendar,Listing>();
		for (int i=0; i<pos.length; i++)
		{
			Listing l = (Listing)pos[i];
			Calendar end = (Calendar)l.getStartDate().clone();
			end.add(Calendar.HOUR, (l.getDuration()*24));
			long millisToGo = end.getTimeInMillis() - System.currentTimeMillis();
			if (l.getNowDelinquent()==0  //my required extended credit and ROI
					&& (millisToGo/1000/60/60)<=m_HoursToGo
					&& l.getInquiriesLast6Months()<2
					&& l.getPublicRecordsLast10Years()==0
					&& l.getDelinquenciesLast7Years()==0
					&& l.getBankcardUtilization().doubleValue()<=.8
					&& l.getBankcardUtilization().doubleValue()>=.03
					&& ((l.getBidMaximumRate().doubleValue()+l.getROINetDefaultRate().doubleValue()+l.getROIInterestAndFeesRate().doubleValue()+l.getROIServicingFeeRate().doubleValue())>=m_MinROI)
					)
			{
				timeLeftListings.put(end, l);
			}
		}
		boolean pause = false;
		for (Iterator<listing> i = timeLeftListings.values().iterator(); i.hasNext(); )
		{
			if (pause)  // you have to pause to avoid bid throttling
				{try {Thread.sleep(6000);}catch (Exception ignore){}}
			Listing l = i.next();
			Timestamp startts = new Timestamp(l.getStartDate().getTimeInMillis());
			Calendar end = (Calendar)l.getStartDate().clone();
			end.add(Calendar.HOUR, (l.getDuration()*24));
			Timestamp endts = new Timestamp(end.getTimeInMillis());
			long hoursToGo = (end.getTimeInMillis() - System.currentTimeMillis())/1000/60/60;
			System.err.println("\n"+startts+" + "+l.getDuration()+" days = "+endts+" | Hours To Go: "+hoursToGo);
			System.err.println("Bid on Listing: "+l.getListingNumber()+"\nAt Rate: "+(m_MinROI-l.getROINetDefaultRate().doubleValue()-l.getROIInterestAndFeesRate().doubleValue()-l.getROIServicingFeeRate().doubleValue()));
			res = m_APISoap.bid(token, l.getListingNumber(), new BigDecimal(50,new MathContext(4)), new BigDecimal(m_MinROI-l.getROINetDefaultRate().doubleValue()-l.getROIInterestAndFeesRate().doubleValue()-l.getROIServicingFeeRate().doubleValue(),new MathContext(4)), m_PlaceBids);
			pause = true;
			System.err.println("Bid Message: "+res.getMessage());
		}
		m_APISoap.logout(token);
	}   

	private String getFieldsString(String type, boolean authenticated) throws RemoteException
	{
		DefinitionResult res = m_APISoap.describe(null, type);
		Field[] fields = res.getDefinition().getFields();
		int count = 0;
		String s="";
		for (int i=0; i<fields.length; i++)
		{
			if (authenticated || !fields[i].isAuthenticated())
			{
				if (count!=0)
				{
					s+= ",";
				}
				s+= fields[i].getName();
				count++;
			}
		}
		return s;
	}
}
Related posts:
If you liked this article, vote for it on del.icio.us and stumbleupon.


Categories:

Prosper.com



2 comments ↓
#1 Ben on 02.27.08 at 9:25 pm

Cool, thanks for sharing! I’ll have to get my jdk installed again at home and give it a shot.

#2 Prosper Roundup — The Week After Edition on 03.02.08 at 4:59 pm

[...] RateLadder on Prosper Days 2008 as well as the source code for the tool demonstrated at Prosper Days: QuickSnipe [...]

Leave a Comment

aa algorithm axis azerbaijan banks benefit blog borrowers ceo Collections credit grade credit history credit information credit score curves doug fuller email friends and family good luck google income borrowers interest rate interest rates investments launch lenders lending institutions liquidity loans marketplace money mozambique peer to peer lending portfolio plan private data promissory notes quiet period registration statement risk securities and exchange securities and exchange commission spreadsheets sql student loans Zopa