public async Task <Task> ProcessCsv(string csv, Dictionary <string, string> attr)
        {
            var    path    = attr["FilePath"];
            var    machine = attr["MachineName"];
            string key     = path + "-" + machine;

            var epexRows = _parser.Parse(csv, CultureInfo.GetCultureInfo("en-US"));

            var posHelp    = new PositionsHelper(_context, key);
            var currentPos = await posHelp.GetCurrentPosition();

            var tradeNo = Int32.MinValue;

            foreach (var row in epexRows.OrderBy(r => r.TradeNo))
            {
                tradeNo = Convert.ToInt32(row.TradeNo);
                if (tradeNo > currentPos)
                {
                    // Quantity bestemmes af buy/sell: Hvis vi har købt skal quantity angives med positivt fortegn.
                    // Hvis vi har solgt skal quantity angives med negativt fortegn
                    decimal quant = row.Quantity;
                    decimal price = row.Price;
                    int     fact  = row.BuySell.ToUpper() == "B" ? 1 : -1;

                    Effect effect = Effect.FromMegawatts(quant * fact);
                    Money  money  = new Money(price, new Currency(row.Currency));

                    // Hent alias og heraf grid ud fra landekoden i CSV filen (aflæses i EIC feltet).
                    TsoAlias alias = GetTsoAliases(row.EIC.Substring(3, 2), "TsoAlias");
                    Grid     grid  = alias.Grid;

                    // Vi henter tidszonen fra grid
                    var timeZone = grid.TimeZoneInfo;

                    //CSV timeperiod format : 20200123 15:00-20200123 15:30
                    DateTimeOffset from       = GetEpexDateTimeOffSet(row.Contract.Substring(0, 14), timeZone);
                    DateTimeOffset to         = GetEpexDateTimeOffSet(row.Contract.Substring(15, 14), timeZone);
                    TimePeriod     timePeriod = new TimePeriod(from, to);

                    var sourceBook = _context.Books.Where(tso => (tso.ShortName == row.TSO || tso.ShortName == row.TSO + " INTRA")).FirstOrDefault() ?? throw new ArgumentException($"Could not get exchange book for TSO {row.TSO}");
                    var targetBook = grid.DefaultTradeBook ?? throw new ArgumentException($"Could not get default trade book for grid {grid}");

                    var traderId = _context.Traders.Where(trader => trader.ExternalTraderId == row.TraderId && trader.TradingPlatform == "EPEX").FirstOrDefault() ?? throw new ArgumentException($"Could not validate trader {row.TraderId}");

                    var transaction = Model.Entities.Transaction.CreateTrade(grid, timePeriod, sourceBook, targetBook, effect, money, traderId.ExternalTraderId, row.Text);
                    transaction.SetExternalReference(new ExternalReference("EPEX-" + row.TSO + "-" + row.OrderNo + "-" + row.TradeNo));

                    var ex = await _context.Transactions.FindByExternalReferenceAsync(transaction.ExternalReference);

                    if (ex == null)
                    {
                        await _context.Transactions.AddAsync(transaction);
                    }
                }
            }
            await posHelp.SetPosition(tradeNo);

            _context.SaveChanges();
            return(Task.CompletedTask);
        }
        public async Task <Task> ProcessCsv(string filePath)
        {
            var epexRowsJao = _parser.ParseJao(filePath, CultureInfo.GetCultureInfo("en-US"));

            foreach (var row in epexRowsJao)
            {
                Trade trade = _context.Trades.Find(row.TradeNo);

                if (trade == null)
                {
                    await _context.Trades.AddAsync(row);
                }
            }

            _context.SaveChanges();
            return(Task.CompletedTask);
        }