public void Process()
 {
     foreach (var stx in _txs)
     {
         _tp.Process(stx);
     }
 }
        public void Setup()
        {
            var random = new Random(Seed: 145);
            var utxos  = new List <Coin>();

            _tp = CreateTransactionProcessorAsync().Result;

            // Crediting transactions
            for (var i = 0; i < 100; i++)
            {
                var stx = CreateCreditingTransaction(GetP2wpkhScript(_tp), Money.Coins(2.0m), true);
                utxos.Add(stx.Transaction.Outputs.AsCoins().First());
                _tp.Process(stx);
            }

            _txs = new List <SmartTransaction>(TRANSACTIONS);
            for (var i = 0; i < TRANSACTIONS; i++)
            {
                var numOfCoinsToSpend = Math.Min(random.Next(1, 3), utxos.Count());
                var coinsToSpend      = utxos.Take(numOfCoinsToSpend);
                var stx = CreateSpendingTransaction(coinsToSpend, new Key().PubKey.ScriptPubKey, GetP2wpkhScript(_tp));
                utxos.Add(stx.Transaction.Outputs.AsCoins().Last());
                _txs.Add(stx);
            }
        }
예제 #3
0
        public void SaveWrongTransaction()
        {
            //Arrange
            var underTestTransaction = new TransactionInput()
            {
                Account      = "",
                Description  = "Descrip",
                CurrencyCode = "GBP",
                Amount       = "5"
            };
            //Act
            var mockTransactionDataProvider = A.Fake <ITransactionDataProvider>();
            var testTransaction             = new TransactionProcessor(new Iso4217DataProvider(), mockTransactionDataProvider);
            var result = testTransaction.Process(underTestTransaction);

            //Assert
            Assert.True(result.Error);
        }
