/*
* Copyright (c) 2004-2011 Marco Maccaferri and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marco Maccaferri - initial API and implementation
*/
package org.eclipsetrader.directa.internal.core.connector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import junit.framework.TestCase;
import org.eclipsetrader.core.feed.Bar;
import org.eclipsetrader.core.feed.BarOpen;
import org.eclipsetrader.core.feed.FeedIdentifier;
import org.eclipsetrader.core.feed.IFeedSubscription;
import org.eclipsetrader.core.feed.ISubscriptionListener;
import org.eclipsetrader.core.feed.Price;
import org.eclipsetrader.core.feed.QuoteDelta;
import org.eclipsetrader.core.feed.QuoteEvent;
import org.eclipsetrader.core.feed.TimeSpan;
import org.eclipsetrader.core.feed.Trade;
import org.eclipsetrader.directa.internal.core.messages.AstaApertura;
import org.eclipsetrader.directa.internal.core.messages.AstaChiusura;
import org.eclipsetrader.directa.internal.core.messages.HeaderRecord;
import org.eclipsetrader.directa.internal.core.messages.Util;
import org.eclipsetrader.directa.internal.core.repository.IdentifierType;
import org.eclipsetrader.directa.internal.core.repository.IdentifiersList;
import org.eclipsetrader.directa.internal.core.repository.PriceDataType;
public class StreamingConnectorTest extends TestCase {
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
@Override
protected void setUp() throws Exception {
new IdentifiersList();
}
private void putFloat(float value, byte[] arr, int i) {
int k = Float.floatToIntBits(value);
int j = 0;
for (int l = 0; l < 4; l++) {
arr[i + l] = (byte) ((k >> j) & 0xFF);
j += 8;
}
}
public void testSubscribeSameSymbolResultInSameInstance() throws Exception {
StreamingConnector connector = new StreamingConnector();
IFeedSubscription subscription = connector.subscribe(new FeedIdentifier("PG", null));
IFeedSubscription subscription2 = connector.subscribe(new FeedIdentifier("PG", null));
assertSame(subscription, subscription2);
}
public void testSubscribeLevel2And1ResultInSameInstance() throws Exception {
StreamingConnector connector = new StreamingConnector();
FeedSubscription subscription2 = (FeedSubscription) connector.subscribeLevel2("PG");
assertNull(subscription2.getIdentifier());
FeedSubscription subscription = (FeedSubscription) connector.subscribe(new FeedIdentifier("PG", null));
assertNotNull(subscription.getIdentifier());
assertNotNull(subscription2.getIdentifier());
assertSame(subscription2, subscription);
}
public void testFireLevel2And1Notifications() throws Exception {
StreamingConnector connector = new StreamingConnector();
final Set<String> notifications = new HashSet<String>();
FeedSubscription subscription = (FeedSubscription) connector.subscribeLevel2("PG");
subscription.addSubscriptionListener(new ISubscriptionListener() {
@Override
public void quoteUpdate(QuoteEvent event) {
notifications.add("subscription");
}
});
IFeedSubscription subscription2 = connector.subscribe(new FeedIdentifier("PG", null));
subscription2.addSubscriptionListener(new ISubscriptionListener() {
@Override
public void quoteUpdate(QuoteEvent event) {
notifications.add("subscription2");
}
});
subscription.addDelta(new QuoteDelta(subscription.getIdentifier(), new Integer(1), new Integer(2)));
subscription.fireNotification();
assertEquals(2, notifications.size());
}
public void testProcessSnapshotData() throws Exception {
Hashtable<String, Map<String, String>> hashTable = new Hashtable<String, Map<String, String>>();
Map<String, String> map = new HashMap<String, String>();
map.put("[L=]", "4.1400");
map.put("[LC=]", "4.1400");
map.put("[TLT]", "08:32:12");
map.put("[DATA_ULT]", "20111104");
map.put("[CV]", "555236");
map.put("[LO]", "4.1100");
map.put("[HI]", "4.1840");
map.put("[OP1]", "4.4360");
map.put("[LIE]", "4.3800");
map.put("[BS1]", "0");
map.put("[BP1]", "0.0000");
map.put("[AS1]", "0");
map.put("[AP1]", "0.0000");
hashTable.put("F", map);
StreamingConnector connector = new StreamingConnector();
FeedSubscription subscription = (FeedSubscription) connector.subscribe(new FeedIdentifier("F", null));
connector.processSnapshotData(new String[] {
"F"
}, hashTable);
IdentifierType identifierType = subscription.getIdentifierType();
PriceDataType priceData = identifierType.getPriceData();
assertNull(subscription.getPrice());
assertEquals(new Trade(priceData.getTime(), 4.1400, null, 555236L), subscription.getTrade());
}
public void testProcessPreOpenPriceData() throws Exception {
Hashtable<String, Map<String, String>> hashTable = new Hashtable<String, Map<String, String>>();
Map<String, String> map = new HashMap<String, String>();
map.put("[L=]", "4.4020");
map.put("[LC=]", "0.0000");
map.put("[TLT]", "08:32:12");
map.put("[DATA_ULT]", "0");
map.put("[CV]", "0");
map.put("[LO]", "0.0000");
map.put("[HI]", "0.0000");
map.put("[OP1]", "0.0000");
map.put("[LIE]", "0.0000");
map.put("[BS1]", "0");
map.put("[BP1]", "0.0000");
map.put("[AS1]", "0");
map.put("[AP1]", "0.0000");
hashTable.put("F", map);
StreamingConnector connector = new StreamingConnector();
FeedSubscription subscription = (FeedSubscription) connector.subscribe(new FeedIdentifier("F", null));
connector.processSnapshotData(new String[] {
"F"
}, hashTable);
IdentifierType identifierType = subscription.getIdentifierType();
PriceDataType priceData = identifierType.getPriceData();
assertEquals(new Price(priceData.getTime(), 4.4020), subscription.getPrice());
assertEquals(new Trade(null, null, null, null), subscription.getTrade());
}
public void testEventsGeneratedWithAstaApertura() throws Exception {
byte[] arr = new byte[20];
putFloat(4.1200f, arr, 0);
AstaApertura msg = new AstaApertura(arr, 0, 0);
msg.head = new HeaderRecord();
msg.head.key = "F";
final List<QuoteDelta> events = new ArrayList<QuoteDelta>();
StreamingConnector connector = new StreamingConnector();
FeedSubscription subscription = (FeedSubscription) connector.subscribe(new FeedIdentifier("F", null));
subscription.addSubscriptionListener(new ISubscriptionListener() {
@Override
public void quoteUpdate(QuoteEvent event) {
events.addAll(Arrays.asList(event.getDelta()));
}
});
connector.processMessage(msg);
subscription.fireNotification();
assertEquals(1, events.size());
assertEquals(new Price(new Date(msg.ora_aper), (double) Util.getFloat(arr, 0)), events.get(0).getNewValue());
}
public void testEventsGeneratedWithAstaChiusura() throws Exception {
byte[] arr = new byte[8];
putFloat(4.1500f, arr, 0);
AstaChiusura msg = new AstaChiusura(arr, 0, 0);
msg.head = new HeaderRecord();
msg.head.key = "F";
final List<QuoteDelta> events = new ArrayList<QuoteDelta>();
StreamingConnector connector = new StreamingConnector();
FeedSubscription subscription = (FeedSubscription) connector.subscribe(new FeedIdentifier("F", null));
subscription.addSubscriptionListener(new ISubscriptionListener() {
@Override
public void quoteUpdate(QuoteEvent event) {
events.addAll(Arrays.asList(event.getDelta()));
}
});
connector.processMessage(msg);
subscription.fireNotification();
assertEquals(1, events.size());
assertEquals(new Price(new Date(msg.ora_chiu), (double) Util.getFloat(arr, 0)), events.get(0).getNewValue());
}
public void testGenerateBarOpenEventAtMarketOpen() throws Exception {
byte[] arr = new byte[32];
putFloat(4.1200f, arr, 0);
putFloat(0.0f, arr, 12);
putFloat(0.0f, arr, 20);
putFloat(0.0f, arr, 24);
org.eclipsetrader.directa.internal.core.messages.Price msg = new org.eclipsetrader.directa.internal.core.messages.Price(arr, 0, 0);
msg.head = new HeaderRecord();
msg.head.key = "F";
final List<QuoteDelta> events = new ArrayList<QuoteDelta>();
StreamingConnector connector = new StreamingConnector();
FeedSubscription subscription = (FeedSubscription) connector.subscribe(new FeedIdentifier("F", null));
subscription.addSubscriptionListener(new ISubscriptionListener() {
@Override
public void quoteUpdate(QuoteEvent event) {
events.addAll(Arrays.asList(event.getDelta()));
}
});
connector.processMessage(msg);
subscription.fireNotification();
assertEquals(2, events.size());
assertEquals(new BarOpen(new Date(msg.ora_ult), TimeSpan.days(1), (double) Util.getFloat(arr, 0)), events.get(1).getNewValue());
}
public void testDontGenerateBarOpenEventIfAlreadyOpen() throws Exception {
byte[] arr = new byte[32];
putFloat(4.1200f, arr, 0);
putFloat(0.0f, arr, 12);
putFloat(0.0f, arr, 20);
putFloat(0.0f, arr, 24);
org.eclipsetrader.directa.internal.core.messages.Price msg = new org.eclipsetrader.directa.internal.core.messages.Price(arr, 0, 0);
msg.head = new HeaderRecord();
msg.head.key = "F";
final List<QuoteDelta> events = new ArrayList<QuoteDelta>();
StreamingConnector connector = new StreamingConnector();
FeedSubscription subscription = (FeedSubscription) connector.subscribe(new FeedIdentifier("F", null));
subscription.addSubscriptionListener(new ISubscriptionListener() {
@Override
public void quoteUpdate(QuoteEvent event) {
events.addAll(Arrays.asList(event.getDelta()));
}
});
PriceDataType priceData = subscription.getIdentifierType().getPriceData();
priceData.setOpen(4.11);
connector.processMessage(msg);
subscription.fireNotification();
assertEquals(1, events.size());
assertEquals(new Trade(new Date(msg.ora_ult), (double) Util.getFloat(arr, 0), 0L, 0L), events.get(0).getNewValue());
}
public void testGenerateBarCloseEventAtMarketClose() throws Exception {
byte[] arr1 = new byte[32];
putFloat(4.1200f, arr1, 0);
putFloat(0.0f, arr1, 12);
putFloat(4.08f, arr1, 20);
putFloat(4.20f, arr1, 24);
org.eclipsetrader.directa.internal.core.messages.Price msg1 = new org.eclipsetrader.directa.internal.core.messages.Price(arr1, 0, 0);
msg1.head = new HeaderRecord();
msg1.head.key = "F";
byte[] arr2 = new byte[8];
putFloat(4.1500f, arr2, 0);
AstaChiusura msg2 = new AstaChiusura(arr2, 0, 0);
msg2.head = new HeaderRecord();
msg2.head.key = "F";
final List<QuoteDelta> events = new ArrayList<QuoteDelta>();
StreamingConnector connector = new StreamingConnector();
FeedSubscription subscription = (FeedSubscription) connector.subscribe(new FeedIdentifier("F", null));
subscription.addSubscriptionListener(new ISubscriptionListener() {
@Override
public void quoteUpdate(QuoteEvent event) {
events.addAll(Arrays.asList(event.getDelta()));
}
});
PriceDataType priceData = subscription.getIdentifierType().getPriceData();
priceData.setTime(new Date());
priceData.setLast(4.15);
priceData.setOpen(4.12);
priceData.setHigh(4.20);
priceData.setLow(4.08);
priceData.setVolume(100000L);
connector.processMessage(msg2);
subscription.fireNotification();
assertEquals(2, events.size());
Calendar c = Calendar.getInstance();
c.setTime(priceData.getTime());
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
assertEquals(new Bar(c.getTime(), TimeSpan.days(1), 4.12, 4.20, 4.08, 4.15, 100000L), events.get(0).getNewValue());
}
}