public function testRebuildAllocations()
 {
     $this->subclassCollection->rebuildAllocations();
     /** @var Subclass $subclass1 */
     $subclass1 = $this->subclassCollection->get(1);
     /** @var Subclass $subclass2 */
     $subclass2 = $this->subclassCollection->get(2);
     $this->assertEquals(10, $subclass1->getCurrentAllocation());
     $this->assertEquals(90, $subclass2->getCurrentAllocation());
     /*-----------------------------------------*/
     $subclass1->getSecurity()->setAmount(180);
     $subclass1->getMuniSecurity()->setAmount(120);
     $subclass2->getSecurity()->setAmount(300);
     $subclass2->getMuniSecurity()->setAmount(400);
     $this->subclassCollection->rebuildAllocations();
     $this->assertEquals(30, $subclass1->getCurrentAllocation());
     $this->assertEquals(70, $subclass2->getCurrentAllocation());
     /*-----------------------------------------*/
     $subclass1->getSecurity()->setAmount(0);
     $subclass1->getMuniSecurity()->setAmount(0);
     $subclass2->getSecurity()->setAmount(0);
     $subclass2->getMuniSecurity()->setAmount(0);
     $this->subclassCollection->rebuildAllocations();
     $this->assertEquals(0, $subclass1->getCurrentAllocation());
     $this->assertEquals(0, $subclass2->getCurrentAllocation());
 }
 /**
  * Operate subclasses by OOB
  * Return collection of sold and bought subclasses
  *
  * @param SubclassCollection $subclassCollection
  * @param Account $contextAccount
  * @return SubclassCollection
  */
 public function operateSubclasses(SubclassCollection $subclassCollection, Account $contextAccount = null)
 {
     $subclassCollection->rebuildAllocations();
     $oobSubclasses = $subclassCollection->sortByOob();
     $usedSubclasses = new SubclassCollection();
     $buyAndSellLimit = $this->getBuyAndSellLimit($oobSubclasses, $contextAccount);
     if ($buyAndSellLimit > 0) {
         $sellLimit = $buyAndSellLimit;
         $buyLimit = $buyAndSellLimit;
         /** @var Subclass $subclassForSell */
         $subclassForSell = $oobSubclasses->first();
         while ($subclassForSell && $subclassForSell->calcOOB() > 0 && $sellLimit > 0) {
             if ($contextAccount) {
                 $sold = $this->sellSubclass($subclassForSell, $contextAccount, $sellLimit, false);
             } else {
                 $sold = $this->sellSubclassHousehold($subclassForSell, $sellLimit, false);
             }
             $sellLimit -= $sold;
             $usedSubclasses->add($subclassForSell);
             $subclassForSell = $oobSubclasses->next();
         }
         /** @var Subclass $subclassForBuy */
         $subclassForBuy = $oobSubclasses->last();
         while ($subclassForBuy && $subclassForBuy->calcOOB() < 0 && $buyLimit > 0) {
             $needToBuy = $oobSubclasses->getOnePercentAmount() * abs($subclassForBuy->calcOOB());
             if ($contextAccount) {
                 $bought = $this->buySubclass($subclassForBuy, $contextAccount, $needToBuy, false);
             } else {
                 $bought = $this->buySubclassHousehold($subclassForBuy, $needToBuy, false);
             }
             $buyLimit -= $bought;
             $usedSubclasses->add($subclassForBuy);
             $subclassForBuy = $oobSubclasses->prev();
         }
     }
     return $usedSubclasses;
 }