예제 #4
0
        public void ValidateFailedSavingTransaction()
        {
            //Arrange
            var testTransactionInput = new TransactionInput()
            {
                Account      = "Account",
                Description  = "Descrip",
                CurrencyCode = "GBP",
                Amount       = "5"
            };
            //Act


            var transation = Mapper.Map <Transaction>(testTransactionInput);
            ITransactionDataProvider transactionDataProvider = A.Fake <ITransactionDataProvider>();

            A.CallTo(() => transactionDataProvider.Save(transation)).Returns(0);
            var transactionProcessor = new TransactionProcessor(new Iso4217DataProvider(), transactionDataProvider);
            var result = transactionProcessor.Process(testTransactionInput);

            //Assert
            Assert.True(result.Error);
        }
        /// <inheritdoc />
        public RecurringTransaction UpdateRecurringTransaction(
            int id, InputRecurringTransaction input, bool updateInstances)
        {
            this.validator.Description(input.Description);
            var startPeriod = this.validator.DateString(input.StartDateString, "startDate");
            var endPeriod   = input.EndDateString.Select(d => this.validator.DateString(d, "endDate"));

            if (endPeriod.IsSome)
            {
                this.validator.Period(startPeriod, endPeriod);
            }
            this.validator.Interval(input.Interval);
            var type = this.GetTransactionType(input.CategoryId, input.ReceivingAccountId, input.Amount);

            this.validator.Splits(this.splitwiseContext, input.PaymentRequests, input.SplitwiseSplits, type, input.Amount);

            return(this.ConcurrentInvoke(() =>
            {
                var processor = new TransactionProcessor(this.Context, this.splitwiseContext);

                var entity = this.Context.RecurringTransactions.GetEntity(id);

                this.validator.AccountType(entity.Account.Type);
                if (entity.ReceivingAccount != null)
                {
                    this.validator.AccountType(entity.ReceivingAccount.Type);
                }

                if (type != entity.Type) // TODO: Add test for this case
                {
                    throw new ValidationException("Changing the type of transaction is not possible.");
                }

                if (!updateInstances && startPeriod != entity.StartDate)
                {
                    throw new ValidationException($"Updating the start date without updating already created instances is not supported.");
                }

                var account = this.Context.Accounts.GetEntity(input.AccountId, false);

                this.validator.AccountType(account.Type);

                var category = input.CategoryId.Select(cId => this.Context.Categories.GetEntity(cId, false));

                AccountEntity receivingAccount = null;
                if (input.ReceivingAccountId.IsSome)
                {
                    receivingAccount = this.Context.Accounts.GetEntity(input.ReceivingAccountId.Value, false);

                    if (receivingAccount.Id == account.Id)
                    {
                        throw new ValidationException("Sender account can not be the same as receiver account.");
                    }

                    this.validator.AccountType(receivingAccount.Type);
                }

                // Verify a Splitwise account exists when adding providing splits.
                if (input.SplitwiseSplits.Any())
                {
                    this.Context.Accounts.GetSplitwiseEntity();
                }

                entity.AccountId = input.AccountId;
                entity.Account = account;
                entity.Description = input.Description;
                entity.StartDate = startPeriod;
                entity.EndDate = endPeriod.ToNullable();
                entity.Amount = input.Amount;
                entity.CategoryId = input.CategoryId.ToNullable();
                entity.Category = category.ToNullIfNone();
                entity.ReceivingAccountId = input.ReceivingAccountId.ToNullable();
                entity.ReceivingAccount = receivingAccount;
                entity.NeedsConfirmation = input.NeedsConfirmation;
                entity.Interval = input.Interval;
                entity.IntervalUnit = input.IntervalUnit;
                entity.SplitDetails = input.SplitwiseSplits.Select(s => s.ToSplitDetailEntity()).ToList();

                var instances = this.Context.Transactions.GetTransactionsFromRecurring(entity.Id);
                var instancesToUpdate = updateInstances
                    ? instances.ToList() // Copy the list
                                         // Always update all unprocessed transactions.
                    : instances.Where(t => !t.Processed).ToList();

                foreach (var instance in instancesToUpdate)
                {
                    processor.RevertIfProcessed(instance);
                    instances.Remove(instance);
                    this.Context.Remove(instance);
                }

                entity.LastOccurence = instances
                                       .OrderByDescending(t => t.Date)
                                       .FirstOrNone()
                                       .Select(t => (LocalDate?)t.Date)
                                       .ValueOrElse(() => (LocalDate?)null);
                entity.SetNextOccurrence();

                processor.Process(entity);

                this.Context.SaveChanges();

                return entity.AsRecurringTransaction();
            }));
        }
        /// <inheritdoc />
        public RecurringTransaction CreateRecurringTransaction(InputRecurringTransaction input)
        {
            this.validator.Description(input.Description);
            var startPeriod = this.validator.DateString(input.StartDateString, "startDate");
            var endPeriod   = input.EndDateString.Select(d => this.validator.DateString(d, "endDate"));

            if (endPeriod.IsSome)
            {
                this.validator.Period(startPeriod, endPeriod);
            }
            this.validator.Interval(input.Interval);
            var type = this.GetTransactionType(input.CategoryId, input.ReceivingAccountId, input.Amount);

            this.validator.Splits(this.splitwiseContext, input.PaymentRequests, input.SplitwiseSplits, type, input.Amount);

            return(this.ConcurrentInvoke(() =>
            {
                var processor = new TransactionProcessor(this.Context, this.splitwiseContext);

                var account = this.Context.Accounts.GetEntity(input.AccountId, false);

                this.validator.AccountType(account.Type);

                var category = input.CategoryId.Select(cId => this.Context.Categories.GetEntity(cId, false));

                AccountEntity receivingAccount = null;
                if (input.ReceivingAccountId.IsSome)
                {
                    receivingAccount = this.Context.Accounts.GetEntity(input.ReceivingAccountId.Value, false);

                    if (receivingAccount.Id == account.Id)
                    {
                        throw new ValidationException("Sender account can not be the same as receiver account.");
                    }

                    this.validator.AccountType(receivingAccount.Type);
                }

                // Verify a Splitwise account exists when adding providing splits.
                if (input.SplitwiseSplits.Any())
                {
                    this.Context.Accounts.GetSplitwiseEntity();
                }

                var entity = new RecurringTransactionEntity
                {
                    Description = input.Description,
                    Type = type,
                    Amount = input.Amount,
                    StartDate = startPeriod,
                    EndDate = endPeriod.ToNullable(),
                    AccountId = input.AccountId,
                    Account = account,
                    CategoryId = input.CategoryId.ToNullable(),
                    Category = category.ToNullIfNone(),
                    ReceivingAccountId = input.ReceivingAccountId.ToNullable(),
                    ReceivingAccount = receivingAccount,
                    Interval = input.Interval,
                    IntervalUnit = input.IntervalUnit,
                    NeedsConfirmation = input.NeedsConfirmation,
                    NextOccurence = startPeriod,
                    PaymentRequests = new List <PaymentRequestEntity>(), // TODO: Payment requests
                    SplitDetails = input.SplitwiseSplits.Select(s => s.ToSplitDetailEntity()).ToList(),
                };

                processor.Process(entity);

                this.Context.RecurringTransactions.Add(entity);
                this.Context.SaveChanges();

                return entity.AsRecurringTransaction();
            }));
        }
