package org.knowm.xchange.btcchina.service.fix;
import java.math.BigDecimal;
import org.knowm.xchange.btcchina.BTCChinaAdapters;
import org.knowm.xchange.btcchina.service.fix.fix44.AccountInfoRequest;
import org.knowm.xchange.btcchina.service.fix.fix44.AccountInfoResponse;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.account.AccountInfo;
import org.knowm.xchange.dto.marketdata.Ticker;
import org.knowm.xchange.utils.nonce.CurrentNanosecondTimeIncrementalNonceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import quickfix.Application;
import quickfix.DoNotSend;
import quickfix.FieldNotFound;
import quickfix.IncorrectDataFormat;
import quickfix.IncorrectTagValue;
import quickfix.Message;
import quickfix.RejectLogon;
import quickfix.Session;
import quickfix.SessionID;
import quickfix.UnsupportedMessageType;
import quickfix.fix44.MarketDataIncrementalRefresh;
import quickfix.fix44.MarketDataSnapshotFullRefresh;
import quickfix.fix44.MessageCracker;
import quickfix.fix44.NewOrderSingle;
import quickfix.fix44.OrderCancelRequest;
import quickfix.fix44.OrderMassStatusRequest;
import quickfix.fix44.OrderStatusRequest;
import si.mazi.rescu.SynchronizedValueFactory;
/**
* {@link Application} implementation for BTCChina.
*/
public class BTCChinaApplication extends MessageCracker implements Application {
private final Logger log = LoggerFactory.getLogger(BTCChinaApplication.class);
private SynchronizedValueFactory<Long> nonceFactory = new CurrentNanosecondTimeIncrementalNonceFactory();
private volatile Ticker ticker;
@Override
public void fromAdmin(Message message, SessionID sessionId) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon {
log.debug("fromAdmin: {}", message);
}
@Override
public void toAdmin(Message message, SessionID sessionId) {
log.debug("toAdmin: {}", message);
}
@Override
public void fromApp(Message message, SessionID sessionId) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType {
log.debug("fromApp: {}", message);
crack(message, sessionId);
}
@Override
public void toApp(Message message, SessionID sessionId) throws DoNotSend {
log.debug("toApp: {} {}", sessionId, message);
}
@Override
public void onCreate(SessionID sessionId) {
}
@Override
public void onLogon(SessionID sessionId) {
log.debug("onLogon: {}", sessionId);
}
@Override
public void onLogout(SessionID sessionId) {
log.debug("onLogout: {}", sessionId);
}
@Override
public void onMessage(MarketDataSnapshotFullRefresh message, SessionID sessionId) throws FieldNotFound {
log.debug("{}", message);
setTicker(BTCChinaFIXAdapters.adaptTicker(message));
onTicker(ticker, sessionId);
}
@Override
public void onMessage(MarketDataIncrementalRefresh message, SessionID sessionId) throws FieldNotFound {
log.debug("{}", message);
setTicker(BTCChinaFIXAdapters.adaptUpdate(getTicker(), message));
onTicker(ticker, sessionId);
}
public void onMessage(AccountInfoResponse message, SessionID sessionId) throws FieldNotFound {
log.debug("{}", message);
onAccountInfo(message.getAccReqID().getValue(), new AccountInfo(BTCChinaFIXAdapters.adaptWallet(message)), sessionId);
}
/**
* Callback of ticker refreshed.
*
* @param ticker the refreshed ticker.
* @param sessionId the FIX session ID.
*/
protected void onTicker(Ticker ticker, SessionID sessionId) {
}
/**
* Callback of account info got from server.
*
* @param accReqId the account request ID as assigned in the request.
* @param accountInfo the account info.
*/
protected void onAccountInfo(String accReqId, AccountInfo accountInfo, SessionID sessionId) {
}
public Ticker getTicker() {
return ticker;
}
protected void setTicker(Ticker ticker) {
this.ticker = ticker;
}
public void requestSnapshot(CurrencyPair currencyPair, SessionID sessionId) {
requestSnapshot(adaptSymbol(currencyPair), sessionId);
}
public void requestSnapshot(String symbol, SessionID sessionId) {
// MARKET DATA SNAPSHOT FULL REFRESH REQUEST (V)
Message message = BTCChinaMarketDataRequest.marketDataFullSnapRequest(symbol);
sendMessage(message, sessionId);
}
public void requestSnapshotAndUpdates(CurrencyPair currencyPair, SessionID sessionId) {
requestSnapshotAndUpdates(adaptSymbol(currencyPair), sessionId);
}
public void requestSnapshotAndUpdates(String symbol, SessionID sessionId) {
// MARKET DATA INCREMENTAL REFRESH REQUEST (V)
Message message = BTCChinaMarketDataRequest.marketDataIncrementalRequest(symbol);
sendMessage(message, sessionId);
}
public void unsubscribe(CurrencyPair currencyPair, SessionID sessionId) {
unsubscribe(adaptSymbol(currencyPair), sessionId);
}
public void unsubscribe(String symbol, SessionID sessionId) {
// UNSUBSCRIBE MARKET DATA INCREMENTAL REFRESH (V)
Message message = BTCChinaMarketDataRequest.unsubscribeIncrementalRequest(symbol);
sendMessage(message, sessionId);
}
public void requestAccountInfo(String accessKey, String secretKey, String accReqId, SessionID sessionId) {
AccountInfoRequest message = BTCChinaTradeRequest.createAccountInfoRequest(nonceFactory.createValue(), accessKey, secretKey, accReqId);
sendMessage(message, sessionId);
}
public void placeOrder(String accessKey, String secretKey, String clOrdId, char side, char ordType, BigDecimal orderQty, BigDecimal price,
String symbol, SessionID sessionId) {
NewOrderSingle message = BTCChinaTradeRequest.createNewOrderSingle(nonceFactory.createValue(), accessKey, secretKey, clOrdId, side, ordType,
orderQty, price, symbol);
sendMessage(message, sessionId);
}
public void cancelOrder(String accessKey, String secretKey, String clOrdId, String orderId, String symbol, SessionID sessionId) {
OrderCancelRequest message = BTCChinaTradeRequest.createOrderCancelRequest(nonceFactory.createValue(), accessKey, secretKey, clOrdId, orderId,
symbol);
sendMessage(message, sessionId);
}
public void requestOrderMassStatus(String accessKey, String secretKey, String massStatusReqId, int massStatusReqType, String symbol,
SessionID sessionId) {
OrderMassStatusRequest message = BTCChinaTradeRequest.createOrderMassStatusRequest(nonceFactory.createValue(), accessKey, secretKey,
massStatusReqId, massStatusReqType, symbol);
sendMessage(message, sessionId);
}
public void requestOrderStatus(String accessKey, String secretKey, String clOrdId, String orderId, String symbol, SessionID sessionId) {
OrderStatusRequest message = BTCChinaTradeRequest.createOrderStatusRequest(nonceFactory.createValue(), accessKey, secretKey, clOrdId, orderId,
symbol);
sendMessage(message, sessionId);
}
private void sendMessage(Message message, SessionID sessionId) {
Session.lookupSession(sessionId).send(message);
}
private String adaptSymbol(CurrencyPair currencyPair) {
return BTCChinaAdapters.adaptMarket(currencyPair).toUpperCase();
}
@Override
public void crack(Message message, SessionID sessionId) throws UnsupportedMessageType, FieldNotFound, IncorrectTagValue {
if (message instanceof AccountInfoResponse) {
onMessage((AccountInfoResponse) message, sessionId);
} else {
super.crack(message, sessionId);
}
}
}