// returns any closed PL calculated on position basis (not per share) /// <summary> /// Adjusts the position by applying a new position. /// </summary> /// <param name="pos">The position adjustment to apply.</param> /// <returns></returns> public decimal Adjust(Position pos) { if ((_fullsymbol!="") && (this._fullsymbol != pos._fullsymbol)) throw new Exception("Failed because adjustment symbol did not match position symbol"); if (_acct == DefaultSettings.DefaultAccount) _acct = pos.Account; if (_acct != pos.Account) throw new Exception("Failed because adjustment account did not match position account."); if ((_fullsymbol=="") && pos.isValid) _fullsymbol = pos._fullsymbol; if (!pos.isValid) throw new Exception("Invalid position adjustment, existing:" + this.ToString() + " adjustment:" + pos.ToString()); decimal pl = 0; if (! pos.isFlat) { bool oldside = isLong; pl = Calc.ClosePL(this, pos.ToTrade()); if (this.isFlat) this._avgprice = pos.AvgPrice; // if we're leaving flat just copy price else if ((pos.isLong && this.isLong) || (!pos.isLong && !this.isLong)) // sides match, adding so adjust price this._avgprice = ((this._avgprice * this._size) + (pos.AvgPrice * pos.Size)) / (pos.Size + this.Size); this._size += pos.Size; // adjust the size if (oldside != isLong) _avgprice = pos.AvgPrice; // this is for when broker allows flipping sides in one trade if (this.isFlat) _avgprice = 0; // if we're flat after adjusting, size price back to zero _closedpl += pl; // update running closed pl return pl; } _openpl = Calc.OpenPL(pos.AvgPrice, this); return pl; }
// these are for calculating closed pl // they do not adjust positions themselves /// <summary> /// Gets the closed PL on a per-share basis, ignoring how many shares are held. /// </summary> /// <param name="existing">The existing position.</param> /// <param name="closing">The portion of the position that's being closed/changed.</param> /// <returns></returns> public static decimal ClosePT(Position existing, Trade adjust) { if (!existing.isValid || !adjust.IsValid) throw new Exception("Invalid position provided. (existing:" + existing.ToString() + " adjustment:" + adjust.ToString()); if (existing.isFlat) return 0; // nothing to close if (existing.isLong == adjust.Side) return 0; // if we're adding, nothing to close return existing.isLong ? adjust.TradePrice - existing.AvgPrice : existing.AvgPrice - adjust.TradePrice; }