AccountInfoService { @SuppressWarnings("unchecked") public double calculateMarginForTrade(Account<K> accountInfo, TradeableInstrument<N> instrument, int units) { String tokens[] = TradingUtils.splitInstrumentPair(instrument.getInstrument()); String baseCurrency = tokens[0]; double price = 1.0; if (!baseCurrency.equals(accountInfo.getCurrency())) { String currencyPair = this.providerHelper.fromIsoFormat(baseCurrency + accountInfo.getCurrency()); Map<TradeableInstrument<N>, Price<N>> priceInfoMap = this.currentPriceInfoProvider .getCurrentPricesForInstruments(Lists.newArrayList(new TradeableInstrument<N>(currencyPair))); if (priceInfoMap.isEmpty()) { currencyPair = this.providerHelper.fromIsoFormat(accountInfo.getCurrency() + baseCurrency); priceInfoMap = this.currentPriceInfoProvider.getCurrentPricesForInstruments(Lists .newArrayList(new TradeableInstrument<N>(currencyPair))); if (priceInfoMap.isEmpty()) { return Double.MAX_VALUE; } Price<N> priceInfo = priceInfoMap.values().iterator().next(); price = 1.0 / ((priceInfo.getBidPrice() + priceInfo.getAskPrice()) / 2.0); } else { Price<N> priceInfo = priceInfoMap.values().iterator().next(); price = (priceInfo.getBidPrice() + priceInfo.getAskPrice()) / 2.0; } } return price * units * accountInfo.getMarginRate(); } AccountInfoService(AccountDataProvider<K> accountDataProvider,
			CurrentPriceInfoProvider<N> currentPriceInfoProvider, BaseTradingConfig baseTradingConfig,
			ProviderHelper providerHelper); Collection<Account<K>> getAllAccounts(); Account<K> getAccountInfo(K accountId); Collection<K> findAccountsToTrade(); @SuppressWarnings("unchecked") double calculateMarginForTrade(Account<K> accountInfo, TradeableInstrument<N> instrument, int units); double calculateMarginForTrade(K accountId, TradeableInstrument<N> instrument, int units);  }
@Test public void marginRateWhenAccountCurrencyNominated() { AccountDataProvider<Long> accountDataProvider = mock(AccountDataProvider.class); CurrentPriceInfoProvider<String> currentPriceInfoProvider = mock(CurrentPriceInfoProvider.class); ProviderHelper providerHelper = mock(ProviderHelper.class); AccountInfoService<Long, String> accInfoService = new AccountInfoService<Long, String>(accountDataProvider, currentPriceInfoProvider, null, providerHelper); TradeableInstrument<String> gbpusd = new TradeableInstrument<String>("GBP_USD"); TradeableInstrument<String> gbpchf = new TradeableInstrument<String>("GBP_CHF"); Account<Long> account = mock(Account.class); when(accountDataProvider.getLatestAccountInfo(TradingTestConstants.accountId)).thenReturn(account); when(account.getCurrency()).thenReturn("CHF"); when(account.getMarginRate()).thenReturn(marginRate); when(providerHelper.fromIsoFormat(eq("GBPCHF"))).thenReturn(gbpchf.getInstrument()); Map<TradeableInstrument<String>, Price<String>> priceInfoMap = Maps.newHashMap(); priceInfoMap.put(gbpchf, new Price<String>(gbpchf, 1.4811, 1.4813, DateTime.now())); when(currentPriceInfoProvider.getCurrentPricesForInstruments(eq(Lists.newArrayList(gbpchf)))).thenReturn( priceInfoMap); double marginRate = accInfoService.calculateMarginForTrade(TradingTestConstants.accountId, gbpusd, units); assertEquals(888.72, marginRate, TradingTestConstants.precision); }
@Test public void marginRateWhenAccountCurrencyBase() { AccountDataProvider<Long> accountDataProvider = mock(AccountDataProvider.class); CurrentPriceInfoProvider<String> currentPriceInfoProvider = mock(CurrentPriceInfoProvider.class); ProviderHelper providerHelper = mock(ProviderHelper.class); AccountInfoService<Long, String> accInfoService = new AccountInfoService<Long, String>(accountDataProvider, currentPriceInfoProvider, null, providerHelper); TradeableInstrument<String> audusd = new TradeableInstrument<String>("AUD_USD"); TradeableInstrument<String> euraud = new TradeableInstrument<String>("EUR_AUD"); TradeableInstrument<String> audeur = new TradeableInstrument<String>("AUD_EUR"); Account<Long> account = mock(Account.class); when(accountDataProvider.getLatestAccountInfo(TradingTestConstants.accountId)).thenReturn(account); when(account.getCurrency()).thenReturn("EUR"); when(account.getMarginRate()).thenReturn(marginRate); when(providerHelper.fromIsoFormat(eq("AUDEUR"))).thenReturn(audeur.getInstrument()); when(providerHelper.fromIsoFormat(eq("EURAUD"))).thenReturn(euraud.getInstrument()); Map<TradeableInstrument<String>, Price<String>> priceInfoMap = Maps.newHashMap(); priceInfoMap.put(euraud, new Price<String>(euraud, 1.5636, 1.564, DateTime.now())); when(currentPriceInfoProvider.getCurrentPricesForInstruments(eq(Lists.newArrayList(audeur)))).thenReturn( Maps.<TradeableInstrument<String>, Price<String>> newHashMap()); when(currentPriceInfoProvider.getCurrentPricesForInstruments(eq(Lists.newArrayList(euraud)))).thenReturn( priceInfoMap); double marginRate = accInfoService.calculateMarginForTrade(TradingTestConstants.accountId, audusd, units); assertEquals(383.6807, marginRate, TradingTestConstants.precision); marginRate = accInfoService.calculateMarginForTrade(TradingTestConstants.accountId, euraud, units); assertEquals(600.0, marginRate, TradingTestConstants.precision); }