public async Task <TransactionImportResult> ImportFile(TransactonImporterSettings settings) { var textReader = new StreamReader(settings.Filename); var csvReader = new CsvReader(textReader); csvReader.Configuration.RegisterClassMap <ZoDogeCsvImporterRecordClassMap>(); var transactions = new List <Transaction>(); var unknownDogecoinPriceIds = new HashSet <string>(); var rowCount = 0; while (csvReader.Read()) { var record = csvReader.GetRecord <ZoDogeCsvImporterRecord>(); if (!record.IsConfirmed) { continue; } var dogecoinPriceInUsdAtTransactionTime = await this._priceInUsdProvider.GetDogePrice(record.TimeStamp); if (!dogecoinPriceInUsdAtTransactionTime.HasValue) { unknownDogecoinPriceIds.Add(record.Id); continue; } transactions.Add(new Transaction { Crypto = Crypto.CryptoType.Dogecoin, TransactionDate = record.TimeStamp, TransactionType = record.IsReceived ? TransactionType.Buy : TransactionType.Sell, Quantity = record.Amount, UsDollarAmount = dogecoinPriceInUsdAtTransactionTime.Value * record.Amount }); this.RowProcessed?.Invoke(this, new RowProcessedEventArgs { RowsProcessed = ++rowCount }); } string message = null; if (unknownDogecoinPriceIds.Any()) { message = "The following transaction(s) could not be imported because the historic price is unknown:" + Environment.NewLine + string.Join(Environment.NewLine, unknownDogecoinPriceIds); } return(new TransactionImportResult { IsSuccess = true, Transactions = transactions, Message = message }); }
public Task <TransactionImportResult> ImportFile(TransactonImporterSettings settings) { var textReader = new StreamReader(settings.Filename); // skip rows prior to the transaction section for (var i = 1; i < 5; i++) { textReader.ReadLine(); } var csvReader = new CsvReader(textReader); csvReader.Configuration.RegisterClassMap <CoinbaseCsvRecordClassMap>(); var transactions = new List <Transaction>(); var nonBuyOrSellTransactionCount = 0; var rowCount = 0; while (csvReader.Read()) { var record = csvReader.GetRecord <CoinbaseCsvRecord>(); if (record.TransferTotal == null || !this._cryptoMapping.ContainsKey(record.Currency)) { nonBuyOrSellTransactionCount++; continue; } transactions.Add(new Transaction { Crypto = this._cryptoMapping[record.Currency], // Sell transactions appear as negative crypto amounts so that needs to be corrected. Quantity = record.Amount.Value * (record.TransactionType == TransactionType.Buy ? 1 : -1), TransactionDate = record.Timestamp, TransactionType = record.TransactionType, UsDollarAmount = record.TransferTotal.Value - record.TransferFee.Value }); this.RowProcessed?.Invoke(this, new RowProcessedEventArgs { RowsProcessed = ++rowCount }); } return(Task.Factory.StartNew(() => new TransactionImportResult { IsSuccess = true, Transactions = transactions, Message = $"{nonBuyOrSellTransactionCount} item(s) in the CSV were ignored because they are not a buy or sell transction." })); }
public async Task <TransactionImportResult> ImportFile(TransactonImporterSettings settings) { var textReader = new StreamReader(settings.Filename); var csvReader = new CsvReader(textReader); csvReader.Configuration.RegisterClassMap <BitrixOrderCsvRecordClassMap>(); var transactions = new List <Transaction>(); var unknownTransactionTypeCount = 0; var unknownExchangeCount = 0; var unknownExchangeSet = new HashSet <string>(); var unknownTransactionTypeSet = new HashSet <string>(); var rowCount = 0; while (csvReader.Read()) { var record = csvReader.GetRecord <BitrixOrderCsvRecord>(); if (!record.TransactionType.HasValue) { unknownTransactionTypeCount++; unknownTransactionTypeSet.Add(record.RawTransactionTypeText); continue; } if (!this._exchangeMapping.ContainsKey(record.Exchange)) { unknownExchangeCount++; unknownExchangeSet.Add(record.Exchange); continue; } var bitcoinPriceAtTransactionTime = await this._priceInUsdProvider.GetBitcoinPrice(record.ClosedTimestamp); var bitcoinAmount = record.AssetAmount * record.PriceInBitcoin; var usdEquivalentAmount = bitcoinAmount * bitcoinPriceAtTransactionTime; transactions.Add(new Transaction { Crypto = Crypto.CryptoType.Bitcoin, TransactionDate = record.ClosedTimestamp, TransactionType = record.TransactionType.Value == TransactionType.Buy ? TransactionType.Sell : TransactionType.Buy, Quantity = bitcoinAmount + record.CommissionInBitcoin, UsDollarAmount = usdEquivalentAmount }); transactions.Add(new Transaction { Crypto = this._exchangeMapping[record.Exchange], TransactionDate = record.ClosedTimestamp, TransactionType = record.TransactionType.Value, Quantity = record.AssetAmount, UsDollarAmount = usdEquivalentAmount }); this.RowProcessed?.Invoke(this, new RowProcessedEventArgs { RowsProcessed = ++rowCount }); } var messageStringBuilder = new StringBuilder(); if (unknownExchangeCount > 0) { messageStringBuilder.AppendLine($"{unknownExchangeCount} transaction(s) were ignored because they used an unsupported exchange. The following unsupported exchange(s) were found: {string.Join(", ", unknownExchangeSet)}."); } if (unknownTransactionTypeCount > 0) { messageStringBuilder.AppendLine($"{unknownTransactionTypeCount} transaction(s) were ignored because they used an unsupoorted transaction type. The following unsupported transaction type(s) were found: {string.Join(", ", unknownTransactionTypeSet)}."); } return(new TransactionImportResult { IsSuccess = true, Transactions = transactions, Message = messageStringBuilder.ToString() }); }
public async Task <TransactionImportResult> ImportFile(TransactonImporterSettings settings) { var textReader = new StreamReader(settings.Filename); var csvReader = new CsvReader(textReader); csvReader.Configuration.RegisterClassMap <GdaxFillCsvRecordClassMap>(); var transactions = new List <Transaction>(); var unknownProductTransactionCount = 0; var unknownProductTransactionSet = new HashSet <string>(); var rowCount = 0; while (csvReader.Read()) { var record = csvReader.GetRecord <GdaxFillCsvRecord>(); if (!this._productMapping.ContainsKey(record.Product)) { unknownProductTransactionCount++; unknownProductTransactionSet.Add(record.Product); continue; } var product = this._productMapping[record.Product]; switch (product.TransactionCurrency) { case TransactionCurrencyType.Usd: transactions.Add(new Transaction { Crypto = product.ProductAsset, TransactionDate = record.CreatedAt, TransactionType = record.TransactionType, Quantity = record.AssetAmount, UsDollarAmount = record.AssetPrice * record.AssetAmount }); break; case TransactionCurrencyType.Bitcoin: var bitcoinPriceAtTransactionTime = await this._priceInUsdProvider.GetBitcoinPrice(record.CreatedAt); var bitcoinAmount = record.AssetPrice * record.AssetAmount; var usdEquivalentAmounnt = bitcoinAmount * bitcoinPriceAtTransactionTime; transactions.Add(new Transaction { Crypto = Crypto.CryptoType.Bitcoin, TransactionDate = record.CreatedAt, TransactionType = record.TransactionType == TransactionType.Buy ? TransactionType.Sell : TransactionType.Buy, Quantity = bitcoinAmount, UsDollarAmount = usdEquivalentAmounnt }); transactions.Add(new Transaction { Crypto = product.ProductAsset, TransactionDate = record.CreatedAt, TransactionType = record.TransactionType, Quantity = record.AssetAmount, UsDollarAmount = usdEquivalentAmounnt }); break; default: throw new InvalidOperationException($"Unknown transaction currency: {product.TransactionCurrency}"); } this.RowProcessed?.Invoke(this, new RowProcessedEventArgs { RowsProcessed = ++rowCount }); } var result = new TransactionImportResult { IsSuccess = true, Transactions = transactions, }; if (unknownProductTransactionCount > 0) { result.Message = $@"{unknownProductTransactionCount} transaction(s) found were ignored since they used an unsupported product. The following unsupported product(s) were found: {string.Join(", ", unknownProductTransactionSet)}."; } return(result); }
public async Task <TransactionImportResult> ImportFile(TransactonImporterSettings settings) { var settingsDiaolog = this._formFactory.CreateForm <CustomCsvImporterDialog>(); var result = settingsDiaolog.ShowDialog(); if (result != DialogResult.OK) { return(new TransactionImportResult { IsSuccess = false, Message = "Custom CSV import canceled." }); } var customCsvHeaderSettings = settingsDiaolog.Settings; var textReader = new StreamReader(settings.Filename); var csvReader = new CsvReader(textReader); csvReader.Configuration.RegisterClassMap(new CustomCsvImporterRecordClassMap(customCsvHeaderSettings)); var transactions = new List <Transaction>(); var unknownDogecoinPriceIds = new HashSet <string>(); var rowCount = 0; while (csvReader.Read()) { var record = csvReader.GetRecord <CustomCsvImporterRecord>(); var exchangeResult = this._exchangeParser.ParseExchange(record.Exchange); if (record.CryptoAmount == 0) { continue; } if (exchangeResult.TransactionCurrency == TransactionCurrencyType.Usd) { transactions.Add(new Transaction { Crypto = exchangeResult.AssetCurrency, TransactionDate = record.Date, TransactionType = record.TransactionType, Quantity = record.CryptoAmount, UsDollarAmount = record.TransactionCurrencyAmount, ExcludeFromPortfolio = record.ExcludeFromPortfolio }); } else { decimal transactionCurrencyePriceAtTransactionTime; switch (exchangeResult.TransactionCurrency) { case TransactionCurrencyType.Bitcoin: transactionCurrencyePriceAtTransactionTime = await this._priceInUsdProvider.GetBitcoinPrice(record.Date); break; case TransactionCurrencyType.Ethereum: transactionCurrencyePriceAtTransactionTime = await this._priceInUsdProvider.GetEthereumPrice(record.Date); break; default: throw new InvalidOperationException("Should never get here."); } var usdEquivalentAmount = record.TransactionCurrencyAmount * transactionCurrencyePriceAtTransactionTime; transactions.Add(new Transaction { Crypto = exchangeResult.TransactionCurrency.ToCryptoType(), TransactionDate = record.Date, TransactionType = record.TransactionType == TransactionType.Buy ? TransactionType.Sell : TransactionType.Buy, Quantity = record.TransactionCurrencyAmount, UsDollarAmount = usdEquivalentAmount, ExcludeFromPortfolio = record.ExcludeFromPortfolio }); transactions.Add(new Transaction { Crypto = exchangeResult.AssetCurrency, TransactionDate = record.Date, TransactionType = record.TransactionType == TransactionType.Buy ? TransactionType.Buy : TransactionType.Sell, Quantity = record.CryptoAmount, UsDollarAmount = usdEquivalentAmount, ExcludeFromPortfolio = record.ExcludeFromPortfolio }); this.RowProcessed?.Invoke(this, new RowProcessedEventArgs { RowsProcessed = ++rowCount }); } } return(new TransactionImportResult { IsSuccess = true, Transactions = transactions, }); }