import 'dart:core';
import 'dart:io';
import 'dart:typed_data';
import 'marketdatamodels.dart';
class MarketData
{
String host = '192.168.123.136';
int port = 8093;
bool RouterRunning = false;
bool IsLoggedIn = false;
String UserId;
String ServerKey;
Socket socket = null;
int AppId = 3;
String VersionNo = "8.7";
String ReleaseNo = "1.0";
String BuildNo = "1.0";
String SystemId = "SP_F";
int LangNo = 0;
void Function(TickerResponse) OnTickerResp = null;
void Function(PriceResponse) OnPriceResp = null;
MarketData(String userId, String spKey)
{
UserId = userId;
ServerKey = spKey;
Start();
}
void Start()
{
Reconnect();
}
void Reconnect() async
{
socket = await Socket.connect(host, port);
print('Connected to: ${socket.remoteAddress.address}:${socket.remotePort}');
// listen for responses from the server
socket.listen(
// handle data from the server
(Uint8List data) {
final serverResponse = String.fromCharCodes(data);
//print('RECV: $serverResponse');
ProcessRecv(serverResponse);
},
// handle errors
onError: (error) {
print(error);
socket.destroy();
},
// handle server ending connection
onDone: () {
print('Server Disconnected.');
socket.destroy();
},
);
RouterRunning = true;
Login();
}
void Login() async
{
var LoginTime = DateTime.now().millisecondsSinceEpoch;
var strMsg = '4104,0,$UserId,$ServerKey,$AppId,$VersionNo,$ReleaseNo,$BuildNo,$SystemId,$LoginTime,$LangNo\r\n';
await SendMessage(strMsg);
}
Future<void> SendMessage(String message) async
{
//if (RouterRunning)
{
//print('SEND: $message');
socket.write(message);
await Future.delayed(Duration(milliseconds: 50));
}
}
void ProcessRecv(String str)
{
if (str.startsWith("4104"))
{
if (str.endsWith("0\r\n"))
{
IsLoggedIn = true;
}
}
else if (str.startsWith("4102"))
{
var res = DecodePriceProtocol(str);
if (OnPriceResp != null) OnPriceResp(res);
}
else if (str.startsWith("4111"))
{
var res = DecodeTickerProtocol(str);
if (OnTickerResp != null) OnTickerResp(res);
}
}
PriceResponse DecodePriceProtocol(String prot)
{
try
{
var pr = new PriceResponse();
var ss = prot.split(",");
if (ss.length >= 58)
{
pr.prodCode = ss[2];
pr.productName = ss[3];
pr.productType = int.parse(ss[4]);
pr.contractSize = int.parse(ss[5]);
pr.expiryDate = int.parse(ss[6]);
pr.instrumentCode = ss[7];
pr.currency = ss[8];
pr.strike = double.parse(ss[9]);
pr.callPut = ss[10];
pr.underlying = ss[11];
pr.bidPrice = [0, 0, 0, 0, 0];
pr.bidQty = [0, 0, 0, 0, 0];
pr.bidPrice[0] = double.parse(ss[12]);
pr.bidQty[0] = int.parse(ss[13]);
pr.bidPrice[1] = double.parse(ss[14]);
pr.bidQty[1] = int.parse(ss[15]);
pr.bidPrice[2] = double.parse(ss[16]);
pr.bidQty[2] = int.parse(ss[17]);
pr.bidPrice[3] = double.parse(ss[18]);
pr.bidQty[3] = int.parse(ss[19]);
pr.bidPrice[4] = double.parse(ss[20]);
pr.bidQty[4] = int.parse(ss[21]);
pr.askPrice = [0, 0, 0, 0, 0];
pr.askQty = [0, 0, 0, 0, 0];
pr.askPrice[0] = double.parse(ss[22]);
pr.askQty[0] = int.parse(ss[23]);
pr.askPrice[1] = double.parse(ss[24]);
pr.askQty[1] = int.parse(ss[25]);
pr.askPrice[2] = double.parse(ss[26]);
pr.askQty[2] = int.parse(ss[27]);
pr.askPrice[3] = double.parse(ss[28]);
pr.askQty[3] = int.parse(ss[29]);
pr.askPrice[4] = double.parse(ss[30]);
pr.askQty[4] = int.parse(ss[31]);
pr.lastPrice = [0, 0, 0, 0, 0];
pr.lastQty = [0, 0, 0, 0, 0];
pr.lastPrice[0] = double.parse(ss[32]);
pr.lastQty[0] = int.parse(ss[33]);
pr.lastPrice[1] = double.parse(ss[34]);
pr.lastQty[1] = int.parse(ss[35]);
pr.lastPrice[2] = double.parse(ss[36]);
pr.lastQty[2] = int.parse(ss[37]);
pr.lastPrice[3] = double.parse(ss[38]);
pr.lastQty[3] = int.parse(ss[39]);
pr.lastPrice[4] = double.parse(ss[40]);
pr.lastQty[4] = int.parse(ss[41]);
pr.openInterest = int.parse(ss[42]);
pr.turnoverAmount = double.parse(ss[43]);
pr.turnoverVolume = int.parse(ss[44]);
//pr.reserved1 = double.parse(ss[45]);
//pr.reserved2 = double.parse(ss[46]);
pr.equilibriumPrice = double.parse(ss[47]);
pr.open = double.parse(ss[48]);
pr.high = double.parse(ss[49]);
pr.low = double.parse(ss[50]);
pr.previousClose = double.parse(ss[51]);
pr.previousCloseDate = double.parse(ss[52]);
//pr.notUsed = double.parse(ss[53]);
pr.tradeStateNo = double.parse(ss[54]);
pr.lotSize = int.parse(ss[55]);
pr.tickSize = int.parse(ss[56]);
pr.updateTime = DateTime.now().millisecondsSinceEpoch;
// ignore everything after newline
int posNL = ss[57].indexOf("\r\n");
if (posNL >= 0)
{
var dt = ss[57].substring(0, posNL);
pr.updateTime = int.parse(dt);
}
return pr;
}
}
catch(e) { }
return null;
}
TickerResponse DecodeTickerProtocol(String prot)
{
try
{
var tr = new TickerResponse();
var ss = prot.split(",");
if (ss.length >= 11)
{
tr.tickerTime = int.parse(ss[2]);
tr.prodCode = ss[3];
tr.price = double.parse(ss[4]);
tr.qty = int.parse(ss[5]);
tr.dealSrc = int.parse(ss[6]);
tr.hitSide = ss[8];
tr.buySideBroker = ss[9];
tr.sellSideBroker = "";
// adjust price if decInPrc > 0
var dec = int.parse(ss[7]);
if (dec > 0)
{
var mul = 10 * dec;
var prc = tr.price / mul;
tr.price = prc;
}
// ignore everything after newline
int posNL = ss[10].indexOf("\r\n");
if (posNL >= 0)
{
tr.sellSideBroker = ss[10].substring(0, posNL);
}
return tr;
}
}
catch(e) { }
return null;
}
void SubcribePrice(List<String> prods)
{
prods.forEach((element) => _SubcribePrice(element));
}
void _SubcribePrice(String prod)
{
var strMsg = '4107,0,$prod,0,1,0\r\n';
SendMessage(strMsg);
}
void UnSubscribePrice(List<String> prods)
{
prods.forEach((element) => _UnSubscribePrice(element));
}
void _UnSubscribePrice(String prod)
{
var strMsg = '4108,0,$prod,0,0\r\n';
SendMessage(strMsg);
}
void SubcribeTicker(List<String> prods)
{
prods.forEach((element) => _SubcribeTicker(element));
}
void _SubcribeTicker(String prod)
{
var strMsg = '4107,0,$prod,0,1,2\r\n';
SendMessage(strMsg);
}
void UnSubscribeTicker(List<String> prods)
{
prods.forEach((element) => _UnSubscribeTicker(element));
}
void _UnSubscribeTicker(String prod)
{
var strMsg = '4108,0,$prod,0,2\r\n';
SendMessage(strMsg);
}
}