handle stock split
This commit is contained in:
@@ -9,19 +9,27 @@ import (
|
||||
type Filler struct {
|
||||
Record
|
||||
|
||||
filled decimal.Decimal
|
||||
filled decimal.Decimal
|
||||
quantity decimal.Decimal
|
||||
price decimal.Decimal
|
||||
}
|
||||
|
||||
func NewFiller(r Record) *Filler {
|
||||
return &Filler{
|
||||
Record: r,
|
||||
Record: r,
|
||||
quantity: r.Quantity(),
|
||||
price: r.Price(),
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Filler) Quantity() decimal.Decimal { return f.quantity }
|
||||
|
||||
func (f *Filler) Price() decimal.Decimal { return f.price }
|
||||
|
||||
// Fill accrues some quantity. Returns how mutch was accrued in the 1st return value and whether
|
||||
// it was filled or not on the 2nd return value.
|
||||
func (f *Filler) Fill(quantity decimal.Decimal) (decimal.Decimal, bool) {
|
||||
unfilled := f.Record.Quantity().Sub(f.filled)
|
||||
unfilled := f.quantity.Sub(f.filled)
|
||||
delta := decimal.Min(unfilled, quantity)
|
||||
f.filled = f.filled.Add(delta)
|
||||
return delta, f.IsFilled()
|
||||
@@ -29,7 +37,15 @@ func (f *Filler) Fill(quantity decimal.Decimal) (decimal.Decimal, bool) {
|
||||
|
||||
// IsFilled returns true if the fill is equal to the record quantity.
|
||||
func (f *Filler) IsFilled() bool {
|
||||
return f.filled.Equal(f.Quantity())
|
||||
return f.filled.Equal(f.quantity)
|
||||
}
|
||||
|
||||
// ApplySplit adjusts the lot for a stock split by the given ratio (newQty/oldQty).
|
||||
// The total cost basis is preserved: quantity scales up, price scales down proportionally.
|
||||
func (f *Filler) ApplySplit(ratio decimal.Decimal) {
|
||||
f.quantity = f.quantity.Mul(ratio)
|
||||
f.filled = f.filled.Mul(ratio)
|
||||
f.price = f.price.Div(ratio)
|
||||
}
|
||||
|
||||
type FillerQueue struct {
|
||||
@@ -86,6 +102,16 @@ func (fq *FillerQueue) frontElement() *list.Element {
|
||||
return fq.l.Front()
|
||||
}
|
||||
|
||||
// AdjustForSplit applies a stock split ratio to all lots in the queue.
|
||||
func (fq *FillerQueue) AdjustForSplit(ratio decimal.Decimal) {
|
||||
if fq == nil || fq.l == nil {
|
||||
return
|
||||
}
|
||||
for e := fq.l.Front(); e != nil; e = e.Next() {
|
||||
e.Value.(*Filler).ApplySplit(ratio)
|
||||
}
|
||||
}
|
||||
|
||||
// Len returns how many elements are currently on the queue
|
||||
func (fq *FillerQueue) Len() int {
|
||||
if fq == nil || fq.l == nil {
|
||||
|
||||
Reference in New Issue
Block a user