Monitor the Stock Price"

From Documentation
Line 41: Line 41:
 
===Composer===
 
===Composer===
 
This is the controller that handle the onCellChange event. The key method is the onCellChange$stocck() event listener. Whenever an onCellChange event is triggered, this method will be called and pass through with a CellEvent event. The event listener then compare if the cell changed is in the price column range and check if the price achieve buy or sell price setting by end user.
 
This is the controller that handle the onCellChange event. The key method is the onCellChange$stocck() event listener. Whenever an onCellChange event is triggered, this method will be called and pass through with a CellEvent event. The event listener then compare if the cell changed is in the price column range and check if the price achieve buy or sell price setting by end user.
<source lang="java" high="22,29,39,41">
+
<source lang="java" high="22,33,43,45">
 
package org.zkoss.zssessentials.cellaction;
 
package org.zkoss.zssessentials.cellaction;
 
public class StockComposer extends GenericForwardComposer {
 
public class StockComposer extends GenericForwardComposer {
Line 68: Line 68:
 
return; //not the monitorSheet, return
 
return; //not the monitorSheet, return
 
}
 
}
final int row = event.getRow();
+
final int eleft = event.getLeft();
final int col = event.getColumn();
+
final int etop = event.getTop();
if (left <= col && col <= right && top <= row && row <= bottom) { //in range
+
final int eright = event.getRight();
final Range priceRng = Ranges.range(monitorSheet, row, col);
+
final int ebottom = event.getBottom();
final Range sellRng = priceRng.getOffset(0, 3);
+
for (int row = etop; row <= ebottom; ++row) {
final Range buyRng = priceRng.getOffset(0, 2);
+
for (int col = eleft; col <= eright; ++col) {
final Range codeRng = priceRng.getOffset(0, -1);
+
if (left <= col && col <= right && top <= row && row <= bottom) { //in range
final double newPrice = ((Number)priceRng.getValue()).doubleValue();
+
final Range priceRng = Ranges.range(monitorSheet, row, col);
final double sellPrice = ((Number)sellRng.getValue()).doubleValue();
+
final Range sellRng = priceRng.getOffset(0, 3);
final double buyPrice = ((Number)buyRng.getValue()).doubleValue();
+
final Range buyRng = priceRng.getOffset(0, 2);
final String stockCode = (String) codeRng.getValue();
+
final Range codeRng = priceRng.getOffset(0, -1);
if (newPrice <= buyPrice) {
+
final double newPrice = ((Number)priceRng.getValue()).doubleValue();
buy(stockCode, priceRng);
+
final double sellPrice = ((Number)sellRng.getValue()).doubleValue();
} else if (newPrice >= sellPrice) {
+
final double buyPrice = ((Number)buyRng.getValue()).doubleValue();
sell(stockCode, priceRng);
+
final String stockCode = (String) codeRng.getValue();
 +
if (newPrice <= buyPrice) {
 +
buy(stockCode, priceRng);
 +
} else if (newPrice >= sellPrice) {
 +
sell(stockCode, priceRng);
 +
}
 +
}
 
}
 
}
 
}
 
}

Revision as of 05:42, 2 December 2010


Here is a Stock Price monitoring system that uses the ZK Spreadsheet's onCellChange event and data push mechanism.

Purpose

Automatically place buy or sell command whenever the price of a selected stock reach some preset point.

Template Excel File with Proper Name Expressions

Here is an Excel template file with monitorSheet and dataSheet. monitorSheet shows the selected stocks that refer to the dataSheet with formulas. dataSheet is a sheet that list all available stocks.

monitorSheet

Stock-monitor.png

dataSheet

Stock-data.png

How ZK Spreadsheet Do the Job

Assume a stock price service will keep on pumping in updated stock price into the dataSheet on a separate thread. Whenever a new price is updated into dataSheet, ZK Spreadsheet will trigger the cell change event on monitorSheet that refer to the dataSheet. The onCellChange event listener registered on the ZK Spreadsheet will be called and check the prices . It compairs new price with user preset selling and buying price then trigger buying or selling via another Web service.

Stock-event.png

ZUML

<window apply="org.zkoss.zssessentials.cellaction.StockComposer" width="100%" vflex="1">
	<spreadsheet id="stock"
	    src="/WEB-INF/cellaction/stock.xls"
	    maxrows="200"
	    maxcolumns="40"
	    vflex="1"
	    width="100%">
	</spreadsheet>
	<vlayout id="message" height="200px" width="100%" style="overflow:auto">
	</vlayout>
</window>

Composer

This is the controller that handle the onCellChange event. The key method is the onCellChange$stocck() event listener. Whenever an onCellChange event is triggered, this method will be called and pass through with a CellEvent event. The event listener then compare if the cell changed is in the price column range and check if the price achieve buy or sell price setting by end user.

package org.zkoss.zssessentials.cellaction;
public class StockComposer extends GenericForwardComposer {
	private StockUpdateService service;
	private Vlayout message;
	private Spreadsheet stock;
	private Sheet monitorSheet;
	private int left;
	private int top;
	private int right;
	private int bottom;
	
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);
		service = new StockUpdateService(stock);
		monitorSheet = stock.getSelectedSheet();
		final Range priceRange = Ranges.range(monitorSheet, "price");
		left = priceRange.getColumn();
		top = priceRange.getRow();
		right = priceRange.getLastColumn();
		bottom = priceRange.getLastRow();
	}
	public void onCellChange$stock(CellSelectionEvent event) {
		final Sheet sheet = event.getSheet();
		if (!monitorSheet.equals(sheet)) {
			return; //not the monitorSheet, return
		}
		final int eleft = event.getLeft();
		final int etop = event.getTop();
		final int eright = event.getRight();
		final int ebottom = event.getBottom();
		for (int row = etop; row <= ebottom; ++row) {
			for (int col = eleft; col <= eright; ++col) {
				if (left <= col && col <= right && top <= row && row <= bottom) { //in range
					final Range priceRng = Ranges.range(monitorSheet, row, col);
					final Range sellRng = priceRng.getOffset(0, 3);
					final Range buyRng = priceRng.getOffset(0, 2);
					final Range codeRng = priceRng.getOffset(0, -1);
					final double newPrice = ((Number)priceRng.getValue()).doubleValue();
					final double sellPrice = ((Number)sellRng.getValue()).doubleValue();
					final double buyPrice = ((Number)buyRng.getValue()).doubleValue();
					final String stockCode = (String) codeRng.getValue();
					if (newPrice <= buyPrice) {
						buy(stockCode, priceRng);
					} else if (newPrice >= sellPrice) {
						sell(stockCode, priceRng);
					}
				}
			}
		}
	}
	private void buy(String stockCode, Range priceRng) {
		//stockService.buy(stockCode, price);
		new Label("Buy "+stockCode+" at price: "+priceRng.getText()).setParent(message);
	}
	private void sell(String stockCode, Range priceRng) {
		new Label("Sell "+stockCode+" at price: "+priceRng.getText()).setParent(message);
	}
}

Result

Stock-result.png

View complete source of ZUML stock.zul

View complete source of composer StockComposer.java

Version History

Last Update : 2010/12/02


Version Date Content
     


All source code listed in this book is at Github.


Last Update : 2010/12/02

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.