/* * #%L * PortfolioEffect - Quant Client * %% * Copyright (C) 2011 - 2015 Snowfall Systems, Inc. * %% * This file is part of PortfolioEffect Quant Client. * * PortfolioEffect Quant Client is free software: you can redistribute * it and/or modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * PortfolioEffect Quant Client is distributed in the hope that it will * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with PortfolioEffect Quant Client. If not, see <http://www.gnu.org/licenses/>. * #L% */ package com.portfolioeffect.quant.client.portfolio; import gnu.trove.list.array.TDoubleArrayList; import gnu.trove.list.array.TFloatArrayList; import gnu.trove.list.array.TIntArrayList; import gnu.trove.list.array.TLongArrayList; import java.io.IOException; import java.lang.reflect.Type; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; import javax.management.RuntimeErrorException; import org.apache.commons.lang.StringUtils; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.portfolioeffect.quant.client.ClientConnection; import com.portfolioeffect.quant.client.model.ComputeErrorException; import com.portfolioeffect.quant.client.model.ConnectFailedException; import com.portfolioeffect.quant.client.result.LazyMetric; import com.portfolioeffect.quant.client.result.Metric; import com.portfolioeffect.quant.client.util.Console; import com.portfolioeffect.quant.client.util.DateTimeUtil; import com.portfolioeffect.quant.client.util.LazyMetricBuilder; import com.portfolioeffect.quant.client.util.MessageStrings; import com.portfolioeffect.quant.client.util.MetricUpdateCallback; import com.portfolioeffect.quant.client.util.SimpleMetricUpdateCallback; import com.portfolioeffect.quant.client.util.Util; public class Portfolio { public boolean isBatchOn() { return container.isBatchOn; } public void setAutoBatchEnabled(boolean isEnabled) { container.isBatchOn = isEnabled; } private PortfolioContainer container; public void del() { container = null; } public Portfolio(Portfolio portfolio) throws IOException{ this(new PortfolioContainer(portfolio.container)); } public Portfolio(PortfolioContainer portfolio) { container = portfolio; } public Portfolio(ClientConnection clientConnection) { container = new PortfolioContainer(clientConnection); setDefaultParams(); } public Portfolio(ClientConnection clientConnection, String fromTime, String toTime, String indexName) { container = new PortfolioContainer(clientConnection); setDefaultParams(); setFromTime(fromTime); setToTime(toTime); addIndex(indexName); } public Portfolio(ClientConnection clientConnection, String fromTime, String toTime) { this(clientConnection, fromTime, toTime, "SPY"); } private void setDefaultParams() { clearCache(); container.portfolioData.setFromTime("#"); container.portfolioData.setToTime("#"); } private String getMetricTypeList(String metric) throws Exception { String result = ""; try { Gson gson = new Gson(); Type mapTypeMetrics = new TypeToken<HashMap<String, String>>() { }.getType(); HashMap<String, String> metricArgs = gson.fromJson(metric, mapTypeMetrics); // metricArgs.putAll(container.portfolioData.getSettings()); ArrayList<HashMap<String, String>> paramsArgs = new ArrayList<HashMap<String, String>>(); paramsArgs.add(metricArgs); result = gson.toJson(paramsArgs); } catch (Exception e) { throw new Exception(e.getMessage().split(":")[1]); } return result; } private String getFullMetricType(String metric) throws Exception { // // if(metric.contains("isFullMetricType")) // return metric; String result = ""; try { Gson gson = new Gson(); Type mapTypeMetrics = new TypeToken<HashMap<String, String>>() { }.getType(); HashMap<String, String> metricArgsGson = gson.fromJson(metric, mapTypeMetrics); // metricArgsGson.put("isFullMetricType", "true"); HashMap<String, String> metricArgs = new HashMap<String, String>(container.portfolioData.getSettingsReal()); // metricArgs.putAll(metricArgsGson); for (String e : metricArgs.keySet()) Util.putIfAbsent(metricArgsGson, e, metricArgs.get(e)); // metricArgsGson.putIfAbsent(e, metricArgs.get(e)); result = gson.toJson(metricArgsGson); } catch (Exception e) { throw new Exception(e.getMessage().split(":")[1]); } return result; } private String getMetricTypeList(ArrayList<String> metrics) throws Exception { String result = ""; try { Gson gson = new Gson(); ArrayList<HashMap<String, String>> paramsArgs = new ArrayList<HashMap<String, String>>(); for (String e : metrics) { Type mapTypeMetrics = new TypeToken<HashMap<String, String>>() { }.getType(); HashMap<String, String> metricArgsGson = gson.fromJson(e, mapTypeMetrics); // HashMap<String,String> metricArgs = new HashMap<String, // String>(container.portfolioData.getSettings()); // metricArgs.putAll(metricArgsGson); // paramsArgs.add(metricArgs); paramsArgs.add(metricArgsGson); } result = gson.toJson(paramsArgs); } catch (Exception e) { throw new Exception(e.getMessage().split(":")[1]); } return result; } public boolean isMultiBatch() { return container.isMultiBatch; } public void setMultiBatchEnabled(boolean isMultiBatch) { container.isMultiBatch = isMultiBatch; } public void setParam(String key, String value) { if(container.portfolioData.containsParam(key) && container.portfolioData.getParam(key).equals(value)) return; if (!container.isMultiBatch || container.portfolioData.checkEstimatorParams(key)) clearCache(); if (key.equals("windowLength")) { updateBurnWindowLength( Portfolio.parseWindowLength(value) ); // int w= parseWindowLength(value); // container.windowLength = Math.max(container.windowLength, w); } container.portfolioData.setParam(key, value); if (key.equals("samplingInterval")) { removeUserData("sampligTimes"); } } private void updateBurnWindowLength(int windowLength) { container.windowLength = Math.max(container.windowLength, windowLength); } private void updateBurnWindowLength(String windowLength, String rollingWindow) { int w = parseWindowLength(windowLength); int rw = parseWindowLength(rollingWindow); container.windowLength = Math.max(container.windowLength, w + rw); } public void removeParam(String key) { clearCache(); container.portfolioData.removeParam(key); } public String getParam(String key) { if (container.portfolioData.containsParam(key)) return container.portfolioData.getParam(key); else return ""; } public void setPortfolioSettings(Map<String, String> map) { clearCache(); container.portfolioData.setSettings(new HashMap<String, String>(map)); } public void setPortfolioSettings(String settingsJSON) { clearCache(); container.portfolioData.setSettingJSON(settingsJSON); } public HashMap<String, String> getPortfolioSettingsReal() { return container.portfolioData.getSettingsReal(); } public HashMap<String, String> getPortfolioSettingsR() { return container.portfolioData.getSettings(); } public String getPortfolioSettingsJSON() { return container.portfolioData.getSettingJSON(); } public Metric addIndex(String assetName) { clearCache(); if (container.portfolioData.getIndexPrice() != null) { container.portfolioData.setIndexPrice(null); container.portfolioData.setIndexTimeMillisec(null); } container.portfolioData.getPriceID().put(assetName, container.portfolioData.getNextDataId()); container.portfolioData.setIndexSymbol(assetName); return new Metric(); } public Metric addIndex(TDoubleArrayList indexPrice, long timeStepMilliSec) { return addIndex( indexPrice.toArray(), timeStepMilliSec); } public Metric addIndex(double[] indexPrice, long timeStepMilliSec) { clearCache(); long[] timeMilliSec = new long[indexPrice.length]; for (int i = 0; i < indexPrice.length; i++) timeMilliSec[i] = i * timeStepMilliSec + 1000; return addIndex(indexPrice, timeMilliSec); } public Metric addIndex(TDoubleArrayList indexPrice, TLongArrayList timeStepMilliSec) { return addIndex( indexPrice.toArray(), timeStepMilliSec.toArray()); } public Metric addIndex(double[] price, long[] timeMilliSec) { clearCache(); if (container.portfolioData.getIndexPrice() != null) { container.portfolioData.setIndexPrice(null); container.portfolioData.setIndexTimeMillisec(null); } if (price.length == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_PRICE); } if (timeMilliSec.length == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_TIME); } if (timeMilliSec.length != price.length) return new Metric(MessageStrings.WRONG_VECTOR_LEN_PRICE_AND_TIME); try { container.portfolioData.setIndexPrice(new ArrayCache(price)); container.portfolioData.setIndexTimeMillisec(new ArrayCache(timeMilliSec)); } catch (IOException e) { return processException(e); } container.portfolioData.setIndexSymbol("index"); container.portfolioData.getPriceID().put("index", container.portfolioData.getNextDataId()); return new Metric(); } public Metric addIndex(TFloatArrayList indexPrice, long timeStepMilliSec) { return addIndex( indexPrice.toArray(), timeStepMilliSec); } public Metric addIndex(float[] indexPrice, long timeStepMilliSec) { clearCache(); long[] timeMilliSec = new long[indexPrice.length]; for (int i = 0; i < indexPrice.length; i++) timeMilliSec[i] = i * timeStepMilliSec + 1000; return addIndex(indexPrice, timeMilliSec); } public Metric addIndex(TFloatArrayList indexPrice, TLongArrayList timeStepMilliSec) { return addIndex( indexPrice.toArray(), timeStepMilliSec.toArray()); } public Metric addIndex(float[] price, long[] timeMilliSec) { clearCache(); if (container.portfolioData.getIndexPrice() != null) { container.portfolioData.setIndexPrice(null); container.portfolioData.setIndexTimeMillisec(null); } if (price.length == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_PRICE); } if (timeMilliSec.length == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_TIME); } if (timeMilliSec.length != price.length) return new Metric(MessageStrings.WRONG_VECTOR_LEN_PRICE_AND_TIME); try { container.portfolioData.setIndexPrice(new ArrayCache(price)); container.portfolioData.setIndexTimeMillisec(new ArrayCache(timeMilliSec)); } catch (IOException e) { return processException(e); } container.portfolioData.setIndexSymbol("index"); container.portfolioData.getPriceID().put("index", container.portfolioData.getNextDataId()); return new Metric(); } public ClientConnection getClient() { return container.clientConnection; } public void clearCache() { try { container = new PortfolioContainer(container); } catch (IOException e1) { } container.clearCache(); } public Metric addPosition(String[] assetName, int[] quantity) { clearCache(); for (int i = 0; i < assetName.length; i++) { Metric result = addPosition(assetName[i], quantity[i]); if (result.hasError()) { return result; } } return new Metric(); } public Metric addPosition(String assetName, int quantity) { clearCache(); if (container.portfolioData.getIndexSymbol() == null) return new Metric("Add index first"); int quantityArray[] = new int[1]; quantityArray[0] = quantity; long quantityTime[] = new long[1]; quantityTime[0] = -1; return addPosition(assetName, quantityArray, quantityTime); } public Metric addPosition(String assetName, int[] quantity, long[] timeMillSec) { clearCache(); removePositionQuantity(assetName); removePositionPrice(assetName); container.portfolioData.getPriceID().put(assetName, container.portfolioData.getNextDataId()); if (container.portfolioData.getIndexSymbol() == null) { return new Metric("Add index first"); } Metric result = addQuantity(assetName, quantity, timeMillSec); container.portfolioData.getSymbolNamesList().add(assetName); return result; } public Metric setStreamQuantity(String assetName, int quantity) { return setStreamQuantity(assetName, quantity, System.currentTimeMillis() + DateTimeUtil.CLIENT_TIME_DELTA); } public Metric setStreamQuantity(String assetName, int quantity, String time) { return setStreamQuantity(assetName, quantity, DateTimeUtil.toPOSIXTimeWithDelta(time)[0]); } public Metric setStreamQuantity(String assetName, int quantity, long timeMilles) { try { container.clientConnection.transmitStreamQuantity(assetName, quantity, timeMilles); container.portfolioData.getSymbolQuantityMap().get(assetName).writeAsLong(new int[] { quantity }); container.portfolioData.getSymbolQuantityTimeMap().get(assetName).write(new long[] { timeMilles }); Thread.sleep(10); } catch (Exception e) { return processException(e); } return new Metric(); } private Metric addQuantity(String assetName, int[] quantity, long[] timeMillSec) { clearCache(); container.portfolioData.getQuantityID().put(assetName, container.portfolioData.getNextDataId()); ArrayCache cashQuantity; ArrayCache cashQuantityTime; if (timeMillSec.length != quantity.length) return new Metric(MessageStrings.WRONG_VECTOR_LEN_QUANTITY_AND_TIME); try { cashQuantity = new ArrayCache(quantity); container.portfolioData.getSymbolQuantityMap().put(assetName, cashQuantity); cashQuantityTime = new ArrayCache(timeMillSec); container.portfolioData.getSymbolQuantityTimeMap().put(assetName, cashQuantityTime); } catch (IOException e) { return processException(e); } return new Metric(); } private Metric addQuantity(String assetName, ArrayCache quantity, ArrayCache timeMillSec) { clearCache(); container.portfolioData.getQuantityID().put(assetName, container.portfolioData.getNextDataId()); container.portfolioData.getSymbolQuantityMap().put(assetName, quantity); container.portfolioData.getSymbolQuantityTimeMap().put(assetName, timeMillSec); return new Metric(); } public Metric addPosition(String assetName, double[] price, int[] quantity, long[] timeMillSec) { return addPosition(assetName, price, timeMillSec, quantity, timeMillSec); } public Metric addPosition(String assetName, double[] price, int[] quantity, long timeStepMilliSec) { if (price.length != quantity.length) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_QUANTITY_AND_TIME); } long[] timeMilliSec = new long[price.length]; for (int i = 0; i < price.length; i++) timeMilliSec[i] = i * timeStepMilliSec + 1000; return addPosition(assetName, price, quantity, timeMilliSec); } public Metric addPosition(String assetName, double[] price, int quantity, long timeStepMilliSec) { long[] timeMilliSec = new long[price.length]; for (int i = 0; i < price.length; i++) { timeMilliSec[i] = i * timeStepMilliSec + 1000; } return addPosition(assetName, price, quantity, timeMilliSec); } public Metric addPosition(String assetName, double[] price, int quantity, long[] priceTimeMillSec) { int quantityArray[] = new int[1]; quantityArray[0] = quantity; long quantityTime[] = new long[1]; quantityTime[0] = -1; return addPosition(assetName, price, priceTimeMillSec, quantityArray, quantityTime); } public Metric addPosition(String assetName, float[] price, int quantity, long[] priceTimeMillSec) { int quantityArray[] = new int[1]; quantityArray[0] = quantity; long quantityTime[] = new long[1]; quantityTime[0] = -1; return addPosition(assetName, price, priceTimeMillSec, quantityArray, quantityTime); } public Metric addPosition(String assetName, double[] price, long[] priceTimeMillSec, int[] quantity, long[] quantityTimeMillSec) { clearCache(); container.portfolioData.getPriceID().put(assetName, container.portfolioData.getNextDataId()); if (price.length == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_PRICE); } else if (priceTimeMillSec.length == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_TIME); } else if (quantity.length == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_QUANTITY); } else if (quantityTimeMillSec.length == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_QUANTITY_TIME); } else if (container.portfolioData.getIndexSymbol() == null) { return new Metric(MessageStrings.ADD_INDEX); } if (quantityTimeMillSec.length != quantity.length) return new Metric(MessageStrings.WRONG_VECTOR_LEN_QUANTITY_AND_TIME); if (priceTimeMillSec.length != price.length) return new Metric(MessageStrings.WRONG_VECTOR_LEN_PRICE_AND_TIME); removePositionQuantity(assetName); removePositionPrice(assetName); Metric resultQuantity = addQuantity(assetName, quantity, quantityTimeMillSec); if (resultQuantity.hasError()) { return resultQuantity; } ArrayCache cashPrice; ArrayCache cashPriceTime; try { cashPrice = new ArrayCache(price); container.portfolioData.getSymbolPriceMap().put(assetName, cashPrice); cashPriceTime = new ArrayCache(priceTimeMillSec); container.portfolioData.getSymbolPriceTimeMap().put(assetName, cashPriceTime); } catch (IOException e) { return processException(e); } container.portfolioData.getSymbolNamesList().add(assetName); container.portfolioData.getUserPrice().add(assetName); return new Metric(); } public Metric addPosition(String assetName, float[] price, long[] priceTimeMillSec, int[] quantity, long[] quantityTimeMillSec) { clearCache(); container.portfolioData.getPriceID().put(assetName, container.portfolioData.getNextDataId()); if (price.length == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_PRICE); } else if (priceTimeMillSec.length == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_PRICE_TIME); } else if (quantity.length == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_QUANTITY); } else if (quantityTimeMillSec.length == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_QUANTITY_TIME); } else if (container.portfolioData.getIndexSymbol() == null) { return new Metric(MessageStrings.ADD_INDEX); } if (quantityTimeMillSec.length != quantity.length) return new Metric(MessageStrings.WRONG_VECTOR_LEN_QUANTITY_AND_TIME); if (priceTimeMillSec.length != price.length) return new Metric(MessageStrings.WRONG_VECTOR_LEN_PRICE_AND_TIME); removePositionQuantity(assetName); removePositionPrice(assetName); Metric resultQuantity = addQuantity(assetName, quantity, quantityTimeMillSec); if (resultQuantity.hasError()) { return resultQuantity; } ArrayCache cashPrice; ArrayCache cashPriceTime; try { cashPrice = new ArrayCache(price); container.portfolioData.getSymbolPriceMap().put(assetName, cashPrice); cashPriceTime = new ArrayCache(priceTimeMillSec); container.portfolioData.getSymbolPriceTimeMap().put(assetName, cashPriceTime); } catch (IOException e) { return processException(e); } container.portfolioData.getSymbolNamesList().add(assetName); container.portfolioData.getUserPrice().add(assetName); return new Metric(); } public Metric addUserData(String dataName, TDoubleArrayList value, TLongArrayList timeMillSec) { return addUserData(dataName, value.toArray(), timeMillSec.toArray()); } public Metric addUserData(String dataName, double[] value, long[] timeMillSec) { clearCache(); container.portfolioData.getPriceID().put(dataName, container.portfolioData.getNextDataId()); if (value.length == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_DATA); } else if (timeMillSec.length == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_TIME); } if (value.length != timeMillSec.length) return new Metric(MessageStrings.WRONG_VECTOR_LEN_DATA_AND_TIME); removeUserData(dataName); ArrayCache cashData; ArrayCache cashTime; try { cashData = new ArrayCache(value); container.symbolUserDataMap.put(dataName, cashData); cashTime = new ArrayCache(timeMillSec); container.symbolUserDataTimeMap.put(dataName, cashTime); } catch (IOException e) { return processException(e); } container.userData.add(dataName); return new Metric(); } public Metric addUserData(String dataName, ArrayCache value, ArrayCache timeMillSec) { clearCache(); container.portfolioData.getPriceID().put(dataName, container.portfolioData.getNextDataId()); if (value.getSize() == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_DATA); } else if (timeMillSec.getSize() == 0) { return new Metric(MessageStrings.WRONG_VECTOR_LEN_TIME); } removeUserData(dataName); container.symbolUserDataMap.put(dataName, value); container.symbolUserDataTimeMap.put(dataName, timeMillSec); container.userData.add(dataName); return new Metric(); } /** * Remove position from portfolio * * @param symbol */ public void removePositionPrice(String symbol) { clearCache(); if (container.portfolioData.getSymbolNamesList().contains(symbol)) { if (container.portfolioData.getUserPrice().contains(symbol)) { container.portfolioData.getUserPrice().remove(symbol); container.portfolioData.getSymbolPriceMap().remove(symbol); container.portfolioData.getSymbolPriceTimeMap().remove(symbol); container.portfolioData.getSymbolNamesList().remove(symbol); } container.portfolioData.getSymbolNamesList().remove(symbol); } } public void removeUserData(String symbol) { clearCache(); if (container.userData.contains(symbol)) { container.userData.remove(symbol); container.symbolUserDataMap.remove(symbol); container.symbolUserDataTimeMap.remove(symbol); } } public void removePositionQuantity(String symbol) { clearCache(); if (container.portfolioData.getSymbolNamesList().contains(symbol)) { container.portfolioData.getSymbolQuantityMap().remove(symbol); container.portfolioData.getSymbolQuantityTimeMap().remove(symbol); } } public Metric setPositionQuantity(String name, int quantity) { int quantityArray[] = new int[1]; quantityArray[0] = quantity; long quantityTime[] = new long[1]; quantityTime[0] = -1; return setPositionQuantity(name, quantityArray, quantityTime); } public Metric setPositionQuantity(String name, TIntArrayList quantity, TLongArrayList timeMillesc) { return setPositionQuantity(name, quantity.toArray(), timeMillesc.toArray()); } public Metric setPositionQuantity(String name, int[] quantity, long[] timeMillesc) { clearCache(); if (container.portfolioData.getSymbolNamesList().contains(name)) { removePositionQuantity(name); return addQuantity(name, quantity, timeMillesc); } else { return new Metric(String.format(MessageStrings.POSITION_NOT_FOUND, name)); } } public Metric setPositionQuantity(String name, ArrayCache quantity, ArrayCache timeMillesc) { clearCache(); if (container.portfolioData.getSymbolNamesList().contains(name)) { removePositionQuantity(name); return addQuantity(name, quantity, timeMillesc); } else { return new Metric(String.format(MessageStrings.POSITION_NOT_FOUND, name)); } } public Metric setPositionQuantity(String name, TDoubleArrayList quantityD, TLongArrayList timeMillesc) { return setPositionQuantity( name, quantityD.toArray(), timeMillesc.toArray()); } public Metric setPositionQuantity(String name, double[] quantityD, long[] timeMillesc) { clearCache(); int[] quantity = new int[quantityD.length]; for (int i = 0; i < quantity.length; i++) { quantity[i] = (int) quantityD[i]; } if (container.portfolioData.getSymbolNamesList().contains(name)) { removePositionQuantity(name); return addQuantity(name, quantity, timeMillesc); } else { return new Metric(String.format(MessageStrings.POSITION_NOT_FOUND, name)); } } public Metric setPositionQuantity(String name, TIntArrayList quantity, String[] timeMillesc) { return setPositionQuantity( name, quantity.toArray(), timeMillesc); } public Metric setPositionQuantity(String name, int[] quantity, String[] timeMillesc) { clearCache(); if (container.portfolioData.getUserPrice().contains(name)) { double[] price; long[] time; try { price = container.portfolioData.getSymbolPriceMap().get(name).getDoubleArray(); time = container.portfolioData.getSymbolPriceTimeMap().get(name).getLongArray(); } catch (Exception e) { return new Metric(e.getMessage()); } return addPosition(name, price, time, quantity, DateTimeUtil.toPOSIXTime(timeMillesc)); } else { return addPosition(name, quantity, DateTimeUtil.toPOSIXTime(timeMillesc)); } } public PortfolioData getPortfolioData() { return container.portfolioData; } public Portfolio setMetricKey(String key) { container.batchMetricKey = key; return this; } public void addMetricToBatch(String metricType) { //metricType = selectPortfolioParamsT(metricType); try { metricType = getFullMetricType(metricType); } catch (Exception e) { // Console.writeln(e.getMessage()); } if (container.batchMetricsPortfolio != null || container.batchMetricsPosition != null) { if (metricType.contains("PORTFOLIO")) { container.batchMetricsPortfolio.add(metricType); if (container.batchMetricKey != null) { container.batchMetricPortfolioKeys.add(container.batchMetricKey); container.batchMetricKey = null; } else container.batchMetricPortfolioKeys.add(metricType); } if (metricType.contains("POSITION") || metricType.contains("INDEX")) { container.batchMetricsPosition.add(metricType); if (container.batchMetricKey != null) { container.batchMetricPositionKeys.add(container.batchMetricKey); container.batchMetricKey = null; } else container.batchMetricPositionKeys.add(metricType); } } } public void addMetricToBatch(Map<String, String> metricType) { Gson gson = new Gson(); addMetricToBatch(gson.toJson(metricType)); } public Metric runBatch(List<Map<String, String>> metrics) { startBatch(); for (Map<String, String> e : metrics) { addMetricToBatch(e); } return finishBatch(); } public List<LazyMetric> runBatchLazy(List<Map<String, String>> metrics) { Type mapType = new TypeToken<HashMap<String,String>>() {}.getType(); Gson gson = new Gson(); ArrayList<LazyMetric> result = new ArrayList<LazyMetric>(); for(Map<String,String> e: metrics){ LazyMetricBuilder builder = new LazyMetricBuilder(e); result.add(getLazyMetric(builder)); } for(LazyMetric e: result){ e.compute(); } return result; } public Metric runBatch(List<Map<String, String>> metrics, List<String> metricKeys) { startBatch(); int i = 0; for (Map<String, String> e : metrics) { setMetricKey(metricKeys.get(i)); i++; addMetricToBatch(e); } return finishBatch(); } public Metric runBatchList(List<String> metrics, List<String> metricKeys) { startBatch(); int i = 0; for (String e : metrics) { setMetricKey(metricKeys.get(i)); i++; addMetricToBatch(e); } return finishBatch(); } public Metric runBatchList(List<String> metrics) { startBatch(); for (String e : metrics) { addMetricToBatch(e); } return finishBatch(); } public Metric runBatch(String metricsStr) { Gson gson = new Gson(); Type mapType = new TypeToken<List<Map<String, String>>>() { }.getType(); List<Map<String, String>> list = gson.fromJson(metricsStr, mapType); return runBatch(list); } public Metric runBatch(String metricsStr, String metricsKeys) { Gson gson = new Gson(); Type mapType = new TypeToken<List<Map<String, String>>>() { }.getType(); List<Map<String, String>> list = gson.fromJson(metricsStr, mapType); mapType = new TypeToken<List<String>>() { }.getType(); List<String> keys = gson.fromJson(metricsKeys, mapType); return runBatch(list, keys); } public Metric getMetric(Map<String, String> metricType) { Gson gson = new Gson(); Metric result = getMetric(gson.toJson(metricType), ""); return result; } public Metric getMetric(String metricType) { // metricType = selectPortfolioParams(metricType); try { metricType = getFullMetricType(metricType); } catch (Exception e) { Console.writeln(e.getMessage()); } if (container.isBatchStart) { addMetricToBatch(metricType); return new Metric(); } Metric result = getMetric(metricType, ""); result.setDebug(container.isDebug); return result; } private String selectPortfolioParamsT(String metricType){ Gson gson = new Gson(); Type mapTypeMetrics = new TypeToken<HashMap<String, String>>() {}.getType(); HashMap<String, String> argsGson = gson.fromJson(metricType, mapTypeMetrics); HashMap<String, String> argsGsonNew = new HashMap<String, String>(argsGson); for(String e: argsGson.keySet()) if(container.portfolioData.checkPortfolioParams(e)){ setParam(e, argsGson.get(e)); argsGsonNew.remove(e); } metricType = gson.toJson(argsGsonNew, mapTypeMetrics); return metricType; } public LazyMetric getLazyMetric(LazyMetricBuilder metricBuilder) { HashMap<String, String> portfolioSetting = new HashMap<String, String>( container.portfolioData.getPortfolioSettings() ); HashMap<String, String> estimatorSetting = new HashMap<String, String>( container.portfolioData.getEstimatorSettings() ); String metricTypeB = metricBuilder.getParam("metricType"); metricBuilder.removeParam("metricType"); updateBurnWindowLength( metricBuilder.getActualWindowLenght() ); // for(String e: metricBuilder.getWindowLengthSetMax()) // updateBurnWindowLength(e); // for(String e: metricBuilder.getWindowLengthSetAdd()) // addToBurnWindowLength(e); // addToBurnWindowLength(getMaxWindow(metricBuilder.getWindowLengthSetAdd())); String metricType = selectPortfolioParamsT(metricBuilder.getJsonString()); metricBuilder.setParam("metricType",metricTypeB); try { String metricTypeFull = getFullMetricType(metricType); if (isContainsResult(metricTypeFull)) { container.portfolioData.setPortfolioSettings(portfolioSetting); container.portfolioData.setEstimatorSettings(estimatorSetting); return new LazyMetric(container, metricType, metricTypeFull, metricBuilder); } if (!container.isBatchStart) startBatch(); LazyMetric result = new LazyMetric(container, metricType, metricTypeFull, metricBuilder); addMetricToBatch(metricTypeFull); if (!isBatchOn()) finishBatch(); if(isMultiBatch()){ container.portfolioData.setPortfolioSettings(portfolioSetting); container.portfolioData.setEstimatorSettings(estimatorSetting); } return result; } catch (Exception e) { container.portfolioData.setPortfolioSettings(portfolioSetting); container.portfolioData.setEstimatorSettings(estimatorSetting); return new LazyMetric("Exception error:" + e.getMessage()); } } public String getStrRequest(LazyMetricBuilder metricBuilder) { HashMap<String, String> portfolioSetting = new HashMap<String, String>( container.portfolioData.getPortfolioSettings() ); HashMap<String, String> estimatorSetting = new HashMap<String, String>( container.portfolioData.getEstimatorSettings() ); String metricTypeB = metricBuilder.getParam("metricType"); metricBuilder.removeParam("metricType"); updateBurnWindowLength( metricBuilder.getActualWindowLenght() ); String metricType = selectPortfolioParamsT(metricBuilder.getJsonString()); metricBuilder.setParam("metricType",metricTypeB); String metricTypeFull; try { metricTypeFull = getFullMetricType(metricType); } catch (Exception e) { container.portfolioData.setPortfolioSettings(portfolioSetting); container.portfolioData.setEstimatorSettings(estimatorSetting); return "Exception error:" + e.getMessage(); } return metricTypeFull; } private void processNoCashError(String str) throws Exception { if (str.contains("No data in cache")) throw new Exception(str); } private Metric transmitData(ArrayList<String> dataList) throws Exception { String windowLength = container.windowLength + "s";// getParam("windowLength"); String priceSamplingInterval = getParam("priceSamplingInterval"); String momentsModel = getParam("riskMethodology"); Metric result = container.clientConnection.transmitDataList(container.portfolioData.getFromTime(), container.portfolioData.getToTime(), dataList, windowLength, priceSamplingInterval, momentsModel, getTrainingModel()); if (result.hasError()) { processNoCashError(result.getErrorMessage()); return result; } if (result.getMessage().length() == 0) return new Metric(); Gson gson = new Gson(); Type mapType = new TypeToken<String[]>() { }.getType(); String[] dataTransmit = gson.fromJson(result.getMessage(), mapType);// result.getMessage().split(";"); for (String e : dataTransmit) { String[] ePars = e.split("-"); if (ePars[0].equals("h") || ePars[0].equals("hI")) { result = new Metric(MessageStrings.ERROR_HIST_PRICE); if (result.hasError()) { processNoCashError(result.getErrorMessage()); return result; } } else if (ePars[0].equals("u")) { String position = ePars[1].split(":")[1]; if (position.equals("index")) { result = container.clientConnection.transmitUserPrice(ePars[1], container.portfolioData.getIndexPrice().getDoubleAsFloatArray(), container.portfolioData.getIndexTimeMillisec().getLongArray()); if (result.hasError()) { processNoCashError(result.getErrorMessage()); return result; } } else { ArrayCache cache = container.portfolioData.getSymbolPriceMap().get(position); if (cache == null) cache = container.symbolUserDataMap.get(position); if (cache == null) throw new Exception(String.format(MessageStrings.PRICE_FOR_SYMBOL_NO, position)); float price[] = cache.getDoubleAsFloatArray(); cache = container.portfolioData.getSymbolPriceTimeMap().get(position); if (cache == null) cache = container.symbolUserDataTimeMap.get(position); if (cache == null) throw new Exception(String.format(MessageStrings.TIME_FOR_SYMBOL_NO, position)); long time[] = cache.getLongArray(); if (price == null || time == null) throw new Exception(String.format(MessageStrings.PRICE_FOR_SYMBOL_NO, position)); result = container.clientConnection.transmitUserPrice(ePars[1], price, time); if (result.hasError()) { processNoCashError(result.getErrorMessage()); return result; } } } else if (ePars[0].equals("q")) { String position = ePars[1].split(":")[1]; ArrayCache xq = container.portfolioData.getSymbolQuantityMap().get(position); if (xq == null) throw new Exception(String.format(MessageStrings.QUANTITY_FOR_SYMBOL_NO, position)); int quantity[] = xq.getIntArray(); ArrayCache xt = container.portfolioData.getSymbolQuantityTimeMap().get(position); if (xt == null) throw new Exception(String.format(MessageStrings.TIME_FOR_SYMBOL_NO, position)); long time[] = xt.getLongArray(); result = container.clientConnection.transmitQuantity(ePars[1], quantity, time); if (result.hasError()) { processNoCashError(result.getErrorMessage()); return result; } } else { return new Metric(MessageStrings.ERROR_TRANSMIT); } } return new Metric(); } public boolean isContainsResult(String metricType) throws Exception { String metricTypeFull = getMetricTypeList(metricType);// , CacheKey key = new CacheKey(metricTypeFull, ""); return container.portfolioCache.containsKey(key); } public Metric getMetric(String metricType, String params) { //metricType = selectPortfolioParams(metricType); try { metricType = getFullMetricType(metricType); } catch (Exception e) { // Console.writeln(e.getMessage()); } if (container.portfolioData.getFromTime().length() == 0 || container.portfolioData.getToTime().length() == 0) { container.clientConnection.resetProgressBar(); return new Metric("Set time interval first"); } for (int ii = 0; ii < container.NUMBER_OF_TRIES; ii++) { try { if (container.portfolioData.getSymbolNamesList().size() == 0) { container.clientConnection.resetProgressBar(); return new Metric(MessageStrings.EMPTY_PORTFOLIO); } String metricTypeFull = getMetricTypeList(metricType);// , // params); String[] positions = null; CacheKey key = new CacheKey(metricTypeFull, params); if (container.portfolioCache.containsKey(key)) { Metric result = new Metric(); result.setData("value", container.portfolioCache.getMetric(key)); result.setData("time", container.portfolioCache.getTime(key)); result.setDebug(container.isDebug); result.setNaNFiltered(isNaNFiltered()); result.setNaN2Zero(isNaN2Zero()); return result; } container.clientConnection.printProgressBar(0); { Metric result = container.clientConnection.validateStringRequest(metricTypeFull); if (result.hasError()) throw new Exception(result.getErrorMessage()); positions = result.getStringArray("positions"); } Metric result = null; ArrayList<String> positionList = new ArrayList<String>(); String indexPosition = ""; if (Arrays.asList(positions).contains("@_ALL_PORTFOLIO_")) { String position = ""; if (metricTypeFull.contains("position")) { String[] firstSplit = metricTypeFull.split(":"); if (firstSplit.length == 2) { firstSplit[1] = firstSplit[1].trim(); if (firstSplit[1].length() != 0) { String[] secondSplit = firstSplit[1].split(","); for (int i = 0; i < secondSplit.length; i++) { String[] thirdSplit = secondSplit[i].split("="); if (thirdSplit[0].trim().equals("position")) { position = thirdSplit[1].trim(); } } } } } if (position.length() != 0 && !container.portfolioData.getSymbolNamesList().contains(position)) { container.clientConnection.resetProgressBar(); return new Metric(String.format(MessageStrings.POSITION_NOT_FOUND, position)); } if (position.length() != 0) { positionList.add(position); } for (String symbol : container.portfolioData.getSymbolNamesList()) { if (!symbol.equals(position)) { positionList.add(symbol); } } } else { for (int i = 0; i < positions.length; i++) { if (positions[i].equals("@_INDEX_")) { } else { if (!container.portfolioData.getSymbolNamesList().contains(positions[i])) { container.clientConnection.resetProgressBar(); return new Metric(String.format(MessageStrings.POSITION_NOT_FOUND, positions[i])); } positionList.add(positions[i]); } } } // ------------------------------ ArrayList<String> dataList = new ArrayList<String>(); if (container.portfolioData.getIndexPrice() == null) { dataList.add("hI-" + container.portfolioData.getPortfolioId() + ":" + container.portfolioData.getIndexSymbol() + ":" + container.portfolioData.getPriceID().get(container.portfolioData.getIndexSymbol())); indexPosition = container.portfolioData.getIndexSymbol(); } else { dataList.add("u-" + container.portfolioData.getPortfolioId() + ":" + "index" + ":" + container.portfolioData.getPriceID().get(container.portfolioData.getIndexSymbol())); indexPosition = "index"; } for (String symbol : container.portfolioData.getSymbolNamesList()) { if (container.portfolioData.getUserPrice().contains(symbol)) { dataList.add("u-" + container.portfolioData.getPortfolioId() + ":" + symbol + ":" + container.portfolioData.getPriceID().get(symbol)); } else { dataList.add("h-" + container.portfolioData.getPortfolioId() + ":" + symbol + ":" + container.portfolioData.getPriceID().get(symbol)); } dataList.add("q-" + container.portfolioData.getPortfolioId() + ":" + symbol + ":" + container.portfolioData.getQuantityID().get(symbol)); } // ------------------------------ ArrayList<String> positionNames = new ArrayList<String>(); for (String e : positionList) { if (container.portfolioData.getUserPrice().contains(e)) positionNames.add(container.portfolioData.getPortfolioId() + ":" + e + ":" + container.portfolioData.getPriceID().get(e) + "=" + container.portfolioData.getPortfolioId() + ":" + e + ":" + container.portfolioData.getQuantityID().get(e)); else positionNames.add("h-" + container.portfolioData.getPortfolioId() + ":" + e + ":" + container.portfolioData.getPriceID().get(e) + "=" + container.portfolioData.getPortfolioId() + ":" + e + ":" + container.portfolioData.getQuantityID().get(e)); } if (indexPosition.length() != 0) { if (container.portfolioData.getIndexPrice() != null) indexPosition = container.portfolioData.getPortfolioId() + ":" + indexPosition + ":" + container.portfolioData.getPriceID().get(indexPosition) + "=" + container.portfolioData.getPortfolioId() + ":" + indexPosition + ":" + container.portfolioData.getQuantityID().get(indexPosition); else indexPosition = "hI-" + container.portfolioData.getPortfolioId() + ":" + indexPosition + ":" + container.portfolioData.getPriceID().get(indexPosition) + "=" + container.portfolioData.getPortfolioId() + ":" + indexPosition + ":" + container.portfolioData.getQuantityID().get(indexPosition); } for (String e : container.userData) { dataList.add("u-" + container.portfolioData.getPortfolioId() + ":" + e + ":" + container.portfolioData.getPriceID().get(e)); positionNames.add(container.portfolioData.getPortfolioId() + ":" + e + ":" + container.portfolioData.getPriceID().get(e)); } Metric resultTransmit = transmitData(dataList); if (resultTransmit.hasError()) { throw new Exception(resultTransmit.getErrorMessage()); // return new // MethodResult(resultTransmit.getErrorMessage()); } result = container.clientConnection.estimateTransactional(metricTypeFull, indexPosition, positionNames, params); if (!result.hasError()) { container.portfolioCache.addMetric(key, result.getDataArrayCacheArray("values")[0]); container.portfolioCache.addTime(key, result.getDataArrayCacheArray("times")[0]); container.cachedValueList.add(key); Metric resultT = new Metric(); resultT.setData("value", result.getDataArrayCacheArray("values")[0]); resultT.setData("time", result.getDataArrayCacheArray("times")[0]); resultT.setInfo(result.getInfoParams()); resultT.setDebug(container.isDebug); resultT.setNaNFiltered(isNaNFiltered()); resultT.setNaN2Zero(isNaN2Zero()); result = resultT; } else { container.clientConnection.createCallGroup(1); } return result; } catch (Exception e) { Metric result = processException(e); if (result.getErrorMessage().equals("Server too busy, try again later")) continue; return result; } } container.clientConnection.resetProgressBar(); return new Metric(MessageStrings.FAILED_SERVER_TIME_OUT); } public Metric getAllSymbolsList() { for (int ii = 0; ii < container.NUMBER_OF_TRIES; ii++) { CacheKey keyId = new CacheKey("[{name:\"allSymbolsId\"}]", ""); CacheKey keyDescription = new CacheKey("[{name:\"allSymbolsDescription\"}]", ""); CacheKey keyExchange = new CacheKey("[{name:\"allSymbolsExchange\"}]", ""); if (container.portfolioCache.containsKey(keyId)) { Metric result = new Metric(); result.setData("id", container.portfolioCache.getMetric(keyId)); result.setData("description", container.portfolioCache.getMetric(keyDescription)); result.setData("exchange", container.portfolioCache.getMetric(keyExchange)); return result; } try { Metric result = container.clientConnection.getAllSymbolsList(); container.portfolioCache.addMetric(keyId, result.getDataArrayCache("id")); container.portfolioCache.addMetric(keyDescription, result.getDataArrayCache("description")); container.portfolioCache.addMetric(keyExchange, result.getDataArrayCache("exchange")); return result; } catch (Exception e) { Metric result = processException(e); if (result.getErrorMessage().equals("Server too busy, try again later")) continue; return result; } } return new Metric(MessageStrings.FAILED_SERVER_TIME_OUT); } public void clearBatchMetric() { container.batchMetricsPortfolio.clear(); container.batchMetricsPosition.clear(); container.batchMetricsPortfolio = null; container.batchMetricsPosition = null; } public Metric finishBatch() { if (!container.isBatchStart) return new Metric(); if (container.clientConnection.isStreamEnabled().get()) { return new Metric(container.clientConnection.STREAM_IS_ALREADY_RUNNING); } container.isBatchStart = false; if (container.batchMetricsPortfolio == null && container.batchMetricsPosition == null) return new Metric(); String factorModel = container.portfolioData.getParam("factorModel"); if (factorModel == "sim" || factorModel == null) { container.batchMetricsPortfolio.addAll(container.batchMetricsPosition); container.batchMetricPortfolioKeys.addAll(container.batchMetricPositionKeys); Metric result = computeBatch(container.batchMetricsPortfolio, container.batchMetricPortfolioKeys); clearBatchMetric(); return result; } else { Metric result; if (getParam("stream").equals("on") && factorModel != "sim") return new Metric("Streaming mode is supported only with SIM portfolio"); if (container.batchMetricsPortfolio.size() != 0 && container.batchMetricsPosition.size() != 0) { container.clientConnection.createCallGroup(2); result = computeBatch(container.batchMetricsPortfolio); if (result.hasError()) { clearBatchMetric(); container.clientConnection.createCallGroup(1); return result; } result = computeBatch(container.batchMetricsPosition); clearBatchMetric(); container.clientConnection.createCallGroup(1); return result; } else { container.batchMetricsPortfolio.addAll(container.batchMetricsPosition); result = computeBatch(container.batchMetricsPortfolio); clearBatchMetric(); return result; } } } private Metric processException(Exception e) { if (container.isDebug) { if (e.getMessage() == null || !e.getMessage().equals("Cannot connect to server. Server request failed due to a timeout.")) Console.writeStackTrace(e); } if (e instanceof ConnectFailedException) { Metric isRestarted = container.clientConnection.restart(); if (isRestarted.hasError()) { container.clientConnection.resetProgressBar(); return new Metric(isRestarted.getErrorMessage()); } return new Metric("Server too busy, try again later"); } if (e.getMessage() == null || e.getMessage().contains("No data in cache") || e.getMessage().contains("null")) { Metric isRestarted = container.clientConnection.restart(); if (isRestarted.hasError()) { container.clientConnection.resetProgressBar(); return new Metric(isRestarted.getErrorMessage()); } return new Metric("Server too busy, try again later"); } if (e.getMessage() == null) { Console.writeStackTrace(e); return new Metric(MessageStrings.ERROR_101); } container.clientConnection.resetProgressBar(); return new Metric(e.getMessage()); } private Metric computeBatch(ArrayList<String> batchMetrics) { return computeBatch(batchMetrics, new ArrayList<String>()); } private Metric computeBatch(ArrayList<String> batchMetrics, ArrayList<String> batchMetricKeys) { ArrayList<String> metricsTypeNewList = new ArrayList<String>(); for (String e : batchMetrics) { CacheKey key; try { String metricTypeFull = getMetricTypeList(e); key = new CacheKey(metricTypeFull, ""); } catch (Exception e1) { return processException(e1); } if (container.portfolioCache.containsKey(key) && !getParam("stream").equals("on")) continue; else metricsTypeNewList.add(e); } if (metricsTypeNewList.size() == 0) { return new Metric(); } batchMetrics.clear(); container.clientConnection.printProgressBar(0); if (container.portfolioData.getFromTime().length() == 0 || container.portfolioData.getToTime().length() == 0) { container.clientConnection.resetProgressBar(); return new Metric("Set time interval first"); } for (int ii = 0; ii < container.NUMBER_OF_TRIES; ii++) { try { String metricsType = getMetricTypeList(metricsTypeNewList); if (container.portfolioData.getSymbolNamesList().size() == 0) { container.clientConnection.resetProgressBar(); return new Metric(MessageStrings.EMPTY_PORTFOLIO); } String[] positions = null; { Metric result = container.clientConnection.validateStringRequest(metricsType); if (result.hasError()) { throw new Exception(result.getErrorMessage()); } positions = result.getStringArray("positions"); } Metric result = null; ArrayList<String> positionList = new ArrayList<String>(); String indexPosition = ""; if (Arrays.asList(positions).contains("@_ALL_PORTFOLIO_")) { for (String symbol : container.portfolioData.getSymbolNamesList()) { positionList.add(symbol); } } else { for (int i = 0; i < positions.length; i++) { if (positions[i].equals("@_INDEX_")) { } else { if (!container.portfolioData.getSymbolNamesList().contains(positions[i])) { container.clientConnection.resetProgressBar(); return new Metric(String.format(MessageStrings.POSITION_NOT_FOUND, positions[i])); } positionList.add(positions[i]); } } } ArrayList<String> positionNames = new ArrayList<String>(); for (String e : positionList) { if (container.portfolioData.getUserPrice().contains(e)) { positionNames.add(container.portfolioData.getPortfolioId() + ":" + e + ":" + container.portfolioData.getPriceID().get(e) + "=" + container.portfolioData.getPortfolioId() + ":" + e + ":" + container.portfolioData.getQuantityID().get(e)); } else { positionNames.add("h-" + container.portfolioData.getPortfolioId() + ":" + e + ":" + container.portfolioData.getPriceID().get(e) + "=" + container.portfolioData.getPortfolioId() + ":" + e + ":" + container.portfolioData.getQuantityID().get(e)); } } ArrayList<String> dataList = new ArrayList<String>(); if (container.portfolioData.getIndexPrice() == null) { dataList.add("hI-" + container.portfolioData.getPortfolioId() + ":" + container.portfolioData.getIndexSymbol() + ":" + container.portfolioData.getPriceID().get(container.portfolioData.getIndexSymbol())); indexPosition = container.portfolioData.getIndexSymbol(); } else { dataList.add("u-" + container.portfolioData.getPortfolioId() + ":" + "index" + ":" + container.portfolioData.getPriceID().get(container.portfolioData.getIndexSymbol())); indexPosition = "index"; } for (String symbol : container.portfolioData.getSymbolNamesList()) { if (container.portfolioData.getUserPrice().contains(symbol)) { dataList.add("u-" + container.portfolioData.getPortfolioId() + ":" + symbol + ":" + container.portfolioData.getPriceID().get(symbol)); } else { dataList.add("h-" + container.portfolioData.getPortfolioId() + ":" + symbol + ":" + container.portfolioData.getPriceID().get(symbol)); } dataList.add("q-" + container.portfolioData.getPortfolioId() + ":" + symbol + ":" + container.portfolioData.getQuantityID().get(symbol)); } // ------------------------------ if (indexPosition.length() != 0) { if (container.portfolioData.getIndexPrice() != null) { indexPosition = container.portfolioData.getPortfolioId() + ":" + indexPosition + ":" + container.portfolioData.getPriceID().get(indexPosition) + "=" + container.portfolioData.getPortfolioId() + ":" + indexPosition + ":" + container.portfolioData.getQuantityID().get(indexPosition); } else { indexPosition = "hI-" + container.portfolioData.getPortfolioId() + ":" + indexPosition + ":" + container.portfolioData.getPriceID().get(indexPosition) + "=" + container.portfolioData.getPortfolioId() + ":" + indexPosition + ":" + container.portfolioData.getQuantityID().get(indexPosition); } } for (String e : container.userData) { dataList.add("u-" + container.portfolioData.getPortfolioId() + ":" + e + ":" + container.portfolioData.getPriceID().get(e)); } for (String e : container.userData) { dataList.add("u-" + container.portfolioData.getPortfolioId() + ":" + e + ":" + container.portfolioData.getPriceID().get(e)); positionNames.add(container.portfolioData.getPortfolioId() + ":" + e + ":" + container.portfolioData.getPriceID().get(e)); } Metric resultTransmit = transmitData(dataList); if (resultTransmit.hasError()) { throw new Exception(resultTransmit.getErrorMessage()); // return new // MethodResult(resultTransmit.getErrorMessage()); } container.clientConnection.setBatchMetricKeys(batchMetricKeys, container.portfolioData.getPortfolioId()); result = container.clientConnection.estimateTransactional(metricsType, indexPosition, positionNames, ""); if (!result.hasError()) { for (int k = 0; k < result.getDataArrayCacheArray("values").length; k++) { String metricTypeFull = getMetricTypeList(metricsTypeNewList.get(k)); CacheKey key = new CacheKey(metricTypeFull, ""); container.portfolioCache.addMetric(key, result.getDataArrayCacheArray("values")[k]); container.portfolioCache.addTime(key, result.getDataArrayCacheArray("times")[k]); container.cachedValueList.add(key); } metricsTypeNewList.clear(); } else { container.clientConnection.createCallGroup(1); } return new Metric(); } catch (Exception e) { Metric result = processException(e); if (result.getErrorMessage().equals("Server too busy, try again later")) continue; return result; } } container.clientConnection.resetProgressBar(); return new Metric(MessageStrings.FAILED_SERVER_TIME_OUT); } private Metric processException(IOException e) { if (container.isDebug) { Console.writeStackTrace(e); } if (e.getMessage() != null) { return new Metric(e.getMessage()); } else { return new Metric(MessageStrings.ERROR_FILE); } } public LazyMetric getPDF(double from, double to, int number) throws Exception { return getPDF(from, to, number, ""); } public LazyMetric getPDF(int number) throws Exception { return getPDF(0, 1, number, ""); } public LazyMetric getPDF(int number, String position) throws Exception { return getPDF(0, 1, number, position); } public LazyMetric getPDF(double from, double to, int number, String position) throws Exception { if (getSymbolNamesList().size() == 0) return new LazyMetric(MessageStrings.EMPTY_PORTFOLIO); number = number > container.MAX_PDF_POINTS ? 300 : number; HashMap<String, String> params = new HashMap<String, String>(); String sampling = getSamplingInterval(); Gson gson = new Gson(); Metric result; if (position.length() == 0) { params.put("metric", "PORTFOLIO_PDF"); } else { params.put("metric", "POSITION_PDF"); params.put("position", position); } params.put("from", "" + from); params.put("to", "" + to); params.put("number", "" + number); result = getMetric(gson.toJson(params)); long[] time = null; double[][] PDF = null; double[][] x = null; if (!result.hasError()) { time = result.getLongArray("time"); PDF = new double[time.length][number]; x = new double[time.length][number]; ArrayCache qResult = result.getDataArrayCache("value"); try { qResult.lockToRead(); for (int j = 0; j < time.length; j++) for (int i = 0; i < number; i++) { x[j][i] = qResult.getNextDouble(); PDF[j][i] = qResult.getNextDouble(); } qResult.unlockToRead(); } catch (Exception e) { if (isDebug()) Console.writeStackTrace(e); if (e.getMessage() != null) return new LazyMetric(e.getMessage()); else return new LazyMetric(MessageStrings.ERROR_FILE); } } else { return new LazyMetric(result.getErrorMessage()); } if (sampling.equals("last")) { double[][] newPDF = new double[1][number]; double[][] newX = new double[1][number]; for (int i = 0; i < number; i++) { newPDF[0][i] = PDF[PDF.length - 1][i]; newX[0][i] = x[x.length - 1][i]; } PDF = newPDF; x = newX; long newTime[] = new long[] { time[time.length - 1] }; time = newTime; } getClient().resetProgressBar(); Metric resultP = new Metric(); resultP.setData("time", new ArrayCache(time)); resultP.setData("x", new ArrayCache(x)); resultP.setData("pdf", new ArrayCache(PDF)); return new LazyMetric(resultP); } public Metric getPositionQuantity(String symbol) { if (container.portfolioData.getSymbolQuantityMap().containsKey(symbol)) try { double[] value = container.portfolioData.getSymbolQuantityMap().get(symbol).getIntAsDoubleArray(); long[] time = container.portfolioData.getSymbolQuantityTimeMap().get(symbol).getLongArray(); String samplingInterval = getParam("samplingInterval"); if (samplingInterval.equals("last")) { Metric result = new Metric(); result.setData("value", new ArrayCache(new double[] { value[value.length - 1] })); result.setData("time", new ArrayCache(new long[] { time[time.length - 1] })); return result; } Metric result = new Metric(); result.setData("value", new ArrayCache(value)); result.setData("time", new ArrayCache(time)); return result; } catch (Exception e) { return processException(e); } else { return new Metric(String.format(MessageStrings.POSITION_NOT_FOUND, symbol)); } } /** * Returns an unmodifiable list of symbols that have non-zero position * weights in the portfolio * * @return symbol array */ public String[] getSymbols() { String[] names = new String[container.portfolioData.getSymbolNamesList().size()]; int i = 0; for (String name : container.portfolioData.getSymbolNamesList()) { names[i] = name; i++; } return names; } public int[] getQuantities() throws Exception { String[] positions = getSymbols(); int[] quantities = new int[positions.length]; for (int i = 0; i < positions.length; i++) { quantities[i] = container.portfolioData.getSymbolQuantityMap().get(positions[i]).getIntArray()[0]; } return quantities; } public void createCallGroup(int groupSize) { container.clientConnection.createCallGroup(groupSize); } public List<String> getSymbolNamesList() { return container.portfolioData.getSymbolNamesList(); } public Map<String, ArrayCache> getSymbolQuantityMap() { return container.portfolioData.getSymbolQuantityMap(); } public boolean isPriceJumpsFilterEnabled() { return getParam("isPriceJumpsFilterEnabled").equals("true"); } public boolean isHoldingPeriodEnabled() { return getParam("isHoldingPeriodEnabled").equals("true"); } public void setHoldingPeriodEnabled(boolean isHoldingPeriodEnabled) { setParam("isHoldingPeriodEnabled", String.valueOf(isHoldingPeriodEnabled)); } public void setHoldingPeriodEnabled(String isHoldingPeriodEnabled) { setParam("isHoldingPeriodEnabled", isHoldingPeriodEnabled); } public String getFromTime() { return container.portfolioData.getFromTime(); } public Metric setFromTime(String fromTime) { clearCache(); updatePriceData(); container.portfolioData.setFromTime(""); if (fromTime.contains("t")) { int daysBack; if (fromTime.trim().equals("t")) { container.portfolioData.setFromTime(fromTime); return new Metric(); } else { String[] a = fromTime.trim().split("-"); try { container.portfolioData.setFromTime(fromTime); return new Metric(); } catch (Exception e) { return new Metric(String.format(MessageStrings.WRONG_TIME_FORMAT_FROM, fromTime)); } } } else if (!fromTime.contains(":")) { String s = fromTime.trim() + " 09:30:01"; try { Timestamp t = Timestamp.valueOf(s); container.portfolioData.setFromTime(fromTime); return new Metric(); } catch (Exception e) { return new Metric(String.format(MessageStrings.WRONG_TIME_FORMAT_FROM, fromTime)); } } try { Timestamp t = Timestamp.valueOf(fromTime); } catch (Exception e) { return new Metric(String.format(MessageStrings.WRONG_TIME_FORMAT_FROM, fromTime)); } container.portfolioData.setFromTime(fromTime); return new Metric(); } public String getToTime() { return container.portfolioData.getToTime(); } public void updatePriceData() { clearCache(); for (String e : container.portfolioData.getPriceID().keySet()) { if (!container.portfolioData.getUserPrice().contains(e)) container.portfolioData.getPriceID().put(e, container.portfolioData.getNextDataId()); } } public Metric setToTime(String toTime) { clearCache(); updatePriceData(); container.portfolioData.setToTime(""); if (toTime.contains("t")) { if (toTime.trim().equals("t")) { container.portfolioData.setToTime(toTime); return new Metric(); } else { String[] a = toTime.trim().split("-"); try { int daysBack = Integer.parseInt(a[1].split("d")[0]); container.portfolioData.setToTime(toTime); return new Metric(); } catch (Exception e) { return new Metric(String.format(MessageStrings.WRONG_TIME_FORMAT_TO, toTime)); } } } else if (!toTime.contains(":")) { String s = toTime.trim() + " 09:30:01"; try { Timestamp t = Timestamp.valueOf(s); container.portfolioData.setToTime(toTime); return new Metric(); } catch (Exception e) { return new Metric(String.format(MessageStrings.WRONG_TIME_FORMAT_TO, toTime)); } } try { Timestamp t = Timestamp.valueOf(toTime); } catch (Exception e) { return new Metric(String.format(MessageStrings.WRONG_TIME_FORMAT_TO, toTime)); } container.portfolioData.setToTime(toTime); return new Metric(); } public String getSamplingInterval() { return getParam("samplingInterval"); } /** * set times when the data are calculated * * @param samplingIntervalServer * "all" or - with out sampling ; "Xs" X -seconds; "Xm" X * -minutes; "Xh" X - hours; "Xd" X -days; "Xw" X -weeks; "Xmo" X * - months; "Xy" X - years; "last" - only final result */ public void setSamplingInterval(String samplingIntervalServer) { setParam("samplingInterval", samplingIntervalServer); removeUserData("sampligTimes"); container.samplingTimes = null; } public long[] getSamplingIntervalArray() { return container.samplingTimes; } public void setSamplingInterval(TLongArrayList samplingTimes) { setSamplingInterval( samplingTimes.toArray()); } /** * set times when the data are calculated * * @param samplingTimes * - arrays of data milliseconds */ public void setSamplingInterval(long[] samplingTimes) { clearCache(); container.samplingTimes = samplingTimes; double[] value = new double[samplingTimes.length + 1]; long[] time = new long[samplingTimes.length + 1]; value[0] = 0; time[0] = samplingTimes[0] - 1000; for (int i = 1; i < value.length; i++) { value[i] = i; time[i] = samplingTimes[i - 1]; } setParam("samplingInterval", "all"); addUserData("sampligTimes", value, time); } public void startBatch() { if (container.clientConnection.isStreamEnabled().get()) { return; } if (container.isBatchStart) return; container.isBatchStart = true; container.batchMetricKey = null; container.batchMetricsPosition = new ArrayList<String>(); container.batchMetricsPortfolio = new ArrayList<String>(); container.batchMetricPortfolioKeys = new ArrayList<String>(); container.batchMetricPositionKeys = new ArrayList<String>(); } @Override protected void finalize() throws Throwable { clearCache(); super.finalize(); } public boolean isNoiseModelEnabled() { return getParam("isNoiseModelEnabled").equals("true"); } public void setNoiseModelEnabled(boolean isNoiseFilterEnabled) { setParam("isNoiseModelEnabled", String.valueOf(isNoiseFilterEnabled)); } public void setNoiseModelEnabled(String isNoiseFilterEnabled) { setParam("isNoiseModelEnabled", isNoiseFilterEnabled); } public boolean isNonGaussianModelEnabled() { return getParam("isNonGaussianModelEnabled").equals("true"); } public void setNonGaussianModelEnabled(boolean isNonGaussianModelEnabled) { setParam("isNonGaussianModelEnabled", String.valueOf(isNonGaussianModelEnabled)); } public String getShortSalesMode() { return getParam("shortSalesMode"); } /** * * @param shortSalesMode * = "lintner" or "markowitz" */ public void setShortSalesMode(String shortSalesMode) { setParam("shortSalesMode", shortSalesMode); } public String getPriceSamplingInterval() { return getParam("priceSamplingInterval"); } public void setPriceSamplingInterval(String priceSamplingInterval) { setParam("priceSamplingInterval", priceSamplingInterval); } public String getIndexSymbol() { return container.portfolioData.getIndexSymbol(); } /** * * * @param factorModel * = "sim" for single index model or "direct" for direct model * */ public void setFactorModel(String factorModel) { setParam("factorModel", factorModel); } public String getFactorModel() { return getParam("factorModel"); } public boolean isJumpsModelEnabled() { return getParam("isJumpsModelEnabled").equals("true"); } /** * set model type for filtering jumps * * @param jumpsModel * = "moments" - filtering jumps happens only in the calculation * of moments and related metrics, "none" jumps is not filtering, * "all" filtering jumps happens for all metrics including price * as metrics */ public void setJumpsModel(String jumpsModel) { setParam("jumpsModel", jumpsModel); } public String getJumpsModel() { return getParam("jumpsModel"); } /** * * @param windowLengthString * "Xs" X -seconds; "Xm" X -minutes; "Xh" X - hours; "Xd" X * -days; "Xw" X -weeks; "Xmo" X - months; "Xy" X - years; * * "all" - cumulative value without window * */ public void setWindowLength(String windowLengthString) { setParam("windowLength", windowLengthString); } public String getWindowLength() { return getParam("windowLength"); } /** * time scale * * "Xs" X -seconds; "Xm" X -minutes; "Xh" X - hours; "Xd" X -days; "Xw" X * -weeks; "Xmo" X - months; "Xy" X - years; * * * @param timeScaleSecString */ public void setTimeScale(String timeScaleSecString) { setParam("timeScale", timeScaleSecString); } public String getTimeScale() { return getParam("timeScale"); } public boolean isDebug() { return container.isDebug; } public void setDebug(boolean isDebug) { container.isDebug = isDebug; container.clientConnection.setDebugModeEnabled(isDebug); } public long getNewDataId() { return container.portfolioData.getNextDataId(); } public ClientConnection getClientConnection() { return container.clientConnection; } public void setClientConnection(ClientConnection clientConnection) { this.container.clientConnection = clientConnection; } /** * transaction cost per share * * @param value */ public void setTxnCostPerShare(double value) { setParam("txnCostPerShare", String.valueOf(value)); } public double getTxnCostPerShare() { return Double.valueOf(getParam("txnCostPerShare")); } /** * transaction cost fixed * * @param value */ public void setTxnCostFixed(double value) { setParam("txnCostFixed", String.valueOf(value)); } public double getTxnCostFixed() { return Double.valueOf(getParam("txnCostFixed")); } public boolean isDriftEnabled() { return Boolean.valueOf(getParam("isDriftEnabled")); } public void setDriftEnabled(boolean isDriftEnabled) { setParam("isDriftEnabled", String.valueOf(isDriftEnabled)); } public void setDriftEnabled(String isDriftEnabled) { setParam("isDriftEnabled", isDriftEnabled); } /** * * @param model * = "PortfolioEffect" or "RiskMetrics" */ public void setRiskMethodology(String model) { setParam("riskMethodology", model); if (getParam("priceSamplingInterval").equals("") && model.equals("RiskMetrics")) setParam("priceSamplingInterval", "1d"); } public String getRiskMethodology() { return getParam("riskMethodology"); } public void setLambdaRiskMetrics(double lambda) { setParam("lambdaRiskMetrics", String.valueOf(lambda)); } public double getLambdaRiskMetrics() { return Double.valueOf(getParam("lambdaRiskMetrics")); } /** * * * @param densityApproxModel * = "GLD" -generalized lambda distribution, "CORNISH_FISHER" - * Cornish Fisher expansion "NORMAL" - normal distribution */ public void setDensityApproxModel(String densityApproxModel) { setParam("densityApproxModel", densityApproxModel); } public String getDensityApproxModelString() { return getParam("densityApproxModel"); } public void setPortfolioMetricsMode(String mode) { setParam("portfolioMetricsMode", mode); } public String getPortfolioMetricsMode() { return getParam("portfolioMetricsMode"); } public void setStartWhenBurn(boolean mode) { setParam("isStartWhenBurn", "" + mode); } public boolean isStartWhenBurn() { return Boolean.valueOf(getParam("isStartWhenBurn")); } public void setFractalPriceModelEnabled(boolean flag) { setParam("isFractalPriceModelEnabled", "" + flag); } public void setFractalPriceModelEnabled(String flag) { setParam("isFractalPriceModelEnabled", "" + flag); } public void setSynchonizationModelEnabled(String flag) { setParam("synchronizationModel", "" + flag); } public void setSynchonizationModelEnabled(boolean flag) { setParam("synchronizationModel", "" + flag); } public boolean getSynchronizationModelEnabled() { return Boolean.parseBoolean(getParam("synchronizationModel")); } public void setSpotWindowLength(String value) { setParam("spotWindowLength", value); } public void setTrainingModel(boolean flag) { setParam("trainingModel", "" + flag); } public void setTrainingModel(String flag) { setParam("trainingModel", "" + flag); } public String getTrainingModel() { return getParam("trainingModel"); } public boolean isTrainingModel() { return Boolean.parseBoolean(getParam("trainingModel")); } public String getSpotWindowLength(String value) { return getParam("spotWindowLength"); } public boolean isFractalPriceModelEnabled() { return Boolean.valueOf(getParam("isFractalPriceModelEnabled")); } public Metric findSymbols(String searchStr, int numResults) throws Exception { ArrayList<String> id = new ArrayList<String>(); ArrayList<String> description = new ArrayList<String>(); ArrayList<String> exchange = new ArrayList<String>(); Metric allSymbols = getAllSymbolsList(); String[] idStrings = allSymbols.getStringArray("id"); String[] descriptionString = allSymbols.getStringArray("description"); String[] exchangeString = allSymbols.getStringArray("exchange"); for (int i = 0; i < idStrings.length; i++) { if (StringUtils.containsIgnoreCase(idStrings[i], searchStr) || StringUtils.containsIgnoreCase(descriptionString[i], searchStr)) { id.add(idStrings[i]); description.add(descriptionString[i]); exchange.add(exchangeString[i]); } if (id.size() >= numResults) { break; } } Metric result = new Metric(); ArrayCache idCache = new ArrayCache(id.toArray(new String[0])); result.setData("id", idCache); ArrayCache descriptionCache = new ArrayCache(description.toArray(new String[0])); result.setData("description", descriptionCache); ArrayCache exchangeCache = new ArrayCache(exchange.toArray(new String[0])); result.setData("exchange", exchangeCache); return result; } public void initStreamSingleMetric() { container.clientConnection.stop(); ClientConnection tClient = new ClientConnection(); tClient.setUsername(container.clientConnection.getUsername()); tClient.setPassword(container.clientConnection.getPassword()); tClient.setApiKey(container.clientConnection.getApiKey()); tClient.setHost(container.clientConnection.getHost()); tClient.setPort(container.clientConnection.getPort()); container.clientConnection = tClient; setParam("stream", "on"); } public void initStreamSingleMetric(SimpleMetricUpdateCallback callback) { initStreamSingleMetric(); setStreamRefreshCallbackPureData(callback); } public void initStream() { initStreamSingleMetric(); startBatch(); } public void initStream(MetricUpdateCallback callback) { initStream(); setStreamRefreshCallback(callback); } public Metric startStream() { return finishBatch(); } public void stopStream() { container.clientConnection.stopStream(); removeParam("stream"); // clearCache(); } public void setStreamRefreshCallback(MetricUpdateCallback streamRefreshCallback) { container.clientConnection.setStreamRefreshCallback(streamRefreshCallback); } public void setStreamRefreshCallbackPureData(SimpleMetricUpdateCallback streamRefreshCallbackPureData) { container.clientConnection.setStreamRefreshCallbackPureData(streamRefreshCallbackPureData); } public long getId() { return container.portfolioData.getPortfolioId(); } public boolean isNaNFiltered() { return container.portfolioData.isNaNFiltered(); } public void setNaNFiltered(boolean isNaNFiltered) { container.portfolioData.setNaNFiltered(isNaNFiltered); } public boolean isNaN2Zero() { return container.portfolioData.isNaN2Zero(); } public void setNaN2Zero(boolean isNaN2Zero) { container.portfolioData.setNaN2Zero(isNaN2Zero); } public static int parseWindowLength(String s) { String res[] = s.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)"); boolean error = false; if (s.equals("all")) return -1; if (s.equals("last")) return 0; if (s.equals("none")) return -1; int number = 1; int scale = 0; if (res.length != 2) { error = true; } else { try { number = Integer.parseInt(res[0]); } catch (Exception e) { error = true; } if (res[1].equals("s")) scale = 1; if (res[1].equals("m")) scale = 60; if (res[1].equals("h")) scale = 60 * 60; if (res[1].equals("d")) scale = 23400; if (res[1].equals("w")) scale = 23400 * 5; if (res[1].equals("mo")) scale = 23400 * 21; if (res[1].equals("y")) scale = 23400 * 256; if (scale == 0) error = true; } if (error) return -1; return number * scale; } public Position[] getPositions(){ Position[] positions = new Position[getSymbolNamesList().size()]; int i=0; for(String e: getSymbolNamesList()){ positions[i] = new Position(this, e); i++; } return positions; } public Position getPosition(String symbol){ if(getSymbolNamesList().contains(symbol)) return new Position(this, symbol); return null; } }