package org.juxtapose.fxtradingsystem.priceengine; import static org.juxtapose.fxtradingsystem.priceengine.PriceEngineDataConstants.STATE_EUR; import static org.juxtapose.fxtradingsystem.priceengine.PriceEngineDataConstants.STATE_SEK; import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; import java.util.HashMap; import org.juxtapose.fxtradingsystem.constants.FXDataConstants; import org.juxtapose.fxtradingsystem.constants.FXProducerServiceConstants; import org.juxtapose.fxtradingsystem.marketdata.MarketDataConstants; import org.juxtapose.streamline.producer.STMEntryProducer; import org.juxtapose.streamline.producer.ISTMEntryKey; import org.juxtapose.streamline.stm.DataTransaction; import org.juxtapose.streamline.stm.ISTM; import org.juxtapose.streamline.tools.DataConstants; import org.juxtapose.streamline.util.ISTMEntryRequestSubscriber; import org.juxtapose.streamline.util.ISTMEntry; import org.juxtapose.streamline.util.Status; import org.juxtapose.streamline.util.data.DataTypeBigDecimal; import org.juxtapose.streamline.util.data.DataTypeLong; /** * @author Pontus J�rgne * 6 okt 2011 * Copyright (c) Pontus J�rgne. All rights reserved */ public class SwapPriceProducer extends STMEntryProducer implements ISTMEntryRequestSubscriber { final long reutersTag = 0; final long bloombergTag = 1; ISTMEntryKey reutersDataKey; ISTMEntryKey bloombergDataKey; final String ccy1; final String ccy2; final String period; public SwapPriceProducer(ISTMEntryKey inKey, String inCcy1, String inCcy2, String inPeriod, ISTM inSTM) { super( inKey, inSTM ); ccy1 = inCcy1; ccy2 = inCcy2; period = inPeriod; } public void subscribe() { HashMap<String, String> query = new HashMap<String, String>(); query.put( MarketDataConstants.FIELD_TYPE, MarketDataConstants.STATE_TYPE_INSTRUMENT ); query.put( MarketDataConstants.FIELD_CCY1, ccy1 ); query.put( MarketDataConstants.FIELD_CCY2, ccy2 ); query.put( MarketDataConstants.FIELD_PERIOD, FXDataConstants.STATE_PERIOD_SP ); query.put( MarketDataConstants.FIELD_SOURCE, "REUTERS" ); PriceEngineUtil.getSpotPriceQuery( STATE_EUR, STATE_SEK ); stm.getDataKey( FXProducerServiceConstants.MARKET_DATA, this, reutersTag, query ); HashMap<String, String> queryB = new HashMap<String, String>(); queryB.putAll( query ); queryB.put( MarketDataConstants.FIELD_SOURCE, "BLOOMBERG" ); stm.getDataKey( FXProducerServiceConstants.MARKET_DATA, this, bloombergTag, queryB ); } @Override public void deliverKey(ISTMEntryKey inDataKey, Object inTag) { if( inTag.equals( reutersTag ) ) { reutersDataKey = inDataKey; stm.subscribeToData( reutersDataKey, this ); } else if( inTag.equals( bloombergTag ) ) { bloombergDataKey = inDataKey; stm.subscribeToData( bloombergDataKey, this ); } } @Override public void updateData( ISTMEntryKey inKey, final ISTMEntry inData, boolean inFullUpdate ) { if( reutersDataKey == null || bloombergDataKey == null ) return; if( inData.getStatus() == Status.OK ) { stm.commit( new DataTransaction( entryKey, SwapPriceProducer.this, true ) { @Override public void execute() { ISTMEntry reutData = stm.getData( reutersDataKey.getKey() ); ISTMEntry bloomData = stm.getData( bloombergDataKey.getKey() ); if( reutData == null || bloomData == null ) { dispose(); return; } BigDecimal[] reutBidAsk = PriceEngineUtil.getBidAskFromData( reutData ); BigDecimal[] bloomBidAsk = PriceEngineUtil.getBidAskFromData( bloomData ); if( reutBidAsk == null || bloomBidAsk == null ) { dispose(); return; } if( getStatus() == Status.ON_REQUEST) setStatus( Status.OK ); BigDecimal bid = (reutBidAsk[0].add( bloomBidAsk[0] )).divide( new BigDecimal( 2 ) ); BigDecimal ask = (reutBidAsk[1].add( bloomBidAsk[1] )).divide( new BigDecimal( 2 ) ); DataTypeLong timeStamp = (DataTypeLong)inData.getValue( DataConstants.FIELD_TIMESTAMP ); putValue( MarketDataConstants.FIELD_TIMESTAMP, timeStamp); bid = bid.round( new MathContext( 3, RoundingMode.DOWN) ); ask = ask.round( new MathContext( 3, RoundingMode.UP) ); final DataTypeBigDecimal spread = new DataTypeBigDecimal( ask.subtract( bid ) ); putValue(FXDataConstants.FIELD_BID, new DataTypeBigDecimal( bid ) ); putValue(FXDataConstants.FIELD_ASK, new DataTypeBigDecimal( ask ) ); putValue(FXDataConstants.FIELD_SPREAD, spread ); } }); } } @Override protected void start() { subscribe(); } @Override public void stop() { stm.unsubscribeToData( reutersDataKey, this ); stm.unsubscribeToData( bloombergDataKey, this ); } @Override public void queryNotAvailible(Object inTag) { setStatus( Status.NA ); stm.logError( "could not retrieve datakey from market data" ); return; } }