diff --git a/stock/generate.go b/stock/generate.go index 96f431a..7d9db91 100644 --- a/stock/generate.go +++ b/stock/generate.go @@ -1,2 +1,3 @@ package main + //go:generate make proto diff --git a/stock/handler/stock.go b/stock/handler/stock.go index cc91c5d..bb11705 100644 --- a/stock/handler/stock.go +++ b/stock/handler/stock.go @@ -25,6 +25,20 @@ type Stock struct { Cache *cache.Cache } +type OrderBook struct { + Symbol string + Results []*Order +} + +type Order struct { + Symbol string + Ask float64 + Bid float64 + Asize int32 + Bsize int32 + T int64 +} + type Quote struct { Symbol string Ask float64 @@ -44,6 +58,63 @@ type History struct { From string } +func (s *Stock) OrderBook(ctx context.Context, req *pb.OrderBookRequest, rsp *pb.OrderBookResponse) error { + if len(req.Stock) <= 0 || len(req.Stock) > 5 { + return errors.BadRequest("stock.orderbook", "invalid symbol") + } + if len(req.Date) == 0 { + return errors.BadRequest("stock.orderbook", "missing date") + } + if req.Limit <= 0 { + req.Limit = 25 + } + + uri := fmt.Sprintf("%shistory/stock/all?apikey=%s&stock=%s&date=%s&limit=%d", s.Api, s.Key, req.Stock, req.Date, req.Limit) + + if req.Start > 0 { + uri = fmt.Sprintf("%s&ts=%d", uri, req.Start) + } + if req.End > 0 { + uri = fmt.Sprintf("%s&te=%d", uri, req.End) + } + + resp, err := http.Get(uri) + if err != nil { + logger.Errorf("Failed to get orderbook: %v\n", err) + return errors.InternalServerError("stock.orderbook", "failed to get orderbook") + } + defer resp.Body.Close() + + b, _ := ioutil.ReadAll(resp.Body) + + if resp.StatusCode != 200 { + logger.Errorf("Failed to get orderbook (non 200): %d %v\n", resp.StatusCode, string(b)) + return errors.InternalServerError("stock.orderbook", "failed to get orderbook") + } + + var respBody OrderBook + + if err := json.Unmarshal(b, &respBody); err != nil { + logger.Errorf("Failed to unmarshal orderbook: %v\n", err) + return errors.InternalServerError("stock.orderbook", "failed to get orderbook") + } + + rsp.Symbol = respBody.Symbol + rsp.Date = req.Date + + for _, result := range respBody.Results { + rsp.Orders = append(rsp.Orders, &pb.Order{ + AskPrice: result.Ask, + BidPrice: result.Bid, + AskSize: result.Asize, + BidSize: result.Bsize, + Timestamp: time.Unix(0, result.T).UTC().Format(time.RFC3339Nano), + }) + } + + return nil +} + func (s *Stock) History(ctx context.Context, req *pb.HistoryRequest, rsp *pb.HistoryResponse) error { if len(req.Stock) <= 0 || len(req.Stock) > 5 { return errors.BadRequest("stock.history", "invalid symbol") @@ -85,6 +156,7 @@ func (s *Stock) History(ctx context.Context, req *pb.HistoryRequest, rsp *pb.His rsp.Volume = respBody.Volume return nil } + func (s *Stock) Quote(ctx context.Context, req *pb.QuoteRequest, rsp *pb.QuoteResponse) error { if len(req.Symbol) <= 0 || len(req.Symbol) > 5 { return errors.BadRequest("stock.quote", "invalid symbol") diff --git a/stock/main.go b/stock/main.go index c3cad65..82070c7 100644 --- a/stock/main.go +++ b/stock/main.go @@ -6,10 +6,10 @@ import ( "github.com/micro/services/stock/handler" pb "github.com/micro/services/stock/proto" - "github.com/patrickmn/go-cache" "github.com/micro/micro/v3/service" "github.com/micro/micro/v3/service/config" "github.com/micro/micro/v3/service/logger" + "github.com/patrickmn/go-cache" ) func main() { @@ -19,29 +19,29 @@ func main() { service.Version("latest"), ) - v, err := config.Get("finage.api") - if err != nil { - logger.Fatalf("finage.api config not found: %v", err) - } - api := v.String("") - if len(api) == 0 { - logger.Fatal("finage.api config not found") - } - v, err = config.Get("finage.key") - if err != nil { - logger.Fatalf("finage.key config not found: %v", err) - } - key := v.String("") - if len(key) == 0 { - logger.Fatal("finage.key config not found") - } + v, err := config.Get("finage.api") + if err != nil { + logger.Fatalf("finage.api config not found: %v", err) + } + api := v.String("") + if len(api) == 0 { + logger.Fatal("finage.api config not found") + } + v, err = config.Get("finage.key") + if err != nil { + logger.Fatalf("finage.key config not found: %v", err) + } + key := v.String("") + if len(key) == 0 { + logger.Fatal("finage.key config not found") + } - // Register handler - pb.RegisterStockHandler(srv.Server(), &handler.Stock{ - Api: api, - Key: key, + // Register handler + pb.RegisterStockHandler(srv.Server(), &handler.Stock{ + Api: api, + Key: key, Cache: cache.New(5*time.Minute, 10*time.Minute), - }) + }) // Run service if err := srv.Run(); err != nil { diff --git a/stock/proto/stock.pb.go b/stock/proto/stock.pb.go index 3e7cdbc..eafd7f5 100644 --- a/stock/proto/stock.pb.go +++ b/stock/proto/stock.pb.go @@ -20,6 +20,241 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type Order struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the asking price + AskPrice float64 `protobuf:"fixed64,2,opt,name=ask_price,json=askPrice,proto3" json:"ask_price,omitempty"` + // the bidding price + BidPrice float64 `protobuf:"fixed64,3,opt,name=bid_price,json=bidPrice,proto3" json:"bid_price,omitempty"` + // the ask size + AskSize int32 `protobuf:"varint,4,opt,name=ask_size,json=askSize,proto3" json:"ask_size,omitempty"` + // the bid size + BidSize int32 `protobuf:"varint,5,opt,name=bid_size,json=bidSize,proto3" json:"bid_size,omitempty"` + // the UTC timestamp of the quote + Timestamp string `protobuf:"bytes,6,opt,name=timestamp,proto3" json:"timestamp,omitempty"` +} + +func (x *Order) Reset() { + *x = Order{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_stock_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Order) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Order) ProtoMessage() {} + +func (x *Order) ProtoReflect() protoreflect.Message { + mi := &file_proto_stock_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Order.ProtoReflect.Descriptor instead. +func (*Order) Descriptor() ([]byte, []int) { + return file_proto_stock_proto_rawDescGZIP(), []int{0} +} + +func (x *Order) GetAskPrice() float64 { + if x != nil { + return x.AskPrice + } + return 0 +} + +func (x *Order) GetBidPrice() float64 { + if x != nil { + return x.BidPrice + } + return 0 +} + +func (x *Order) GetAskSize() int32 { + if x != nil { + return x.AskSize + } + return 0 +} + +func (x *Order) GetBidSize() int32 { + if x != nil { + return x.BidSize + } + return 0 +} + +func (x *Order) GetTimestamp() string { + if x != nil { + return x.Timestamp + } + return "" +} + +// Get the historic order book and each trade by timestamp +type OrderBookRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // stock to retrieve e.g AAPL + Stock string `protobuf:"bytes,1,opt,name=stock,proto3" json:"stock,omitempty"` + // the date in format YYYY-MM-dd + Date string `protobuf:"bytes,2,opt,name=date,proto3" json:"date,omitempty"` + // optional nanosecond timestamp start + Start int64 `protobuf:"varint,3,opt,name=start,proto3" json:"start,omitempty"` + // optional nanosecond timestamp end + End int64 `protobuf:"varint,4,opt,name=end,proto3" json:"end,omitempty"` + // limit number of prices + Limit int32 `protobuf:"varint,5,opt,name=limit,proto3" json:"limit,omitempty"` +} + +func (x *OrderBookRequest) Reset() { + *x = OrderBookRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_stock_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OrderBookRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OrderBookRequest) ProtoMessage() {} + +func (x *OrderBookRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_stock_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OrderBookRequest.ProtoReflect.Descriptor instead. +func (*OrderBookRequest) Descriptor() ([]byte, []int) { + return file_proto_stock_proto_rawDescGZIP(), []int{1} +} + +func (x *OrderBookRequest) GetStock() string { + if x != nil { + return x.Stock + } + return "" +} + +func (x *OrderBookRequest) GetDate() string { + if x != nil { + return x.Date + } + return "" +} + +func (x *OrderBookRequest) GetStart() int64 { + if x != nil { + return x.Start + } + return 0 +} + +func (x *OrderBookRequest) GetEnd() int64 { + if x != nil { + return x.End + } + return 0 +} + +func (x *OrderBookRequest) GetLimit() int32 { + if x != nil { + return x.Limit + } + return 0 +} + +type OrderBookResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the stock symbol + Symbol string `protobuf:"bytes,1,opt,name=symbol,proto3" json:"symbol,omitempty"` + // date of the request + Date string `protobuf:"bytes,2,opt,name=date,proto3" json:"date,omitempty"` + // list of orders + Orders []*Order `protobuf:"bytes,3,rep,name=orders,proto3" json:"orders,omitempty"` +} + +func (x *OrderBookResponse) Reset() { + *x = OrderBookResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_stock_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OrderBookResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OrderBookResponse) ProtoMessage() {} + +func (x *OrderBookResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_stock_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OrderBookResponse.ProtoReflect.Descriptor instead. +func (*OrderBookResponse) Descriptor() ([]byte, []int) { + return file_proto_stock_proto_rawDescGZIP(), []int{2} +} + +func (x *OrderBookResponse) GetSymbol() string { + if x != nil { + return x.Symbol + } + return "" +} + +func (x *OrderBookResponse) GetDate() string { + if x != nil { + return x.Date + } + return "" +} + +func (x *OrderBookResponse) GetOrders() []*Order { + if x != nil { + return x.Orders + } + return nil +} + // Get the last price for a given stock ticker type PriceRequest struct { state protoimpl.MessageState @@ -33,7 +268,7 @@ type PriceRequest struct { func (x *PriceRequest) Reset() { *x = PriceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_proto_stock_proto_msgTypes[0] + mi := &file_proto_stock_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -46,7 +281,7 @@ func (x *PriceRequest) String() string { func (*PriceRequest) ProtoMessage() {} func (x *PriceRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_stock_proto_msgTypes[0] + mi := &file_proto_stock_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -59,7 +294,7 @@ func (x *PriceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PriceRequest.ProtoReflect.Descriptor instead. func (*PriceRequest) Descriptor() ([]byte, []int) { - return file_proto_stock_proto_rawDescGZIP(), []int{0} + return file_proto_stock_proto_rawDescGZIP(), []int{3} } func (x *PriceRequest) GetSymbol() string { @@ -83,7 +318,7 @@ type PriceResponse struct { func (x *PriceResponse) Reset() { *x = PriceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_proto_stock_proto_msgTypes[1] + mi := &file_proto_stock_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -96,7 +331,7 @@ func (x *PriceResponse) String() string { func (*PriceResponse) ProtoMessage() {} func (x *PriceResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_stock_proto_msgTypes[1] + mi := &file_proto_stock_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -109,7 +344,7 @@ func (x *PriceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PriceResponse.ProtoReflect.Descriptor instead. func (*PriceResponse) Descriptor() ([]byte, []int) { - return file_proto_stock_proto_rawDescGZIP(), []int{1} + return file_proto_stock_proto_rawDescGZIP(), []int{4} } func (x *PriceResponse) GetSymbol() string { @@ -139,7 +374,7 @@ type QuoteRequest struct { func (x *QuoteRequest) Reset() { *x = QuoteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_proto_stock_proto_msgTypes[2] + mi := &file_proto_stock_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -152,7 +387,7 @@ func (x *QuoteRequest) String() string { func (*QuoteRequest) ProtoMessage() {} func (x *QuoteRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_stock_proto_msgTypes[2] + mi := &file_proto_stock_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -165,7 +400,7 @@ func (x *QuoteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use QuoteRequest.ProtoReflect.Descriptor instead. func (*QuoteRequest) Descriptor() ([]byte, []int) { - return file_proto_stock_proto_rawDescGZIP(), []int{2} + return file_proto_stock_proto_rawDescGZIP(), []int{5} } func (x *QuoteRequest) GetSymbol() string { @@ -197,7 +432,7 @@ type QuoteResponse struct { func (x *QuoteResponse) Reset() { *x = QuoteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_proto_stock_proto_msgTypes[3] + mi := &file_proto_stock_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -210,7 +445,7 @@ func (x *QuoteResponse) String() string { func (*QuoteResponse) ProtoMessage() {} func (x *QuoteResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_stock_proto_msgTypes[3] + mi := &file_proto_stock_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -223,7 +458,7 @@ func (x *QuoteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use QuoteResponse.ProtoReflect.Descriptor instead. func (*QuoteResponse) Descriptor() ([]byte, []int) { - return file_proto_stock_proto_rawDescGZIP(), []int{3} + return file_proto_stock_proto_rawDescGZIP(), []int{6} } func (x *QuoteResponse) GetSymbol() string { @@ -283,7 +518,7 @@ type HistoryRequest struct { func (x *HistoryRequest) Reset() { *x = HistoryRequest{} if protoimpl.UnsafeEnabled { - mi := &file_proto_stock_proto_msgTypes[4] + mi := &file_proto_stock_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -296,7 +531,7 @@ func (x *HistoryRequest) String() string { func (*HistoryRequest) ProtoMessage() {} func (x *HistoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_stock_proto_msgTypes[4] + mi := &file_proto_stock_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -309,7 +544,7 @@ func (x *HistoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use HistoryRequest.ProtoReflect.Descriptor instead. func (*HistoryRequest) Descriptor() ([]byte, []int) { - return file_proto_stock_proto_rawDescGZIP(), []int{4} + return file_proto_stock_proto_rawDescGZIP(), []int{7} } func (x *HistoryRequest) GetStock() string { @@ -350,7 +585,7 @@ type HistoryResponse struct { func (x *HistoryResponse) Reset() { *x = HistoryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_proto_stock_proto_msgTypes[5] + mi := &file_proto_stock_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -363,7 +598,7 @@ func (x *HistoryResponse) String() string { func (*HistoryResponse) ProtoMessage() {} func (x *HistoryResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_stock_proto_msgTypes[5] + mi := &file_proto_stock_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -376,7 +611,7 @@ func (x *HistoryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use HistoryResponse.ProtoReflect.Descriptor instead. func (*HistoryResponse) Descriptor() ([]byte, []int) { - return file_proto_stock_proto_rawDescGZIP(), []int{5} + return file_proto_stock_proto_rawDescGZIP(), []int{8} } func (x *HistoryResponse) GetSymbol() string { @@ -432,54 +667,82 @@ var File_proto_stock_proto protoreflect.FileDescriptor var file_proto_stock_proto_rawDesc = []byte{ 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x22, 0x26, 0x0a, 0x0c, 0x50, 0x72, - 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, - 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, - 0x6f, 0x6c, 0x22, 0x3d, 0x0a, 0x0d, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x22, 0x95, 0x01, 0x0a, 0x05, 0x4f, + 0x72, 0x64, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x73, 0x6b, 0x5f, 0x70, 0x72, 0x69, 0x63, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x61, 0x73, 0x6b, 0x50, 0x72, 0x69, 0x63, + 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x69, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x62, 0x69, 0x64, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x19, + 0x0a, 0x08, 0x61, 0x73, 0x6b, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x07, 0x61, 0x73, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x69, 0x64, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x62, 0x69, 0x64, + 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x22, 0x7a, 0x0a, 0x10, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x12, 0x12, 0x0a, 0x04, + 0x64, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x65, + 0x0a, 0x11, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x70, - 0x72, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, - 0x65, 0x22, 0x26, 0x0a, 0x0c, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x22, 0xb5, 0x01, 0x0a, 0x0d, 0x51, 0x75, - 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, - 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, - 0x62, 0x6f, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x73, 0x6b, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x61, 0x73, 0x6b, 0x50, 0x72, 0x69, 0x63, 0x65, - 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x69, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x01, 0x52, 0x08, 0x62, 0x69, 0x64, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x19, 0x0a, - 0x08, 0x61, 0x73, 0x6b, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x07, 0x61, 0x73, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x69, 0x64, 0x5f, - 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x62, 0x69, 0x64, 0x53, - 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x22, 0x3a, 0x0a, 0x0e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, 0x22, 0xa5, 0x01, - 0x0a, 0x0f, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6f, 0x70, 0x65, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x12, 0x14, 0x0a, - 0x05, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x63, 0x6c, - 0x6f, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x67, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x01, 0x52, 0x04, 0x68, 0x69, 0x67, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x77, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x6c, 0x6f, 0x77, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x6f, 0x6c, - 0x75, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x76, 0x6f, 0x6c, 0x75, 0x6d, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x64, 0x61, 0x74, 0x65, 0x32, 0xaf, 0x01, 0x0a, 0x05, 0x53, 0x74, 0x6f, 0x63, 0x6b, 0x12, - 0x34, 0x0a, 0x05, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x73, 0x74, 0x6f, 0x63, 0x6b, - 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, - 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x13, - 0x2e, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x2e, 0x50, 0x72, 0x69, 0x63, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x07, 0x48, - 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x15, 0x2e, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x2e, 0x48, - 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, - 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x0f, 0x5a, 0x0d, 0x2e, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x3b, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, 0x12, + 0x24, 0x0a, 0x06, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0c, 0x2e, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x06, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x73, 0x22, 0x26, 0x0a, 0x0c, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x22, 0x3d, 0x0a, + 0x0d, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x22, 0x26, 0x0a, 0x0c, + 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, + 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, + 0x6d, 0x62, 0x6f, 0x6c, 0x22, 0xb5, 0x01, 0x0a, 0x0d, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x1b, + 0x0a, 0x09, 0x61, 0x73, 0x6b, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x01, 0x52, 0x08, 0x61, 0x73, 0x6b, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, + 0x69, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, + 0x62, 0x69, 0x64, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x73, 0x6b, 0x5f, + 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x61, 0x73, 0x6b, 0x53, + 0x69, 0x7a, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x69, 0x64, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x62, 0x69, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, + 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3a, 0x0a, 0x0e, + 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, + 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, + 0x74, 0x6f, 0x63, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x0f, 0x48, 0x69, 0x73, + 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, + 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x01, 0x52, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6c, 0x6f, 0x73, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x68, 0x69, 0x67, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x68, 0x69, + 0x67, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x77, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, + 0x03, 0x6c, 0x6f, 0x77, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x64, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, + 0x32, 0xf1, 0x01, 0x0a, 0x05, 0x53, 0x74, 0x6f, 0x63, 0x6b, 0x12, 0x34, 0x0a, 0x05, 0x51, 0x75, + 0x6f, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x2e, 0x51, 0x75, 0x6f, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x73, 0x74, 0x6f, 0x63, 0x6b, + 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x34, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x13, 0x2e, 0x73, 0x74, 0x6f, 0x63, + 0x6b, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, + 0x2e, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x2e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x07, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, + 0x79, 0x12, 0x15, 0x2e, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x73, 0x74, 0x6f, 0x63, 0x6b, + 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x40, 0x0a, 0x09, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x12, + 0x17, 0x2e, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x6f, 0x6f, + 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x73, 0x74, 0x6f, 0x63, 0x6b, + 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x42, 0x0f, 0x5a, 0x0d, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, + 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -494,27 +757,33 @@ func file_proto_stock_proto_rawDescGZIP() []byte { return file_proto_stock_proto_rawDescData } -var file_proto_stock_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_proto_stock_proto_msgTypes = make([]protoimpl.MessageInfo, 9) var file_proto_stock_proto_goTypes = []interface{}{ - (*PriceRequest)(nil), // 0: stock.PriceRequest - (*PriceResponse)(nil), // 1: stock.PriceResponse - (*QuoteRequest)(nil), // 2: stock.QuoteRequest - (*QuoteResponse)(nil), // 3: stock.QuoteResponse - (*HistoryRequest)(nil), // 4: stock.HistoryRequest - (*HistoryResponse)(nil), // 5: stock.HistoryResponse + (*Order)(nil), // 0: stock.Order + (*OrderBookRequest)(nil), // 1: stock.OrderBookRequest + (*OrderBookResponse)(nil), // 2: stock.OrderBookResponse + (*PriceRequest)(nil), // 3: stock.PriceRequest + (*PriceResponse)(nil), // 4: stock.PriceResponse + (*QuoteRequest)(nil), // 5: stock.QuoteRequest + (*QuoteResponse)(nil), // 6: stock.QuoteResponse + (*HistoryRequest)(nil), // 7: stock.HistoryRequest + (*HistoryResponse)(nil), // 8: stock.HistoryResponse } var file_proto_stock_proto_depIdxs = []int32{ - 2, // 0: stock.Stock.Quote:input_type -> stock.QuoteRequest - 0, // 1: stock.Stock.Price:input_type -> stock.PriceRequest - 4, // 2: stock.Stock.History:input_type -> stock.HistoryRequest - 3, // 3: stock.Stock.Quote:output_type -> stock.QuoteResponse - 1, // 4: stock.Stock.Price:output_type -> stock.PriceResponse - 5, // 5: stock.Stock.History:output_type -> stock.HistoryResponse - 3, // [3:6] is the sub-list for method output_type - 0, // [0:3] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 0, // 0: stock.OrderBookResponse.orders:type_name -> stock.Order + 5, // 1: stock.Stock.Quote:input_type -> stock.QuoteRequest + 3, // 2: stock.Stock.Price:input_type -> stock.PriceRequest + 7, // 3: stock.Stock.History:input_type -> stock.HistoryRequest + 1, // 4: stock.Stock.OrderBook:input_type -> stock.OrderBookRequest + 6, // 5: stock.Stock.Quote:output_type -> stock.QuoteResponse + 4, // 6: stock.Stock.Price:output_type -> stock.PriceResponse + 8, // 7: stock.Stock.History:output_type -> stock.HistoryResponse + 2, // 8: stock.Stock.OrderBook:output_type -> stock.OrderBookResponse + 5, // [5:9] is the sub-list for method output_type + 1, // [1:5] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name } func init() { file_proto_stock_proto_init() } @@ -524,7 +793,7 @@ func file_proto_stock_proto_init() { } if !protoimpl.UnsafeEnabled { file_proto_stock_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PriceRequest); i { + switch v := v.(*Order); i { case 0: return &v.state case 1: @@ -536,7 +805,7 @@ func file_proto_stock_proto_init() { } } file_proto_stock_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PriceResponse); i { + switch v := v.(*OrderBookRequest); i { case 0: return &v.state case 1: @@ -548,7 +817,7 @@ func file_proto_stock_proto_init() { } } file_proto_stock_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QuoteRequest); i { + switch v := v.(*OrderBookResponse); i { case 0: return &v.state case 1: @@ -560,7 +829,7 @@ func file_proto_stock_proto_init() { } } file_proto_stock_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QuoteResponse); i { + switch v := v.(*PriceRequest); i { case 0: return &v.state case 1: @@ -572,7 +841,7 @@ func file_proto_stock_proto_init() { } } file_proto_stock_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HistoryRequest); i { + switch v := v.(*PriceResponse); i { case 0: return &v.state case 1: @@ -584,6 +853,42 @@ func file_proto_stock_proto_init() { } } file_proto_stock_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QuoteRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_stock_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QuoteResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_stock_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HistoryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_stock_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HistoryResponse); i { case 0: return &v.state @@ -602,7 +907,7 @@ func file_proto_stock_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_stock_proto_rawDesc, NumEnums: 0, - NumMessages: 6, + NumMessages: 9, NumExtensions: 0, NumServices: 1, }, diff --git a/stock/proto/stock.pb.micro.go b/stock/proto/stock.pb.micro.go index 0f238f0..73a5837 100644 --- a/stock/proto/stock.pb.micro.go +++ b/stock/proto/stock.pb.micro.go @@ -45,6 +45,7 @@ type StockService interface { Quote(ctx context.Context, in *QuoteRequest, opts ...client.CallOption) (*QuoteResponse, error) Price(ctx context.Context, in *PriceRequest, opts ...client.CallOption) (*PriceResponse, error) History(ctx context.Context, in *HistoryRequest, opts ...client.CallOption) (*HistoryResponse, error) + OrderBook(ctx context.Context, in *OrderBookRequest, opts ...client.CallOption) (*OrderBookResponse, error) } type stockService struct { @@ -89,12 +90,23 @@ func (c *stockService) History(ctx context.Context, in *HistoryRequest, opts ... return out, nil } +func (c *stockService) OrderBook(ctx context.Context, in *OrderBookRequest, opts ...client.CallOption) (*OrderBookResponse, error) { + req := c.c.NewRequest(c.name, "Stock.OrderBook", in) + out := new(OrderBookResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for Stock service type StockHandler interface { Quote(context.Context, *QuoteRequest, *QuoteResponse) error Price(context.Context, *PriceRequest, *PriceResponse) error History(context.Context, *HistoryRequest, *HistoryResponse) error + OrderBook(context.Context, *OrderBookRequest, *OrderBookResponse) error } func RegisterStockHandler(s server.Server, hdlr StockHandler, opts ...server.HandlerOption) error { @@ -102,6 +114,7 @@ func RegisterStockHandler(s server.Server, hdlr StockHandler, opts ...server.Han Quote(ctx context.Context, in *QuoteRequest, out *QuoteResponse) error Price(ctx context.Context, in *PriceRequest, out *PriceResponse) error History(ctx context.Context, in *HistoryRequest, out *HistoryResponse) error + OrderBook(ctx context.Context, in *OrderBookRequest, out *OrderBookResponse) error } type Stock struct { stock @@ -125,3 +138,7 @@ func (h *stockHandler) Price(ctx context.Context, in *PriceRequest, out *PriceRe func (h *stockHandler) History(ctx context.Context, in *HistoryRequest, out *HistoryResponse) error { return h.StockHandler.History(ctx, in, out) } + +func (h *stockHandler) OrderBook(ctx context.Context, in *OrderBookRequest, out *OrderBookResponse) error { + return h.StockHandler.OrderBook(ctx, in, out) +} diff --git a/stock/proto/stock.proto b/stock/proto/stock.proto index 7cacdd4..30ec6aa 100644 --- a/stock/proto/stock.proto +++ b/stock/proto/stock.proto @@ -8,6 +8,43 @@ service Stock { rpc Quote(QuoteRequest) returns (QuoteResponse) {} rpc Price(PriceRequest) returns (PriceResponse) {} rpc History(HistoryRequest) returns (HistoryResponse) {} + rpc OrderBook(OrderBookRequest) returns (OrderBookResponse) {} +} + +message Order { + // the asking price + double ask_price = 2; + // the bidding price + double bid_price = 3; + // the ask size + int32 ask_size = 4; + // the bid size + int32 bid_size = 5; + // the UTC timestamp of the quote + string timestamp = 6; +} + +// Get the historic order book and each trade by timestamp +message OrderBookRequest { + // stock to retrieve e.g AAPL + string stock = 1; + // the date in format YYYY-MM-dd + string date = 2; + // optional nanosecond timestamp start + int64 start = 3; + // optional nanosecond timestamp end + int64 end = 4; + // limit number of prices + int32 limit = 5; +} + +message OrderBookResponse { + // the stock symbol + string symbol = 1; + // date of the request + string date = 2; + // list of orders + repeated Order orders = 3; } // Get the last price for a given stock ticker diff --git a/stock/publicapi.json b/stock/publicapi.json index 3c21b6e..b327c11 100644 --- a/stock/publicapi.json +++ b/stock/publicapi.json @@ -5,6 +5,7 @@ "pricing": { "Stock.Price": 2000, "Stock.Quote": 2000, - "Stock.History": 3500 + "Stock.History": 3500, + "Stock.OrderBook": 3500 } }