예제 #7
0
        public static void Main(string[] args)
        {
            try
            {
                var result = new List <string>();

                const string transactionSource = @"C:\Users\tgravran\Documents\visual studio 2015\Projects\SolutionStockExplorer\stock.console\data_total.csv";
                const string resultFile        = @"C:\Users\tgravran\Documents\visual studio 2015\Projects\SolutionStockExplorer\stock.console\resultFile.csv";

                IDataLoader         loader  = new DataLoader.DataLoader(transactionSource);
                ITransactionFactory factory = new TransactionFactory();

                decimal amountIncrement = (decimal)1000;
                decimal amountMin       = (decimal)1000;
                decimal amountMax       = (decimal)30000;

                decimal highPriceMin       = (decimal)0;
                decimal highPriceMax       = (decimal)2;
                decimal highPriceIncrement = (decimal)0.1;

                decimal lowPriceMin       = (decimal)0;
                decimal lowPriceMax       = (decimal)2;
                decimal lowPriceIncrement = (decimal)0.1;

                double totalCount = Convert.ToDouble((amountMax - amountMin) / amountIncrement * ((highPriceMax - highPriceMin) / highPriceIncrement) * ((lowPriceMax - lowPriceMin) / lowPriceIncrement));

                var tasks = new List <Task>();

                //for (var initialAmount = amountMin; initialAmount < amountMax; initialAmount += amountIncrement)
                //    for (var highPrice = highPriceMin; highPrice < highPriceMax; highPrice += highPriceIncrement)
                //        for (var lowPrice = lowPriceMin; lowPrice < lowPriceMax; lowPrice += lowPriceIncrement)
                //        {
                //            var c = new ProcessCondition()
                //            {
                //                HighPrice = highPrice,
                //                LowPrice = lowPrice,
                //                InitialAmount = initialAmount
                //            };

                //            var t = Task.Run(() =>
                //            {
                //                var processor = new TransactionProcessor(c);

                //                var enumerator = loader.Read();

                //                while (enumerator.MoveNext())
                //                    processor.Process(processor.Vault, enumerator.Current);

                //                result.Add(string.Format("{0},{1},{2},{3},{4},{5}", c.InitialAmount, c.HighPrice, c.LowPrice, processor.Vault.GetMargin(), processor.Vault.GetTotalBankFees(), processor.Vault.GetTransactionCount()));
                //                Console.WriteLine("{0},{1},{2},{3},{4},{5}", c.InitialAmount, c.HighPrice, c.LowPrice, processor.Vault.GetMargin(), processor.Vault.GetTotalBankFees(), processor.Vault.GetTransactionCount());
                //            });

                //            tasks.Add(t);
                //        }

                var c = new ProcessCondition()
                {
                    HighPrice     = (decimal)1.8,
                    LowPrice      = (decimal)0.2,
                    InitialAmount = (decimal)3000
                };

                var t = Task.Run(() =>
                {
                    IStockTradingStrategy strategy = new StandardStockStrategy(ComputeTransactionFee);

                    var processor  = new TransactionProcessor(ComputeTransactionFee, strategy, factory, c);
                    var enumerator = loader.Read();

                    while (enumerator.MoveNext())
                    {
                        processor.Process(enumerator.Current);
                    }

                    result.Add(string.Format("{0},{1},{2},{3},{4},{5},{6}", c.InitialAmount, c.HighPrice, c.LowPrice, processor.Vault.GetMargin(), processor.Vault.GetTotalBankFees(), processor.Vault.GetTransactionCount(), processor.Vault.Money));
                    Console.WriteLine("{0},{1},{2},{3},{4},{5},{6}", c.InitialAmount, c.HighPrice, c.LowPrice, processor.Vault.GetMargin(), processor.Vault.GetTotalBankFees(), processor.Vault.GetTransactionCount(), processor.Vault.Money);
                });

                tasks.Add(t);

                Task.WaitAll(tasks.ToArray());

                if (File.Exists(resultFile))
                {
                    File.Delete(resultFile);
                }

                //Insert Header
                result.Insert(0, string.Format("{0},{1},{2},{3},{4},{5},{6}", "InitialAmount", "High", "Low", "Margin", "BankFees", "TransactionCount", "Money"));

                //Write to file
                File.AppendAllLines(resultFile, result);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            Console.WriteLine("Process Over");
            Console.ReadKey();
        }