mirror of
https://github.com/HackaTUM-2022-PMWO/GameOfStonks.git
synced 2025-10-16 12:45:40 +00:00
fixed matcher
This commit is contained in:
parent
0bcc168c41
commit
e079a0785a
@ -42,7 +42,7 @@ var (
|
||||
startMoney float64 = 1000.0
|
||||
roundDuration time.Duration = 10 * time.Minute
|
||||
|
||||
matcherUpdateInterval time.Duration = time.Millisecond * 2000
|
||||
matcherUpdateInterval time.Duration = time.Second
|
||||
)
|
||||
|
||||
type ServiceHandler struct {
|
||||
@ -222,6 +222,7 @@ func main() {
|
||||
)
|
||||
|
||||
defer match.Close()
|
||||
go match.Start()
|
||||
|
||||
// create some bots so the market has some actual movement
|
||||
bots := make([]bot.Bot, 0, 40)
|
||||
|
||||
@ -68,8 +68,11 @@ func (m *Matcher) Start() {
|
||||
m.l.Info("shutting down")
|
||||
return
|
||||
case <-ticker.C:
|
||||
//m.l.Info("running matcher")
|
||||
|
||||
allMatches := m.matchStonks()
|
||||
if len(allMatches) > 0 {
|
||||
m.l.Info("matcher found new matches")
|
||||
// NOTE: blocking, but the channel is buffered
|
||||
m.matchUpdateCh <- allMatches
|
||||
}
|
||||
@ -78,11 +81,18 @@ func (m *Matcher) Start() {
|
||||
}
|
||||
|
||||
func (m *Matcher) matchStonks() []*store.Match {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
defer cancel()
|
||||
var allMatches []*store.Match
|
||||
|
||||
for _, stonk := range m.stonks {
|
||||
// Run the matching process
|
||||
orders, _ := m.orderP.GetOrders(m.ctx, stonk, nil)
|
||||
orders, err := m.orderP.GetOrders(ctx, stonk, nil)
|
||||
if err != nil {
|
||||
m.l.Error("matcher run failed")
|
||||
return nil
|
||||
}
|
||||
|
||||
// sort in ascending order w.r.t. time
|
||||
sort.Slice(orders, func(i, j int) bool {
|
||||
return orders[i].Time.Before(orders[j].Time)
|
||||
@ -96,25 +106,41 @@ func (m *Matcher) matchStonks() []*store.Match {
|
||||
buyOrders = append(buyOrders, o)
|
||||
}
|
||||
}
|
||||
|
||||
m.l.Debug("got order",
|
||||
zap.Int("len", len(orders)),
|
||||
zap.Int("buy_len", len(buyOrders)),
|
||||
zap.Int("sell_len", len(sellOrders)),
|
||||
)
|
||||
|
||||
// sort sell price low-high
|
||||
sort.Slice(sellOrders, func(i, j int) bool {
|
||||
return orders[i].Price < orders[j].Price
|
||||
})
|
||||
// sort buy price high-low
|
||||
sort.Slice(buyOrders, func(i, j int) bool {
|
||||
return orders[i].Price > orders[j].Price
|
||||
})
|
||||
m.l.Debug("11", zap.Int("len_matches", len(allMatches)))
|
||||
|
||||
for _, sellOrder := range sellOrders {
|
||||
if len(buyOrders) == 0 || sellOrder.Price > buyOrders[0].Price {
|
||||
// no possible match
|
||||
break
|
||||
}
|
||||
|
||||
qty := sellOrder.Quantity
|
||||
|
||||
// sort buy price high-low
|
||||
sort.Slice(buyOrders, func(i, j int) bool {
|
||||
return orders[i].Price > orders[j].Price
|
||||
})
|
||||
m.l.Debug("23", zap.Int("len_matches", len(allMatches)))
|
||||
// if len(buyOrders) == 0 || sellOrder.Price > buyOrders[0].Price {
|
||||
// // no possible match
|
||||
// m.l.Info("skipping further checks")
|
||||
// break
|
||||
// }
|
||||
m.l.Debug("42", zap.Int("len_matches", len(allMatches)))
|
||||
|
||||
qty := sellOrder.Quantity
|
||||
newBuyOrders := make([]*store.Order, 0, len(buyOrders))
|
||||
m.l.Debug("69", zap.Int("len_matches", len(allMatches)))
|
||||
for _, buyOrder := range buyOrders {
|
||||
m.l.Debug("180", zap.Int("len_matches", len(allMatches)))
|
||||
match := &store.Match{
|
||||
Id: uuid.New().String(),
|
||||
Stonk: sellOrder.Stonk,
|
||||
@ -124,6 +150,8 @@ func (m *Matcher) matchStonks() []*store.Match {
|
||||
Quantity: min(qty, buyOrder.Quantity),
|
||||
}
|
||||
allMatches = append(allMatches, match)
|
||||
m.l.Debug("added new match", zap.Int("len_matches", len(allMatches)))
|
||||
|
||||
m.matchP.AddMatch(m.ctx, match)
|
||||
|
||||
qty -= buyOrder.Quantity
|
||||
@ -172,5 +200,7 @@ func (m *Matcher) matchStonks() []*store.Match {
|
||||
}
|
||||
}
|
||||
|
||||
m.l.Debug("finished matchin", zap.Int("len_matches", len(allMatches)))
|
||||
|
||||
return allMatches
|
||||
}
|
||||
|
||||
@ -315,13 +315,16 @@ func (s *StonksService) GetStonkInfo(w http.ResponseWriter, r *http.Request, sto
|
||||
// update the prices before we retrieve them
|
||||
updated := s.update()
|
||||
if updated {
|
||||
state := State{
|
||||
Start: nil,
|
||||
Reload: true,
|
||||
Finish: nil,
|
||||
}
|
||||
go func() {
|
||||
time.Sleep(time.Millisecond * 500)
|
||||
state := State{
|
||||
Start: nil,
|
||||
Reload: true,
|
||||
Finish: nil,
|
||||
}
|
||||
|
||||
s.sseCh <- state
|
||||
s.sseCh <- state
|
||||
}()
|
||||
}
|
||||
|
||||
ts, ok := s.prices[stonk]
|
||||
|
||||
@ -3,7 +3,6 @@ package stonks
|
||||
type StonkName string
|
||||
|
||||
const (
|
||||
stonkEmpty StonkName = "" // INVALID!
|
||||
StonkPaperClip StonkName = "paperClip"
|
||||
StonkScissors StonkName = "scissors"
|
||||
StonkPencil StonkName = "pencil"
|
||||
|
||||
@ -11,6 +11,8 @@ import (
|
||||
)
|
||||
|
||||
func (s *StonksService) update() bool {
|
||||
s.l.Debug("initiating update")
|
||||
defer s.l.Debug("finished update")
|
||||
// drain the updates chanel until it is empty
|
||||
updated := false
|
||||
for {
|
||||
@ -29,17 +31,18 @@ func (s *StonksService) update() bool {
|
||||
Time: time,
|
||||
Value: value,
|
||||
})
|
||||
s.l.Warn("newest timestamp", zap.Int("ts", time))
|
||||
}
|
||||
|
||||
// Add a new entry to the users NetWorthTimeSeries-DataPoints
|
||||
for userId, user := range s.activeUsers {
|
||||
user.mu.Lock()
|
||||
//user.mu.Lock()
|
||||
user.NetWorthTimeSeries = append(user.NetWorthTimeSeries, DataPoint{
|
||||
Time: user.NetWorthTimeSeries.LatestTime() + 1,
|
||||
Value: user.NetWorthTimeSeries.LatestValue(),
|
||||
})
|
||||
s.activeUsers[userId] = user
|
||||
user.mu.Unlock()
|
||||
//user.mu.Unlock()
|
||||
}
|
||||
|
||||
// update the value to the actual new on if there is a match for this stock
|
||||
@ -51,7 +54,7 @@ func (s *StonksService) update() bool {
|
||||
|
||||
// update the users stock position
|
||||
for userId, user := range s.activeUsers {
|
||||
user.mu.Lock()
|
||||
//user.mu.Lock()
|
||||
if userId == match.BuyOrder.User.ID { // if buyer
|
||||
user.Stonks[stonkName] += match.Quantity
|
||||
user.ReservedStonks[stonkName] -= match.Quantity
|
||||
@ -61,7 +64,7 @@ func (s *StonksService) update() bool {
|
||||
user.Stonks[stonkName] -= match.Quantity
|
||||
user.Money += float64(match.Quantity) * match.SellOrder.Price
|
||||
} else {
|
||||
user.mu.Unlock()
|
||||
//user.mu.Unlock()
|
||||
continue
|
||||
}
|
||||
|
||||
@ -75,7 +78,7 @@ func (s *StonksService) update() bool {
|
||||
user.NetWorthTimeSeries[len(user.NetWorthTimeSeries)-1].Value = user.NetWorth
|
||||
|
||||
s.activeUsers[userId] = user
|
||||
user.mu.Unlock()
|
||||
//user.mu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -39,11 +39,13 @@ func (p *MemoryMatchPersistor) GetMatches(ctx context.Context, stonk string) ([]
|
||||
filter := bson.D{}
|
||||
if stonk != "" {
|
||||
filter = append(filter, bson.E{Key: "stonk", Value: string(stonk)})
|
||||
} else {
|
||||
filter = append(filter, bson.E{})
|
||||
}
|
||||
|
||||
cur, err := p.col.Find(ctx, filter)
|
||||
if errors.Is(err, mongo.ErrNoDocuments) {
|
||||
return []*Match{}, nil
|
||||
return nil, mongo.ErrNoDocuments
|
||||
} else if err != nil {
|
||||
p.l.Error("Unable to find matches", zap.Error(err))
|
||||
}
|
||||
|
||||
@ -183,7 +183,7 @@ export const vanillaStore = vanillaCreate<StonksState & StonksModifiers>(
|
||||
}
|
||||
|
||||
// filter out empty infos
|
||||
resp = resp.filter((r) => r.ret.Name !== "");
|
||||
//resp = resp.filter((r) => r.ret.Name !== "");
|
||||
|
||||
set({
|
||||
stonkInfos: resp.map((resp) => {
|
||||
|
||||
@ -55,7 +55,6 @@ export enum StonkName {
|
||||
StonkPaperClip = "paperClip",
|
||||
StonkPencil = "pencil",
|
||||
StonkScissors = "scissors",
|
||||
StonkEmpty = "",
|
||||
}
|
||||
// github.com/hackaTUM/GameOfStonks/services/stonks.UpdateOrderCmd
|
||||
export interface UpdateOrderCmd {
|
||||
|
||||
@ -55,7 +55,7 @@ function Search() {
|
||||
<Card>
|
||||
<StonkPositionList
|
||||
stonks={Object.values(StonkName)
|
||||
.filter((val) => val.valueOf().includes(query) && val !== "")
|
||||
//.filter((val) => val.valueOf().includes(query) && val !== "")
|
||||
.reduce((acc, entry) => {
|
||||
acc[entry] = -1;
|
||||
return acc;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user