// parses the base SecurityPosition
        internal static SecurityPosition parseSecurityPosition(CsvRow row, PositionInfo info, PositionCsvInfoResolver resolver)
        {
            string           securityIdScheme = row.findValue(SECURITY_ID_SCHEME_FIELD).orElse(DEFAULT_SECURITY_SCHEME);
            string           securityIdValue  = row.getValue(SECURITY_ID_FIELD);
            SecurityId       securityId       = SecurityId.of(securityIdScheme, securityIdValue);
            DoublesPair      quantity         = CsvLoaderUtils.parseQuantity(row);
            SecurityPosition position         = SecurityPosition.ofLongShort(info, securityId, quantity.First, quantity.Second);

            return(resolver.completePosition(row, position));
        }
        // parses the additional GenericSecurityPosition information
        internal static Position parseNonEtdPosition(CsvRow row, PositionInfo info, PositionCsvInfoResolver resolver)
        {
            SecurityPosition    @base        = parseSecurityPosition(row, info, resolver);
            double?             tickSizeOpt  = row.findValue(TICK_SIZE).map(str => LoaderUtils.parseDouble(str));
            Optional <Currency> currencyOpt  = row.findValue(CURRENCY).map(str => Currency.of(str));
            double?             tickValueOpt = row.findValue(TICK_VALUE).map(str => LoaderUtils.parseDouble(str));
            double              contractSize = row.findValue(CONTRACT_SIZE).map(str => LoaderUtils.parseDouble(str)).orElse(1d);

            if (tickSizeOpt.HasValue && currencyOpt.Present && tickValueOpt.HasValue)
            {
                SecurityPriceInfo priceInfo = SecurityPriceInfo.of(tickSizeOpt.Value, CurrencyAmount.of(currencyOpt.get(), tickValueOpt.Value), contractSize);
                GenericSecurity   sec       = GenericSecurity.of(SecurityInfo.of(@base.SecurityId, priceInfo));
                return(GenericSecurityPosition.ofLongShort(@base.Info, sec, @base.LongQuantity, @base.ShortQuantity));
            }
            return(@base);
        }
 //-------------------------------------------------------------------------
 // parses a position from the CSV row
 internal static Position parsePosition(CsvRow row, PositionInfo info, PositionCsvInfoResolver resolver)
 {
     if (row.findValue(EXPIRY_FIELD).Present)
     {
         // etd
         if (row.findValue(PUT_CALL_FIELD).Present || row.findValue(EXERCISE_PRICE_FIELD).Present)
         {
             return(resolver.parseEtdOptionPosition(row, info));
         }
         else
         {
             return(resolver.parseEtdFuturePosition(row, info));
         }
     }
     else
     {
         return(parseNonEtdPosition(row, info, resolver));
     }
 }
 // parses a SecurityPosition from the CSV row, converting ETD information
 internal static SecurityPosition parsePositionLightweight(CsvRow row, PositionInfo info, PositionCsvInfoResolver resolver)
 {
     if (row.findValue(EXPIRY_FIELD).Present)
     {
         // etd
         if (row.findValue(PUT_CALL_FIELD).Present || row.findValue(EXERCISE_PRICE_FIELD).Present)
         {
             return(resolver.parseEtdOptionSecurityPosition(row, info));
         }
         else
         {
             return(resolver.parseEtdFutureSecurityPosition(row, info));
         }
     }
     else
     {
         // simple
         return(parseSecurityPosition(row, info, resolver));
     }
 }