コード例 #1
0
ファイル: Models.cs プロジェクト: DonaldAirey/quasar
        /// <summary>
        /// Chooses or creates a model for the appraisal.
        /// </summary>
        /// <param name="accountId">The account used to select a model.</param>
        public static int SelectModel(int accountId)
        {
            // The logic in this method will determine if a temporary model is needed and built it.  If a temporary model is
            // required, it will be built using this command batch.  In all cases, the appropriate model for the given account will
            // be returned to the caller.  In some cases, a model will be constructed on the fly from the existing values in the
            // account.  These temporary models will use most of the position and trading tables
            ModelBatch modelBatch = null;

            try
            {
                // Lock the tables
                Debug.Assert(!ClientMarketData.AreLocksHeld);
                ClientMarketData.AccountLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.AllocationLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.CurrencyLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.DebtLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.EquityLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.ModelLock.AcquireWriterLock(CommonTimeout.LockWait);
                ClientMarketData.SectorTargetLock.AcquireWriterLock(CommonTimeout.LockWait);
                ClientMarketData.PositionTargetLock.AcquireWriterLock(CommonTimeout.LockWait);
                ClientMarketData.ObjectLock.AcquireWriterLock(CommonTimeout.LockWait);
                ClientMarketData.ObjectTreeLock.AcquireWriterLock(CommonTimeout.LockWait);
                ClientMarketData.OrderLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.PriceLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.ProposedOrderLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.SchemeLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.SectorLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.SecurityLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.TaxLotLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.TransactionTypeLock.AcquireReaderLock(CommonTimeout.LockWait);

                // Find the account record that is being opened.
                ClientMarketData.AccountRow accountRow = ClientMarketData.Account.FindByAccountId(accountId);
                if (accountRow == null)
                {
                    throw new Exception(String.Format("Account {0} has been deleted", accountId));
                }

                // The objective is to find out whether a 'Self' model must be created from the existing positions, or whether a
                // an empty or a copy of a model is required to view an account appraisal.  The first test is to see whether any model
                // has been assigned to the account.
                if (accountRow.IsModelIdNull())
                {
                    // This will create an empty position model for the appraisal.
                    modelBatch = Models.CreateEmptyModel(accountRow);
                }
                else
                {
                    // At this point, a model has been assigned to the account.  Get the model and find out if a temporary copy
                    // needs to be made.
                    ClientMarketData.ModelRow modelRow = ClientMarketData.Model.FindByModelId(accountRow.ModelId);
                    if (modelRow == null)
                    {
                        throw new Exception(String.Format("Model {0} has been deleted", accountRow.ModelId));
                    }

                    // A 'self' model is one that requires a calculation of the current positions.
                    if (!modelRow.SectorSelf && !modelRow.SecuritySelf)
                    {
                        // Currently, the existing model is used on an appraisal.  Any changes to the model in the appraisal view
                        // will be stored in the persistent model.  It may be useful sometime in the future to make a copy of the
                        // model and prompt the user to save it when the appraisal is closed.
                        return(modelRow.ModelId);
                    }
                    else
                    {
                        // Make sure that the account has been assigned a scheme before attempting to build a model from it.
                        if (accountRow.IsSchemeIdNull())
                        {
                            throw new Exception(String.Format("No scheme has been assigned to account {0}.", accountRow));
                        }

                        // If the account has a default scheme, make sure it still exists.
                        ClientMarketData.SchemeRow schemeRow = ClientMarketData.Scheme.FindBySchemeId(accountRow.SchemeId);
                        if (schemeRow == null)
                        {
                            throw new ArgumentException("This scheme has been deleted", accountRow.SchemeId.ToString());
                        }

                        // Create a model based on the current sector totals.
                        if (modelRow.SectorSelf)
                        {
                            modelBatch = Models.CreateSectorSelfModel(accountRow, schemeRow);
                        }

                        // Create a model based on the current position totals.
                        if (modelRow.SecuritySelf)
                        {
                            modelBatch = Models.CreatePositionSelfModel(accountRow, schemeRow);
                        }
                    }
                }
            }
            finally
            {
                // Release the table locks.
                if (ClientMarketData.AccountLock.IsReaderLockHeld)
                {
                    ClientMarketData.AccountLock.ReleaseReaderLock();
                }
                if (ClientMarketData.AllocationLock.IsReaderLockHeld)
                {
                    ClientMarketData.AllocationLock.ReleaseReaderLock();
                }
                if (ClientMarketData.CurrencyLock.IsReaderLockHeld)
                {
                    ClientMarketData.CurrencyLock.ReleaseReaderLock();
                }
                if (ClientMarketData.DebtLock.IsReaderLockHeld)
                {
                    ClientMarketData.DebtLock.ReleaseReaderLock();
                }
                if (ClientMarketData.EquityLock.IsReaderLockHeld)
                {
                    ClientMarketData.EquityLock.ReleaseReaderLock();
                }
                if (ClientMarketData.ModelLock.IsWriterLockHeld)
                {
                    ClientMarketData.ModelLock.ReleaseWriterLock();
                }
                if (ClientMarketData.SectorTargetLock.IsWriterLockHeld)
                {
                    ClientMarketData.SectorTargetLock.ReleaseWriterLock();
                }
                if (ClientMarketData.PositionTargetLock.IsWriterLockHeld)
                {
                    ClientMarketData.PositionTargetLock.ReleaseWriterLock();
                }
                if (ClientMarketData.ObjectLock.IsWriterLockHeld)
                {
                    ClientMarketData.ObjectLock.ReleaseWriterLock();
                }
                if (ClientMarketData.ObjectTreeLock.IsWriterLockHeld)
                {
                    ClientMarketData.ObjectTreeLock.ReleaseWriterLock();
                }
                if (ClientMarketData.OrderLock.IsReaderLockHeld)
                {
                    ClientMarketData.OrderLock.ReleaseReaderLock();
                }
                if (ClientMarketData.PriceLock.IsReaderLockHeld)
                {
                    ClientMarketData.PriceLock.ReleaseReaderLock();
                }
                if (ClientMarketData.ProposedOrderLock.IsReaderLockHeld)
                {
                    ClientMarketData.ProposedOrderLock.ReleaseReaderLock();
                }
                if (ClientMarketData.SchemeLock.IsReaderLockHeld)
                {
                    ClientMarketData.SchemeLock.ReleaseReaderLock();
                }
                if (ClientMarketData.SectorLock.IsReaderLockHeld)
                {
                    ClientMarketData.SectorLock.ReleaseReaderLock();
                }
                if (ClientMarketData.SecurityLock.IsReaderLockHeld)
                {
                    ClientMarketData.SecurityLock.ReleaseReaderLock();
                }
                if (ClientMarketData.TaxLotLock.IsReaderLockHeld)
                {
                    ClientMarketData.TaxLotLock.ReleaseReaderLock();
                }
                if (ClientMarketData.TransactionTypeLock.IsReaderLockHeld)
                {
                    ClientMarketData.TransactionTypeLock.ReleaseReaderLock();
                }
                Debug.Assert(!ClientMarketData.AreLocksHeld);
            }

            // At this point, a batch is ready to be sent that will create the model and populate it with target values.  The data
            // structure is an overloaded version of the 'RemoteBatch' class.  The 'ModelBatch' contains a member which references
            // the 'modelId' return value from the creation of the model.  This value will be returned to the caller as a reference
            // to the temporary model.
            ClientMarketData.Send(modelBatch);

            // Rethrow a generic error message for the failed model.
            if (modelBatch.HasExceptions)
            {
                throw new Exception("Can't create model.");
            }

            // Return the model identifier generated by the server.
            return((int)modelBatch.ModelIdParameter.Value);
        }