/** * Receives a new MarketTransaction. We look to see whether an order we have placed has cleared. */ public synchronized void handleMessage(MarketTransaction tx) { // reset price escalation when a trade fully clears. Order lastTry = lastOrder.get(tx.getTimeslotIndex()); if (lastTry == null) // should not happen log.error("order corresponding to market tx " + tx + " is null"); else if (tx.getMWh() == lastTry.getMWh()) // fully cleared lastOrder.put(tx.getTimeslotIndex(), null); }
// set commitment leadtime to a larger number and make sure ordering // behavior is correct @Test public void testGenerateOrders2() { // set up the genco with commitment leadtime=3 PluginConfig config = new PluginConfig("Genco", "").addConfiguration("commitmentLeadtime", "3"); genco.configure(config); // all defaults // capture orders final ArrayList<Order> orderList = new ArrayList<Order>(); doAnswer( new Answer() { public Object answer(InvocationOnMock invocation) { Object[] args = invocation.getArguments(); orderList.add((Order) args[0]); return null; } }) .when(mockProxy) .routeMessage(isA(Order.class)); // set up some timeslots Timeslot ts0 = timeslotRepo.makeTimeslot(start); ts0.disable(); assertEquals("first ts has sn=0", 0, ts0.getSerialNumber()); timeslotRepo.makeTimeslot(start.plus(TimeService.HOUR)); timeslotRepo.makeTimeslot(start.plus(TimeService.HOUR * 2)); timeslotRepo.makeTimeslot(start.plus(TimeService.HOUR * 3)); timeslotRepo.makeTimeslot(start.plus(TimeService.HOUR * 4)); assertEquals("4 enabled timeslots", 4, timeslotRepo.enabledTimeslots().size()); // generate orders and check genco.generateOrders(start, timeslotRepo.enabledTimeslots()); assertEquals("two orders", 2, orderList.size()); Order first = orderList.get(0); assertEquals("first order for ts3", 3, first.getTimeslot().getSerialNumber()); assertEquals("first order price", 1.0, first.getLimitPrice(), 1e-6); assertEquals("first order for 50 mwh", -100.0, first.getMWh(), 1e-6); Order second = orderList.get(1); assertEquals("second order for ts4", 4, second.getTimeslot().getSerialNumber()); assertEquals("second order price", 1.0, second.getLimitPrice(), 1e-6); assertEquals("second order for 100 mwh", -100.0, second.getMWh(), 1e-6); }
@Test public void testGenerateOrders() { // set up the genco PluginConfig config = new PluginConfig("Genco", ""); genco.configure(config); // all defaults // capture orders final ArrayList<Order> orderList = new ArrayList<Order>(); doAnswer( new Answer() { public Object answer(InvocationOnMock invocation) { Object[] args = invocation.getArguments(); orderList.add((Order) args[0]); return null; } }) .when(mockProxy) .routeMessage(isA(Order.class)); // set up some timeslots Timeslot ts1 = timeslotRepo.makeTimeslot(start); ts1.disable(); Timeslot ts2 = timeslotRepo.makeTimeslot(start.plus(TimeService.HOUR)); Timeslot ts3 = timeslotRepo.makeTimeslot(start.plus(TimeService.HOUR * 2)); assertEquals("2 enabled timeslots", 2, timeslotRepo.enabledTimeslots().size()); // 50 mwh already sold in ts2 MarketPosition posn2 = new MarketPosition(genco, ts2, -50.0); genco.addMarketPosition(posn2, ts2); // generate orders and check genco.generateOrders(start, timeslotRepo.enabledTimeslots()); assertEquals("two orders", 2, orderList.size()); Order first = orderList.get(0); assertEquals("first order for ts2", ts2, first.getTimeslot()); assertEquals("first order price", 1.0, first.getLimitPrice(), 1e-6); assertEquals("first order for 50 mwh", -50.0, first.getMWh(), 1e-6); Order second = orderList.get(1); assertEquals("second order for ts3", ts3, second.getTimeslot()); assertEquals("second order price", 1.0, second.getLimitPrice(), 1e-6); assertEquals("second order for 100 mwh", -100.0, second.getMWh(), 1e-6); }
/** Computes a limit price with a random element. */ private Double computeLimitPrice(int timeslot, double amountNeeded) { log.debug("Compute limit for " + amountNeeded + ", timeslot " + timeslot); // start with default limits Double oldLimitPrice; double minPrice; if (amountNeeded > 0.0) { // buying oldLimitPrice = buyLimitPriceMax; minPrice = buyLimitPriceMin; } else { // selling oldLimitPrice = sellLimitPriceMax; minPrice = sellLimitPriceMin; } // check for escalation Order lastTry = lastOrder.get(timeslot); if (lastTry != null) log.debug("lastTry: " + lastTry.getMWh() + " at " + lastTry.getLimitPrice()); if (lastTry != null && Math.signum(amountNeeded) == Math.signum(lastTry.getMWh())) { oldLimitPrice = lastTry.getLimitPrice(); log.debug("old limit price: " + oldLimitPrice); } // set price between oldLimitPrice and maxPrice, according to number of // remaining chances we have to get what we need. double newLimitPrice = minPrice; // default value int current = timeslotRepo.currentSerialNumber(); int remainingTries = (timeslot - current - Competition.currentCompetition().getDeactivateTimeslotsAhead()); log.debug("remainingTries: " + remainingTries); if (remainingTries > 0) { double range = (minPrice - oldLimitPrice) * 2.0 / (double) remainingTries; log.debug("oldLimitPrice=" + oldLimitPrice + ", range=" + range); double computedPrice = oldLimitPrice + randomGen.nextDouble() * range; return Math.max(newLimitPrice, computedPrice); } else return null; // market order }