/*
* Copyright (c) 2012 Jeremy Goetsch
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jgoetsch.eventtrader.source.parser.structured;
import java.text.DecimalFormat;
import java.util.Map;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jgoetsch.eventtrader.Msg;
import com.jgoetsch.eventtrader.TradeSignal;
import com.jgoetsch.eventtrader.source.MsgHandler;
import com.jgoetsch.eventtrader.source.parser.MsgParseException;
import com.jgoetsch.tradeframework.Contract;
/**
* Decodes structured Profiding alert into a Msg object.
*
* @author jgoetsch
*
{
"command": "Trade",
"message": {
"type": "EntryDingMessage",
"msgId": 82351,
"newsletter": 3,
"date": 1395669845622,
"username": "timothysykes",
"image": "https://pbs.twimg.com/profile_images/1166026278/TimCover1_bigger.jpg",
"entry": {
"amount": 2000,
"shares": 20000,
"ticker": "MNGA",
"comments": "Got the predictable drop off the bounce highs, but it's taking forever to make a bigger drop that I want so I'm taking safe quick $2k profits to start the week on a good note, this morning bounce on stocks that have just turned red is a common pattern in my video lessons",
"compareDate": 1395669845000,
"dateAdded": 1395669130000,
"dateClosed": 1395669845000,
"entryDate": 1395669130000,
"exitDate": 1395669845000,
"entryComments": "Shorted the morning bounce, goal is to cover in the low 2s or even high 1s",
"entryPrice": 2.3,
"exitPrice": 2.2,
"openTrade": false,
"entryType": "STOCK",
"callOption": true,
"optionType": "CALL",
"optionStrike": 0,
"type": "Short Stock",
"username": "timothysykes",
"shortSell": true,
"shortUrl": "1Moffe",
"percentage": 4.35,
"futuresMonth": 0,
"futuresYear": 0
}
}
}
*/
@Deprecated
public class ProfidingPusherMsgParser implements StructuredMsgParser {
private Logger log = LoggerFactory.getLogger(getClass());
@SuppressWarnings("rawtypes")
public boolean parseData(String type, Map data, MsgHandler handler) throws MsgParseException {
Object ts = data.get("date");
if (ts != null && Number.class.isAssignableFrom(ts.getClass()))
log.info("{} alert latency was {} ms", type, System.currentTimeMillis() - ((Number)ts).longValue());
Msg msg = null;
if ("Trade".equals(type) || "PartialTrade".equals(type)) {
Map partial = (Map)data.get("partialEntry");
Map entry = (Map)data.get("entry");
Contract contract = new Contract();
contract.setSymbol((String)entry.get("ticker"));
if ("OPTION".equals(entry.get("entryType"))) {
contract.setType(Contract.OPTIONS);
}
else if ("FUTURES".equals(entry.get("entryType")))
contract.setType(Contract.FUTURES);
TradeSignal trade = new TradeSignal();
trade.setSourceName((String)entry.get("username"));
trade.setContract(contract);
trade.setNumShares(((Number)(partial != null ? partial : entry).get("shares")).intValue());
trade.setImageUrl((String)data.get("image"));
trade.setPartial(partial != null);
if (partial != null) {
String action = (String)(partial.get("transactionType"));
if ("Bought".equalsIgnoreCase(action))
trade.setType(TradeSignal.TYPE_BUY);
else if ("Sold".equalsIgnoreCase(action))
trade.setType(TradeSignal.TYPE_SELL);
else if ("Shorted".equalsIgnoreCase(action))
trade.setType(TradeSignal.TYPE_SHORT);
else if ("Covered".equalsIgnoreCase(action))
trade.setType(TradeSignal.TYPE_COVER);
else
throw new MsgParseException("Unknown alert action " + action);
} else {
Boolean isShort = (Boolean)entry.get("shortSell");
if (isShort) {
if (entry.get("dateClosed") == null)
trade.setType(TradeSignal.TYPE_SHORT);
else
trade.setType(TradeSignal.TYPE_COVER);
}
else {
if (entry.get("dateClosed") == null)
trade.setType(TradeSignal.TYPE_BUY);
else
trade.setType(TradeSignal.TYPE_SELL);
}
}
if (trade.isPartial()) {
trade.setDate(new DateTime(partial.get("tradeDate")));
trade.setPrice(((Number)partial.get("price")).doubleValue());
trade.setMessage(trade.getTradeString() + "\n" + ((Boolean)entry.get("shortSell") ? "Short " : "Long ")
+ entry.get("shares") + " total at "
+ DecimalFormat.getCurrencyInstance().format(entry.get("entryPrice")) + " average"
+ "\n" + (String)partial.get("comments"));
}
else if (trade.isExit()) {
trade.setDate(new DateTime(entry.get("dateClosed")));
trade.setPrice(((Number)entry.get("exitPrice")).doubleValue());
trade.setMessage(trade.getTradeString() + "\n" + (String)entry.get("comments"));
}
else {
trade.setDate(new DateTime(entry.get("entryDate")));
trade.setPrice(((Number)entry.get("entryPrice")).doubleValue());
trade.setMessage(trade.getTradeString() + "\n" + (String)entry.get("entryComments"));
}
msg = trade;
}
else if ("Commentary".equals(type)) {
msg = new Msg(new DateTime(data.get("date")), (String)data.get("username"), (String)data.get("msg"));
msg.setImageUrl((String)data.get("image"));
}
if (msg != null) {
msg.setSourceType(type);
return handler.newMsg(msg);
}
else
return true;
}
}