-
Notifications
You must be signed in to change notification settings - Fork 1
/
Trans.go
131 lines (118 loc) · 2.74 KB
/
Trans.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package handy
import (
"testing"
"fmt"
"time"
"math/rand"
)
type AskBid int
type MarketLimit int
const (
Ask AskBid = iota
Bid
)
const (
Market MarketLimit = iota
Limit
)
type Order struct {
AskBid AskBid
MarketLimit MarketLimit
Volume int
Price float64 //used by Market Tran
}
var Orders chan Order
func OrderBinarySearch(array []Order, first, last int, value Order) int {
//deal with Market Order
if value.MarketLimit == Market {
if value.AskBid == Ask {
return 0
}
if value.AskBid == Bid {
return last
}
}
for first < last {
mid := first + (last-first)/2
if array[mid].Price < value.Price {
first = mid + 1
} else {
last = mid
}
}
return first
}
func InsertOrder(orders []Order, order Order) []Order {
i := OrderBinarySearch(orders, 0, len(orders), order)
orders = append(orders, Order{})
copy(orders[i+1:], orders[i:])
orders[i] = order
return orders
}
func BrokerMainLoop() {
Asks := make([]Order, 0)
Bids := make([]Order, 0)
for {
select {
case order := <-Orders:
switch order.AskBid {
case Ask:
Asks = InsertOrder(Asks, order)
case Bid:
Bids = InsertOrder(Bids, order)
}
}
//trade off the Asks and Bids
//fmt.Println(len(Asks), len(Bids), len(Orders))
for len(Asks) > 0 && len(Bids) > 0 &&
(Asks[0].Price <= Bids[len(Bids)-1].Price ||
Asks[0].MarketLimit == Market ||
Bids[len(Bids)-1].MarketLimit == Market) {
if Asks[0].Volume < Bids[len(Bids)-1].Volume {
Bids[len(Bids)-1].Volume = Bids[len(Bids)-1].Volume - Asks[0].Volume
fmt.Println("Deal!!!", Asks[0], " -> ", Bids[len(Bids)-1])
Asks = Asks[1:]
continue
}
if Asks[0].Volume > Bids[len(Bids)-1].Volume {
Asks[0].Volume = Asks[0].Volume - Bids[len(Bids)-1].Volume
fmt.Println("Deal!!!", Asks[0], " -> ", Bids[len(Bids)-1])
Bids = Bids[:len(Bids)-1]
continue
}
if Asks[0].Volume == Bids[len(Bids)-1].Volume {
fmt.Println("Deal!!!", Asks[0], " -> ", Bids[len(Bids)-1])
Asks = Asks[1:]
Bids = Bids[:len(Bids)-1]
continue
}
}
if len(Asks) > 5 && len(Bids) > 5 {
//fmt.Println("Loweast 5 Asks", Asks[0:5])
//fmt.Println("Highest 5 Bids", Bids[len(Bids)-5:])
//fmt.Println("-----------------------------------")
}
}
}
func DealerMainLoop() {
for {
select {
case <-time.After(time.Millisecond * 15):
//create dummy orders and send to order chan
order := Order{AskBid: AskBid(rand.Intn(2)), MarketLimit: Limit, Volume: rand.Intn(1000), Price: float64(rand.Intn(1000))}
if order.MarketLimit == Market {
order.Price = 0
}
Orders <- order
}
}
}
func TestPlayWithChan(t *testing.T) {
//Init Orders
Orders = make(chan Order, 100000)
go BrokerMainLoop()
for i := 0; i < 1000; i++ {
go DealerMainLoop()
}
select {}
}