order_list.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. package lmaxapi
  2. import "tickserver/api/lmaxapi/response"
  3. import "log"
  4. import "math"
  5. type OrderList struct {
  6. data []*response.OrderEvent
  7. perSymbol map[int64][]*response.OrderEvent
  8. mtf *Mtf
  9. }
  10. func NewOrderList(mtf *Mtf) *OrderList {
  11. list := &OrderList{}
  12. list.mtf = mtf
  13. list.perSymbol = make(map[int64][]*response.OrderEvent)
  14. return list
  15. }
  16. //mtf 中发生了执行,需要更新订单以及 其他的订单
  17. func (list *OrderList) UpdateOrder(event *response.OrderEvent) []*response.OrderEvent {
  18. order := list.get(event)
  19. var matchedQuantity float64
  20. if order == nil {
  21. matchedQuantity = event.FilledQuantity
  22. } else {
  23. matchedQuantity = event.FilledQuantity - order.FilledQuantity
  24. }
  25. //更新openquantify
  26. var updatedOrder []*response.OrderEvent
  27. if item, ok := list.perSymbol[event.InstrumentId]; ok && matchedQuantity != 0 {
  28. for i := 0; i < len(item); i++ {
  29. if item[i].OpenQuantity == 0 || sameSign(item[i].OpenQuantity, event.FilledQuantity) {
  30. continue
  31. }
  32. tmp := *item[i]
  33. updatedOrder = append(updatedOrder, &tmp)
  34. if math.Abs(item[i].OpenQuantity) > math.Abs(matchedQuantity) {
  35. rate := item[i].MatchedCost / item[i].FilledQuantity
  36. item[i].OpenQuantity += matchedQuantity
  37. item[i].OpenCost = rate * item[i].OpenQuantity
  38. matchedQuantity = 0
  39. } else {
  40. matchedQuantity += item[i].OpenQuantity
  41. item[i].OpenQuantity = 0
  42. item[i].OpenCost = 0
  43. }
  44. if matchedQuantity == 0 {
  45. break
  46. }
  47. }
  48. log.Println("event info:", event.MatchedCost, event.FilledQuantity, matchedQuantity)
  49. rate := event.MatchedCost / event.FilledQuantity
  50. event.OpenQuantity += matchedQuantity
  51. event.OpenCost = rate * event.OpenQuantity
  52. }
  53. tmp := *event
  54. updatedOrder = append(updatedOrder, &tmp)
  55. //opencost 更新结束
  56. list.SetOrder(event)
  57. return updatedOrder
  58. }
  59. func (list *OrderList) get(event *response.OrderEvent) *response.OrderEvent {
  60. if item, ok := list.perSymbol[event.InstrumentId]; ok {
  61. for i := 0; i < len(item); i++ {
  62. if item[i].OrderId == event.OrderId {
  63. return item[i]
  64. }
  65. }
  66. }
  67. return nil
  68. }
  69. func (list *OrderList) SetOrder(event *response.OrderEvent) string {
  70. if event.IsStopProft() {
  71. return "stoploss"
  72. }
  73. if item, ok := list.perSymbol[event.InstrumentId]; ok {
  74. for i := 0; i < len(item); i++ {
  75. if item[i].OrderId == event.OrderId {
  76. //对订单的保证金之类的信息进行更新
  77. list.updateOrder(event)
  78. *item[i] = *event
  79. if event.IsClosed() {
  80. log.Println(event.OrderId, "closed")
  81. list.perSymbol[event.InstrumentId] = list.deleteOrder(list.perSymbol[event.InstrumentId], event)
  82. list.data = list.deleteOrder(list.data, event)
  83. return "closed"
  84. }
  85. return "update"
  86. }
  87. }
  88. }
  89. //新增数据
  90. inst := list.mtf.getInstument(event.InstrumentId)
  91. if inst != nil {
  92. event.Currency = inst.Currency
  93. }
  94. list.updateOrder(event)
  95. if event.IsClosed() {
  96. return "closed"
  97. }
  98. list.perSymbol[event.InstrumentId] = append(list.perSymbol[event.InstrumentId], event)
  99. list.data = append(list.data, event)
  100. return "add"
  101. }
  102. func (list *OrderList) deleteOrder(data []*response.OrderEvent, event *response.OrderEvent) []*response.OrderEvent {
  103. for i := 0; i < len(data); i++ {
  104. if data[i].OrderId == event.OrderId {
  105. data = append(data[:i], data[i+1:]...)
  106. return data
  107. }
  108. }
  109. return data
  110. }
  111. // 一些辅助函数
  112. func (list *OrderList) GetOrders(iscopy bool) []*response.OrderEvent {
  113. if !iscopy {
  114. return list.data
  115. }
  116. ret := make([]*response.OrderEvent, len(list.data))
  117. for i := 0; i < len(list.data); i++ {
  118. tmp := *list.data[i]
  119. ret[i] = &tmp
  120. }
  121. return ret
  122. }
  123. //接下来就是updateOne的问题了,我们要根据各种各样的情况来更新订单。
  124. func (list *OrderList) updateWorkingOrder(order *response.OrderEvent, instrument *response.Instrument,
  125. exchangeRate *response.ExchangeRateEvent, priceEvent *response.OrderBookEvent) error {
  126. //价格
  127. ask := priceEvent.AskPrices[0].Price
  128. bid := priceEvent.BidPrices[0].Price
  129. if order.Quantity > 0 {
  130. order.CurPrice = ask
  131. } else {
  132. order.CurPrice = bid
  133. }
  134. dt := order.Quantity - order.FilledQuantity - order.CancelledQuantity
  135. //margin: 实际上有两个部分,一个是已经成交部分的margin/一个是挂单的margin
  136. //因为margin 对整体position有效,所以这里我们不做处理,只计算挂单的margin,对后面的计算有用
  137. margin := order.LimitPrice * instrument.ContractSize * dt * instrument.MarginRate
  138. if margin < 0 {
  139. margin = -margin
  140. }
  141. order.Margin = margin
  142. if order.OpenQuantity == 0 {
  143. order.Profit = 0
  144. return nil
  145. }
  146. //盈利情况,已经开仓部分的盈利,实际上这个没有用,只是为了计算而计算。
  147. openprice := order.OpenCost / (order.OpenQuantity * instrument.ContractSize)
  148. profit := (order.CurPrice - openprice) * instrument.ContractSize * order.OpenQuantity
  149. order.Profit = profit
  150. return nil
  151. }
  152. func (list *OrderList) updateMarketOrder(order *response.OrderEvent, instrument *response.Instrument,
  153. exchangeRate *response.ExchangeRateEvent, priceEvent *response.OrderBookEvent) error {
  154. //margin
  155. order.CurPrice = getPrice(order.Quantity, priceEvent)
  156. cost := order.CurPrice * order.Quantity * instrument.ContractSize
  157. if cost < 0 {
  158. cost = -cost
  159. }
  160. margin := cost * instrument.MarginRate
  161. order.Margin = margin
  162. //profit
  163. if order.OpenQuantity == 0 {
  164. order.Profit = 0
  165. return nil
  166. }
  167. openprice := order.OpenCost / (order.OpenQuantity * instrument.ContractSize)
  168. profit := (order.CurPrice - openprice) * instrument.ContractSize * order.OpenQuantity
  169. order.Profit = profit
  170. return nil
  171. }
  172. func (list *OrderList) updateOrder(order *response.OrderEvent) error {
  173. if order.IsClosed() { //等待删除的对象
  174. return nil
  175. }
  176. instrument, exchangeRate, priceEvent, err := list.mtf.getInstrumentInfo(order.InstrumentId)
  177. if err != nil {
  178. return err
  179. }
  180. //working order
  181. if order.IsWorking() {
  182. err = list.updateWorkingOrder(order, instrument, exchangeRate, priceEvent)
  183. } else {
  184. err = list.updateMarketOrder(order, instrument, exchangeRate, priceEvent)
  185. }
  186. return nil
  187. }
  188. func (list *OrderList) deleteClosed() {
  189. //delete closed order
  190. tmp := list.data[0:0]
  191. for i := 0; i < len(list.data); i++ {
  192. if !list.data[i].IsClosed() {
  193. tmp = append(tmp, list.data[i])
  194. } else {
  195. //删除这个订单
  196. symbol := list.data[i].InstrumentId
  197. data := list.perSymbol[symbol]
  198. for k := 0; k < len(data); k++ {
  199. if data[k] == list.data[i] {
  200. list.perSymbol[symbol] = append(data[:k], data[k+1:]...)
  201. }
  202. }
  203. }
  204. }
  205. list.data = tmp
  206. }
  207. func (list *OrderList) UpdateTick(event *TickEvent) (ret []*response.OrderEvent) {
  208. //do other things
  209. for i := 0; i < len(list.data); i++ {
  210. if list.data[i].InstrumentId == event.ob2.InstrumentId { //货币对匹配
  211. list.updateOrder(list.data[i])
  212. if event.fetchUpdated {
  213. copyed := list.data[i]
  214. if event.isCopy {
  215. tmp := *list.data[i]
  216. copyed = &tmp
  217. }
  218. ret = append(ret, copyed)
  219. }
  220. }
  221. }
  222. return
  223. }
  224. func (list *OrderList) UpdateRate(event *RateEvent) (ret []*response.OrderEvent) {
  225. //do other things
  226. for i := 0; i < len(list.data); i++ {
  227. if list.data[i].Currency == event.erate.From { //货币对匹配
  228. list.updateOrder(list.data[i])
  229. if event.fetchUpdated {
  230. copyed := list.data[i]
  231. if event.isCopy {
  232. tmp := *list.data[i]
  233. copyed = &tmp
  234. }
  235. ret = append(ret, copyed)
  236. }
  237. }
  238. }
  239. return
  240. }
  241. func (list *OrderList) workingOrderMargin(instrumentId int64) (float64, float64) {
  242. buy := 0.0
  243. sell := 0.0
  244. for i := 0; i < len(list.data); i++ {
  245. o := list.data[i]
  246. if o.InstrumentId == instrumentId && o.IsWorking() {
  247. if o.Quantity > 0 {
  248. buy += o.Margin
  249. } else {
  250. sell += o.Margin
  251. }
  252. }
  253. }
  254. return buy, sell
  255. }
  256. func getPrice(qty float64, priceEvent *response.OrderBookEvent) float64 {
  257. ask := priceEvent.AskPrices[0].Price
  258. bid := priceEvent.BidPrices[0].Price
  259. if qty > 0 {
  260. return bid
  261. }
  262. return ask
  263. }