main.go 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169
  1. // main.go
  2. package main
  3. import (
  4. "compress/gzip"
  5. "encoding/json"
  6. "errors"
  7. "flag"
  8. "fmt"
  9. "io"
  10. "log"
  11. "net/http"
  12. "os"
  13. "runtime"
  14. "strconv"
  15. "strings"
  16. "sync"
  17. "time"
  18. "tickserver/client"
  19. "tickserver/framework/base"
  20. "tickserver/markinfo"
  21. "tickserver/server/market"
  22. )
  23. type RealTick struct {
  24. tg base.TickGo
  25. //tgCh <-chan base.TickGo
  26. now int64
  27. }
  28. type Options struct {
  29. Start int `json:"start"`
  30. End int `json:"end"`
  31. Total int `json:"total_size"`
  32. }
  33. type KCandle struct {
  34. X []int `json:"x"`
  35. Y [][5]float32 `json:"y"`
  36. }
  37. type KVolume struct {
  38. X []int `json:"x"`
  39. Y []int `json:"y"`
  40. }
  41. type KData struct {
  42. C string `json:"c"`
  43. P string `json:"p"`
  44. Action string `json:"action"`
  45. KOptions Options `json:"options"`
  46. Candles KCandle `json:"main"`
  47. Volumes KVolume `json:"volumes|||__ignore__"`
  48. }
  49. type HistoryData struct {
  50. C string `json:"c"`
  51. P string `json:"p"`
  52. Action string `json:"action"`
  53. End int64 `json:"end"`
  54. MainData [][6]string `json:"main"`
  55. Easyforex [][6]string `json:"easyforex"`
  56. Oanda [][6]string `json:"oanda"`
  57. }
  58. type SymbolData struct {
  59. Unit float64
  60. PriceIncrement float64
  61. Symbol int
  62. Name string
  63. }
  64. //type byDlInfo []market.DlInfo
  65. //func (a byDlInfo) Len() int { return len(a) }
  66. //func (a byDlInfo) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
  67. //func (a byDlInfo) Less(i, j int) bool { return a[i].Reply.St < a[j].Reply.St }
  68. var saddr1 = flag.String("s1", "127.0.0.1:19528", "tick server address 1") //115.231.103.7
  69. var saddr2 = flag.String("s2", "127.0.0.1:19528", "tick server address 2") //127.0.0.1
  70. var saddr3 = flag.String("s3", "127.0.0.1:19529", "tick server address 3") //115.236.75.194
  71. var saddr4 = flag.String("s4", "127.0.0.1:9090", "tick server address 4") //19528 9090
  72. var clientSub *client.ClientSimple
  73. var clientDown *client.ClientSimple
  74. var tkMap = make(map[string]base.TickGo)
  75. var tkMutex sync.Mutex
  76. type Conf struct {
  77. Saddr1 string //
  78. Saddr2 string //
  79. Saddr3 string //
  80. Saddr4 string
  81. }
  82. type SpecialTick struct {
  83. Timestamp int64 `json:"ts"`
  84. Open float64 `json:"open"`
  85. High float64 `json:"high"`
  86. Low float64 `json:"low"`
  87. Last float64 `json:"last"`
  88. Volume float64 `json:"volume"`
  89. }
  90. type StringSpecialTick struct {
  91. Timestamp string `json:"ts"`
  92. Open string `json:"open"`
  93. High string `json:"high"`
  94. Low string `json:"low"`
  95. Last string `json:"last"`
  96. Volume string `json:"volume"`
  97. }
  98. func readConf() (*Conf, error) {
  99. f, err := os.Open("webproxy.json")
  100. if err != nil {
  101. return nil, err
  102. }
  103. defer f.Close()
  104. dec := json.NewDecoder(f)
  105. conf := &Conf{}
  106. err = dec.Decode(conf)
  107. if err != nil {
  108. return nil, err
  109. }
  110. return conf, nil
  111. }
  112. func dayHandler(w http.ResponseWriter, r *http.Request) {
  113. //cb := r.FormValue("callback")
  114. typ := r.FormValue("type")
  115. symbol := r.FormValue("symbol")
  116. //log.Println(cb, typ, symbol)
  117. insId := typ + "_" + symbol
  118. candles, err := clientDown.GetLastCandles(insId, market.D1, 1)
  119. if err != nil || len(candles) == 0 {
  120. http.Error(w, "server get data failed", http.StatusInternalServerError)
  121. return
  122. } else {
  123. //fmt.Println("day", len(candles))
  124. stk := SpecialTick{Timestamp: candles[0].Timestamp / 1000, Open: candles[0].Open, High: candles[0].High,
  125. Low: candles[0].Low, Last: candles[0].Close, Volume: candles[0].RealVolums}
  126. b, err := json.Marshal(&stk)
  127. if err != nil {
  128. http.Error(w, "json encoding error", http.StatusInternalServerError)
  129. return
  130. }
  131. io.WriteString(w, string(b))
  132. }
  133. }
  134. func h24Handler(w http.ResponseWriter, r *http.Request) {
  135. //cb := r.FormValue("callback")
  136. typ := r.FormValue("type")
  137. symbol := r.FormValue("symbol")
  138. //log.Println(cb, typ, symbol)
  139. var candles []client.Candle
  140. insId := typ + "_" + symbol
  141. bufcandles, err := clientDown.GetLastCandles(insId, market.H1, 24)
  142. if err != nil {
  143. http.Error(w, "server get data failed", http.StatusInternalServerError)
  144. return
  145. } else {
  146. //fmt.Println("h24 1", len(bufcandles), bufcandles[0], bufcandles[len(bufcandles)-1])
  147. if len(bufcandles) < 24 {
  148. _, filecandles, _ := clientDown.GetHistory(insId, market.H1, -24, -1)
  149. //fmt.Println("h24 2", len(filecandles), filecandles[0], filecandles[len(filecandles)-1])
  150. var candlesDesc []client.Candle
  151. var bufCandleTime int64
  152. if len(bufcandles) > 0 {
  153. bufCandleTime = bufcandles[0].Timestamp
  154. }
  155. for i := 0; i < len(filecandles); i++ {
  156. if filecandles[i].Timestamp < bufCandleTime {
  157. candlesDesc = append(candlesDesc, filecandles[i])
  158. }
  159. if len(candlesDesc) >= (24 - len(bufcandles)) {
  160. break
  161. }
  162. }
  163. for i := len(candlesDesc) - 1; i >= 0; i-- {
  164. candles = append(candles, candlesDesc[i])
  165. }
  166. //fmt.Println("h24 3", len(candles), candles[0], candles[len(candles)-1])
  167. candles = append(candles, bufcandles[:]...)
  168. //fmt.Println("h24 4", len(candles), candles[0], candles[len(candles)-1])
  169. } else {
  170. candles = bufcandles[:]
  171. }
  172. var stk SpecialTick
  173. if len(candles) > 0 {
  174. stk.Low = candles[0].Low
  175. stk.Open = candles[0].Open
  176. stk.Timestamp = candles[0].Timestamp / 1000
  177. for i := 0; i < len(candles); i++ {
  178. //fmt.Println("h24 5", i, candles[i])
  179. stk.Volume += candles[i].RealVolums
  180. if candles[i].High > stk.High {
  181. stk.High = candles[i].High
  182. }
  183. if candles[i].Low < stk.Low {
  184. stk.Low = candles[i].Low
  185. }
  186. stk.Last = candles[i].Close
  187. }
  188. }
  189. sstk := &StringSpecialTick{
  190. Timestamp: fmt.Sprintf("%d", stk.Timestamp),
  191. Open: fmt.Sprintf("%.4f", stk.Open),
  192. }
  193. switch insId {
  194. case "bty_BCCBTC":
  195. sstk.Last = fmt.Sprintf("%.4f", stk.Last)
  196. sstk.High = fmt.Sprintf("%.4f", stk.High)
  197. sstk.Low = fmt.Sprintf("%.4f", stk.Low)
  198. sstk.Volume = fmt.Sprintf("%.4f", stk.Volume)
  199. case "bty_ETHBTC":
  200. sstk.Last = fmt.Sprintf("%.5f", stk.Last)
  201. sstk.High = fmt.Sprintf("%.5f", stk.High)
  202. sstk.Low = fmt.Sprintf("%.5f", stk.Low)
  203. sstk.Volume = fmt.Sprintf("%.3f", stk.Volume)
  204. case "bty_ETCBTC":
  205. sstk.Last = fmt.Sprintf("%.6f", stk.Last)
  206. sstk.High = fmt.Sprintf("%.6f", stk.High)
  207. sstk.Low = fmt.Sprintf("%.6f", stk.Low)
  208. sstk.Volume = fmt.Sprintf("%.2f", stk.Volume)
  209. case "bty_ZECBTC":
  210. sstk.Last = fmt.Sprintf("%.5f", stk.Last)
  211. sstk.High = fmt.Sprintf("%.5f", stk.High)
  212. sstk.Low = fmt.Sprintf("%.5f", stk.Low)
  213. sstk.Volume = fmt.Sprintf("%.3f", stk.Volume)
  214. case "bty_LTCBTC":
  215. sstk.Last = fmt.Sprintf("%.6f", stk.Last)
  216. sstk.High = fmt.Sprintf("%.6f", stk.High)
  217. sstk.Low = fmt.Sprintf("%.6f", stk.Low)
  218. sstk.Volume = fmt.Sprintf("%.2f", stk.Volume)
  219. case "bty_BTCUSDT":
  220. sstk.Last = fmt.Sprintf("%.2f", stk.Last)
  221. sstk.High = fmt.Sprintf("%.2f", stk.High)
  222. sstk.Low = fmt.Sprintf("%.2f", stk.Low)
  223. sstk.Volume = fmt.Sprintf("%.4f", stk.Volume)
  224. case "bty_BCCUSDT":
  225. sstk.Last = fmt.Sprintf("%.2f", stk.Last)
  226. sstk.High = fmt.Sprintf("%.2f", stk.High)
  227. sstk.Low = fmt.Sprintf("%.2f", stk.Low)
  228. sstk.Volume = fmt.Sprintf("%.4f", stk.Volume)
  229. case "bty_ETHUSDT":
  230. sstk.Last = fmt.Sprintf("%.2f", stk.Last)
  231. sstk.High = fmt.Sprintf("%.2f", stk.High)
  232. sstk.Low = fmt.Sprintf("%.2f", stk.Low)
  233. sstk.Volume = fmt.Sprintf("%.3f", stk.Volume)
  234. case "bty_ETCUSDT":
  235. sstk.Last = fmt.Sprintf("%.2f", stk.Last)
  236. sstk.High = fmt.Sprintf("%.2f", stk.High)
  237. sstk.Low = fmt.Sprintf("%.2f", stk.Low)
  238. sstk.Volume = fmt.Sprintf("%.2f", stk.Volume)
  239. case "bty_ZECUSDT":
  240. sstk.Last = fmt.Sprintf("%.2f", stk.Last)
  241. sstk.High = fmt.Sprintf("%.2f", stk.High)
  242. sstk.Low = fmt.Sprintf("%.2f", stk.Low)
  243. sstk.Volume = fmt.Sprintf("%.3f", stk.Volume)
  244. case "bty_LTCUSDT":
  245. sstk.Last = fmt.Sprintf("%.2f", stk.Last)
  246. sstk.High = fmt.Sprintf("%.2f", stk.High)
  247. sstk.Low = fmt.Sprintf("%.2f", stk.Low)
  248. sstk.Volume = fmt.Sprintf("%.2f", stk.Volume)
  249. case "bty_YCCUSDT":
  250. fallthrough
  251. case "bty_BTYUSDT":
  252. sstk.Last = fmt.Sprintf("%.4f", stk.Last)
  253. sstk.High = fmt.Sprintf("%.4f", stk.High)
  254. sstk.Low = fmt.Sprintf("%.4f", stk.Low)
  255. sstk.Volume = fmt.Sprintf("%.1f", stk.Volume)
  256. case "bty_BTCSUSDT":
  257. sstk.Last = fmt.Sprintf("%.2f", stk.Last)
  258. sstk.High = fmt.Sprintf("%.2f", stk.High)
  259. sstk.Low = fmt.Sprintf("%.2f", stk.Low)
  260. sstk.Volume = fmt.Sprintf("%.2f", stk.Volume)
  261. case "bty_SCUSDT":
  262. sstk.Last = fmt.Sprintf("%.6f", stk.Last)
  263. sstk.High = fmt.Sprintf("%.6f", stk.High)
  264. sstk.Low = fmt.Sprintf("%.6f", stk.Low)
  265. sstk.Volume = fmt.Sprintf("%.0f", stk.Volume)
  266. case "bty_BTSUSDT":
  267. sstk.Last = fmt.Sprintf("%.4f", stk.Last)
  268. sstk.High = fmt.Sprintf("%.4f", stk.High)
  269. sstk.Low = fmt.Sprintf("%.4f", stk.Low)
  270. sstk.Volume = fmt.Sprintf("%.2f", stk.Volume)
  271. case "bty_DCRUSDT":
  272. sstk.Last = fmt.Sprintf("%.2f", stk.Last)
  273. sstk.High = fmt.Sprintf("%.2f", stk.High)
  274. sstk.Low = fmt.Sprintf("%.2f", stk.Low)
  275. sstk.Volume = fmt.Sprintf("%.2f", stk.Volume)
  276. default:
  277. }
  278. b, err := json.Marshal(sstk)
  279. if err != nil {
  280. http.Error(w, "json encoding error", http.StatusInternalServerError)
  281. return
  282. }
  283. w.Header().Set("Access-Control-Allow-Origin", "*")
  284. w.Header().Add("Access-Control-Allow-Headers", "Content-Type")
  285. w.Header().Set("content-type", "application/json")
  286. io.WriteString(w, string(b))
  287. }
  288. }
  289. func subTick(insId string, symbolId int16) error {
  290. ins := clientSub.GetIns(insId)
  291. if ins == nil {
  292. errinfo := fmt.Sprintf("instrument %s not supported.", insId)
  293. return errors.New(errinfo)
  294. }
  295. clientSub.SubMarket(insId)
  296. ins.OnMarket().Attach(func(v interface{}) error {
  297. m, ok := v.(*client.Market)
  298. if !ok {
  299. //log.Println("v.(*Market) is NOT ok", insId)
  300. err := errors.New("v.(*Market) is NOT ok")
  301. return err
  302. }
  303. if m.InsId != insId {
  304. //log.Println("m.InsId != insId", m.InsId, insId)
  305. err := errors.New("v.(*Market) insid is NOT ok")
  306. return err
  307. }
  308. //log.Println("@@@:Market:", m)
  309. //now := time.Now()
  310. //timestampNow := now.Unix()*1000 + int64(now.Nanosecond())/1000000
  311. //log.Println("query", timestampNow, m.Timestamp, timestampNow-m.Timestamp)
  312. var tg base.TickGo
  313. tg.Time = int32(m.Timestamp / 1000)
  314. tg.Ms = int16(m.Timestamp % 1000)
  315. tg.Symbol = symbolId
  316. tg.Ask = float32(m.LastPrice)
  317. tg.Bid = float32(m.LastPrice)
  318. tg.Askv = float32(m.Volume)
  319. tg.Bidv = float32(m.Volume)
  320. if tg.Ask != 0. && tg.Bid != 0. {
  321. tkMutex.Lock()
  322. tkMap[insId] = tg
  323. tkMutex.Unlock()
  324. } else {
  325. //log.Println("value of ask or bid is 0", tg)
  326. }
  327. //log.Println(tg)
  328. return nil
  329. })
  330. return nil
  331. }
  332. func getOutput(cb string, ticks []base.TickGo) (output string) {
  333. b, err := json.Marshal(ticks)
  334. if err != nil {
  335. //log.Println(err)
  336. }
  337. output = fmt.Sprintf("if (%s) %s(%s)\n", cb, cb, string(b))
  338. return output
  339. }
  340. func connectServer() (err error) {
  341. clientSub, err = client.NewClientSimple(*saddr1, *saddr2, *saddr3, *saddr4, "./tmp")
  342. if err != nil {
  343. //log.Println("new client", err)
  344. return err
  345. }
  346. //insMap := clientSub.GetInsMap()
  347. //for insId, ins := range insMap {
  348. //log.Println(insId, ins)
  349. //}
  350. clientDown, err = client.NewClientSimple(*saddr1, *saddr2, *saddr3, *saddr4, "./tmp")
  351. if err != nil {
  352. //log.Println("new client", err)
  353. return err
  354. }
  355. return nil
  356. }
  357. func tickHandler(w http.ResponseWriter, r *http.Request) {
  358. //log.Println(r)
  359. //_, ok := w.(http.Hijacker)
  360. //if !ok {
  361. //http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError)
  362. //return
  363. //} else {
  364. //}
  365. cb := r.FormValue("callback")
  366. typ := r.FormValue("type")
  367. symbol := r.FormValue("symbol")
  368. //log.Println(cb, typ, symbol)
  369. symbols := make([]string, 0)
  370. if symbol == "" {
  371. insMap := clientSub.GetInsMap()
  372. for _, v := range insMap {
  373. insTyp := strings.Split(v.Id, "_")[0]
  374. insSymbol := strings.Split(v.Id, "_")[1]
  375. if insTyp == typ {
  376. if typ == "lmax" {
  377. bookId, err := strconv.Atoi(insSymbol)
  378. if err != nil {
  379. continue
  380. }
  381. symbolId, err := markinfo.BookIdToSymbolId(bookId)
  382. if err != nil {
  383. continue
  384. }
  385. insSymbol, err = markinfo.SymbolName(symbolId)
  386. if err != nil {
  387. continue
  388. }
  389. }
  390. symbols = append(symbols, insSymbol)
  391. }
  392. }
  393. } else {
  394. symbols = strings.Split(symbol, ",")
  395. }
  396. ticks := make([]base.TickGo, 0)
  397. for _, v := range symbols {
  398. symbolId, err := markinfo.SymbolId(v)
  399. if err != nil {
  400. if typ == "lmax" && v == "CRUDE" {
  401. symbolId = markinfo.OILUSD
  402. } // else {
  403. //http.Error(w, "webserver doesn't support symbol", http.StatusBadRequest)
  404. //return
  405. //}
  406. }
  407. myInsId := typ + "_" + v
  408. if typ == "lmax" {
  409. lmaxId, err := markinfo.SymbolIdToBookId(symbolId)
  410. if err != nil {
  411. if typ == "lmax" && (v == "CRUDE" || v == "OILUSD") {
  412. lmaxId = 100800
  413. } else {
  414. http.Error(w, "webserver doesn't support symbol", http.StatusBadRequest)
  415. return
  416. }
  417. }
  418. slmaxId := fmt.Sprintf("%d", lmaxId)
  419. myInsId = typ + "_" + slmaxId
  420. }
  421. tkMutex.Lock()
  422. tick, ok := tkMap[myInsId]
  423. tkMutex.Unlock()
  424. if ok {
  425. /*if typ == "lmax" {
  426. tick.Time = int32(time.Now().Unix())
  427. tick.Ms = 0
  428. }*/
  429. ticks = append(ticks, tick)
  430. } else {
  431. /*if typ == "lmax" {
  432. tmpticks, err := clientSub.GetTickHistory(myInsId, -1, -1)
  433. if len(tmpticks) > 0 {
  434. tick.Time = int32(time.Now().Unix()) //int32(tmpticks[0].Timestamp / 1000)
  435. tick.Ms = 0 //int16(tmpticks[0].Timestamp % 1000)
  436. tick.Symbol = int16(symbolId)
  437. tick.Ask = float32(tmpticks[0].Price)
  438. tick.Bid = float32(tmpticks[0].Price)
  439. tick.Askv = int32(tmpticks[0].Volume)
  440. tick.Bidv = int32(tmpticks[0].Volume)
  441. ticks = append(ticks, tick)
  442. tkMutex.Lock()
  443. tkMap[myInsId] = tick
  444. tkMutex.Unlock()
  445. }
  446. log.Println("fuck", err, len(tmpticks))
  447. }*/
  448. err := subTick(myInsId, int16(symbolId))
  449. if err != nil {
  450. //log.Println(err)
  451. }
  452. }
  453. }
  454. output := getOutput(cb, ticks)
  455. io.WriteString(w, output)
  456. }
  457. func getDownOutput(cb string, hisData *HistoryData) (output string) {
  458. b, err := json.Marshal(hisData)
  459. if err != nil {
  460. //log.Println(err)
  461. }
  462. if len(cb) > 0 {
  463. output = fmt.Sprintf("if (%s) %s(%s)\n", cb, cb, string(b))
  464. } else {
  465. output = string(b) + "\n"
  466. }
  467. return output
  468. }
  469. func candle2Str(candle market.Candle) [6]string {
  470. var candleStrings [6]string
  471. candleStrings[0] = fmt.Sprintf("%d", candle.Timestamp/1000)
  472. candleStrings[1] = fmt.Sprintf("%f", candle.Open)
  473. candleStrings[2] = fmt.Sprintf("%f", candle.High)
  474. candleStrings[3] = fmt.Sprintf("%f", candle.Low)
  475. candleStrings[4] = fmt.Sprintf("%f", candle.Close)
  476. candleStrings[5] = fmt.Sprintf("%d", 0)
  477. return candleStrings
  478. }
  479. func downHandler(w http.ResponseWriter, r *http.Request) {
  480. symbol := r.FormValue("c")
  481. period := r.FormValue("p")
  482. action := r.FormValue("action")
  483. count := r.FormValue("count")
  484. typ := r.FormValue("type")
  485. //out := r.FormValue("out")
  486. cb := r.FormValue("callback")
  487. var ts, te string
  488. if action == "new" {
  489. te = r.FormValue("te")
  490. }
  491. if action == "down" {
  492. ts = r.FormValue("ts")
  493. }
  494. //log.Println(symbol, period, action, count, typ, out, te, ts)
  495. symbolId, err := markinfo.SymbolId(symbol)
  496. if err != nil {
  497. if symbol == "CRUDE" {
  498. symbolId = markinfo.OILUSD
  499. } else {
  500. http.Error(w, "webserver doesn't support symbol", http.StatusBadRequest)
  501. return
  502. }
  503. }
  504. periodId, ok := market.PeriodIdMap[period]
  505. if !ok {
  506. http.Error(w, "webserver doesn't support period", http.StatusBadRequest)
  507. return
  508. }
  509. iCount, err := strconv.Atoi(count)
  510. if action != "new" && err != nil {
  511. http.Error(w, "webserver doesn't support count", http.StatusBadRequest)
  512. return
  513. }
  514. types := strings.Split(typ, "|")
  515. for i, v := range types {
  516. if v == "main" {
  517. types[i] = types[0]
  518. types[0] = v
  519. break
  520. }
  521. }
  522. typeCount := len(types)
  523. done := make(chan bool, typeCount)
  524. endCh := make(chan int64, typeCount-1)
  525. var hisData HistoryData
  526. hisData.C = symbol
  527. hisData.P = period
  528. hisData.Action = action
  529. var mainTimestamps []int64
  530. var easyforexCandles, oandaCandles []client.Candle
  531. easyforexTimestampMap := make(map[int64]int)
  532. oandaTimestampMap := make(map[int64]int)
  533. //log.Println("test", types)
  534. for i := 0; i < typeCount; i++ {
  535. v := types[i]
  536. //for i, v := range types {
  537. var prefix string
  538. switch v {
  539. case "main":
  540. prefix = market.LmaxPrefix
  541. if symbol == "BTCCNY" || symbol == "BTCUSD" || symbol == "BTCFUSD" {
  542. prefix = market.BtcPrefix
  543. } else if symbol == "BTCETH" {
  544. prefix = market.PoloPrefix
  545. } else if symbol == "ETHCNY" || symbol == "BTYCNY" || symbol == "ETCCNY" {
  546. prefix = market.BtyPrefix
  547. }
  548. case "easyforex":
  549. prefix = market.EasyForexPrefix
  550. if symbol == "CRUDE" {
  551. symbol = "OILUSD"
  552. }
  553. case "oanda":
  554. prefix = market.OandaPrefix
  555. if symbol == "CRUDE" {
  556. symbol = "OILUSD"
  557. }
  558. }
  559. myInsId := prefix + symbol
  560. if prefix == market.LmaxPrefix {
  561. lmaxId, err := markinfo.SymbolIdToBookId(symbolId)
  562. if err != nil {
  563. if symbolId == markinfo.OILUSD {
  564. lmaxId = 100800
  565. } else {
  566. http.Error(w, "webserver doesn't support symbol", http.StatusBadRequest)
  567. return
  568. }
  569. }
  570. slmaxId := fmt.Sprintf("%d", lmaxId)
  571. myInsId = market.LmaxPrefix + slmaxId
  572. }
  573. go func() {
  574. var end, iTE, iTS int64
  575. var bufferedCandlesDesc []client.Candle
  576. var downN int
  577. var downTS int64
  578. switch action {
  579. case "init":
  580. bufferedCandlesAsc, _ := clientDown.GetLastCandles(myInsId, periodId, 0x7fffffff)
  581. for cindex := len(bufferedCandlesAsc) - 1; cindex >= 0; cindex-- {
  582. bufferedCandlesDesc = append(bufferedCandlesDesc, bufferedCandlesAsc[cindex])
  583. if len(bufferedCandlesDesc) >= iCount {
  584. break
  585. }
  586. }
  587. downN = -(iCount - len(bufferedCandlesDesc))
  588. downTS = -1
  589. case "new":
  590. iCount = 1000
  591. iTE, _ = strconv.ParseInt(te, 10, 64)
  592. iTE *= 1000
  593. bufferedCandlesAsc, _ := clientDown.GetLastCandles(myInsId, periodId, 0x7fffffff)
  594. //log.Println("haha.....", myInsId, bufferedCandlesAsc)
  595. for cindex := len(bufferedCandlesAsc) - 1; cindex >= 0; cindex-- {
  596. if bufferedCandlesAsc[cindex].Timestamp >= iTE {
  597. bufferedCandlesDesc = append(bufferedCandlesDesc, bufferedCandlesAsc[cindex])
  598. if len(bufferedCandlesDesc) >= iCount {
  599. break
  600. }
  601. }
  602. }
  603. if len(bufferedCandlesDesc) > 0 {
  604. downN = -(iCount - len(bufferedCandlesDesc))
  605. downTS = -1
  606. } else {
  607. downN = iCount
  608. downTS = iTE
  609. }
  610. case "down":
  611. iTS, _ = strconv.ParseInt(ts, 10, 64)
  612. iTS *= 1000
  613. tmpBufferedCandles, _ := clientDown.GetLastCandles(myInsId, periodId, 1)
  614. if len(tmpBufferedCandles) > 0 && tmpBufferedCandles[0].Timestamp <= iTS {
  615. bufferedCandlesAsc, _ := clientDown.GetLastCandles(myInsId, periodId, 0x7fffffff)
  616. for cindex := len(bufferedCandlesAsc) - 1; cindex >= 0; cindex-- {
  617. if bufferedCandlesAsc[cindex].Timestamp <= iTS {
  618. bufferedCandlesDesc = append(bufferedCandlesDesc, bufferedCandlesAsc[cindex])
  619. if len(bufferedCandlesDesc) >= iCount {
  620. break
  621. }
  622. }
  623. }
  624. }
  625. if len(bufferedCandlesDesc) > 0 {
  626. downN = -(iCount - len(bufferedCandlesDesc))
  627. downTS = -1
  628. } else {
  629. downN = -iCount
  630. downTS = iTS
  631. }
  632. }
  633. //log.Println(myInsId, len(bufferedCandlesDesc))
  634. //for _, candle := range bufferedCandlesDesc {
  635. //log.Println(candle)
  636. //}
  637. //log.Println("test", myInsId, periodId, downN, downTS, false)
  638. _, filecandles, _ := clientDown.GetHistory(myInsId, periodId, downN, downTS)
  639. //log.Println("test", myInsId, len(fileticks), len(filecandles))
  640. if v != "main" {
  641. end = <-endCh
  642. }
  643. bEnd := false
  644. var timestampLast int64
  645. timestampLast = 0x7fffffffffffffff
  646. for findex := 1; findex >= 0; findex-- {
  647. var candles []client.Candle
  648. if findex == 1 {
  649. //candles = append(candles, bufferedCandlesDesc...)
  650. for iBuffered := len(bufferedCandlesDesc) - 1; iBuffered >= 0; iBuffered-- {
  651. candles = append(candles, bufferedCandlesDesc[iBuffered])
  652. }
  653. if v == "oanda" {
  654. //for _, vtmp := range candles {
  655. //log.Println("test1", vtmp)
  656. //}
  657. }
  658. //log.Println("buf", v, len(candles))
  659. } else {
  660. if downN < 0 {
  661. for iFile := len(filecandles) - 1; iFile >= 0; iFile-- {
  662. candles = append(candles, filecandles[iFile])
  663. }
  664. } else {
  665. candles = filecandles[:]
  666. }
  667. if v == "oanda" {
  668. //for _, vtmp := range candles {
  669. //log.Println("test2", vtmp)
  670. //}
  671. }
  672. //log.Println("file", v, len(candles), fnames[findex].Fname)
  673. }
  674. //log.Println("aaaa", v, candles)
  675. for cindex := len(candles) - 1; cindex >= 0; cindex-- {
  676. if v == "main" && periodId == market.D1 {
  677. tmpTime := time.Unix(candles[cindex].Timestamp/1000, 0)
  678. if tmpTime.Hour() != 0 || tmpTime.Minute() != 0 || tmpTime.Second() != 0 {
  679. //log.Println("data time not standard", v, tmpTime)
  680. //candles[cindex].Timestamp -= (int64(tmpTime.Hour())*3600 + int64(tmpTime.Minute())*60 + int64(tmpTime.Second())) * 1000
  681. }
  682. }
  683. if candles[cindex].Timestamp >= timestampLast {
  684. continue
  685. }
  686. timestampLast = candles[cindex].Timestamp
  687. if action == "down" && candles[cindex].Timestamp > iTS {
  688. continue
  689. }
  690. if action == "new" && candles[cindex].Timestamp < iTE {
  691. continue
  692. }
  693. if v == "main" {
  694. var candleStrings [6]string
  695. candleStrings[0] = fmt.Sprintf("%d", candles[cindex].Timestamp/1000)
  696. candleStrings[1] = fmt.Sprintf("%f", candles[cindex].Open)
  697. candleStrings[2] = fmt.Sprintf("%f", candles[cindex].High)
  698. candleStrings[3] = fmt.Sprintf("%f", candles[cindex].Low)
  699. candleStrings[4] = fmt.Sprintf("%f", candles[cindex].Close)
  700. candleStrings[5] = fmt.Sprintf("%d", 0)
  701. hisData.MainData = append(hisData.MainData, candleStrings)
  702. end = candles[cindex].Timestamp
  703. mainTimestamps = append(mainTimestamps, end)
  704. //tmpTime := time.Unix(end/1000, 0)
  705. //if tmpTime.Hour() != 0 || tmpTime.Minute() != 0 || tmpTime.Second() != 0 {
  706. //log.Println("data error", v, tmpTime)
  707. //}
  708. if len(hisData.MainData) >= iCount {
  709. bEnd = true
  710. //log.Println("test", v, len(hisData.MainData))
  711. break
  712. }
  713. } else {
  714. if candles[cindex].Timestamp < end {
  715. bEnd = true
  716. if v == "oanda" {
  717. //log.Println("test", v, end, candles[cindex].Timestamp, len(hisData.Oanda))
  718. }
  719. if v == "easyforex" {
  720. //log.Println("test", v, end, candles[cindex].Timestamp, len(hisData.Easyforex))
  721. }
  722. break
  723. }
  724. if v == "easyforex" {
  725. //hisData.Easyforex = append(hisData.Easyforex, candleStrings)
  726. //easyforexMap[candles[cindex].Timestamp] = candles[cindex]
  727. easyforexCandles = append(easyforexCandles, candles[cindex])
  728. easyforexTimestampMap[candles[cindex].Timestamp] = len(easyforexCandles) - 1
  729. //tmpTime := time.Unix(candles[cindex].Timestamp/1000, 0)
  730. //if tmpTime.Hour() != 0 || tmpTime.Minute() != 0 || tmpTime.Second() != 0 {
  731. //log.Println("data error", v, tmpTime)
  732. //}
  733. }
  734. if v == "oanda" {
  735. //hisData.Oanda = append(hisData.Oanda, candleStrings)
  736. //oandaMap[candles[cindex].Timestamp] = candles[cindex]
  737. oandaCandles = append(oandaCandles, candles[cindex])
  738. oandaTimestampMap[candles[cindex].Timestamp] = len(oandaCandles) - 1
  739. //log.Println("hhhhhhh", oandaCandles)
  740. }
  741. }
  742. }
  743. if bEnd {
  744. //log.Println("test", v)
  745. break
  746. }
  747. }
  748. if v == "main" {
  749. for endCount := 1; endCount < typeCount; endCount++ {
  750. endCh <- end
  751. }
  752. //log.Println("test", v, end)
  753. }
  754. if v == "easyforex" {
  755. index := -1 //var index int
  756. for _, iMain := range mainTimestamps {
  757. var candleStrings [6]string
  758. vEasyforex, ok := easyforexTimestampMap[iMain]
  759. if ok {
  760. candleStrings[1] = fmt.Sprintf("%f", easyforexCandles[vEasyforex].Open)
  761. candleStrings[2] = fmt.Sprintf("%f", easyforexCandles[vEasyforex].High)
  762. candleStrings[3] = fmt.Sprintf("%f", easyforexCandles[vEasyforex].Low)
  763. candleStrings[4] = fmt.Sprintf("%f", easyforexCandles[vEasyforex].Close)
  764. index = vEasyforex
  765. } else {
  766. //tmpTime := time.Unix(iMain/1000, 0)
  767. //log.Println("data mismatch", tmpTime)
  768. /*if index < (len(easyforexCandles) - 1) {
  769. candleStrings[1] = fmt.Sprintf("%f", easyforexCandles[index+1].Open)
  770. candleStrings[2] = fmt.Sprintf("%f", easyforexCandles[index+1].High)
  771. candleStrings[3] = fmt.Sprintf("%f", easyforexCandles[index+1].Low)
  772. candleStrings[4] = fmt.Sprintf("%f", easyforexCandles[index+1].Close)
  773. } else {
  774. candleStrings[1] = fmt.Sprintf("%f", 0.0)
  775. candleStrings[2] = fmt.Sprintf("%f", 0.0)
  776. candleStrings[3] = fmt.Sprintf("%f", 0.0)
  777. candleStrings[4] = fmt.Sprintf("%f", 0.0)
  778. }*/
  779. if index != -1 {
  780. candleStrings[1] = fmt.Sprintf("%f", easyforexCandles[index].Open)
  781. candleStrings[2] = fmt.Sprintf("%f", easyforexCandles[index].High)
  782. candleStrings[3] = fmt.Sprintf("%f", easyforexCandles[index].Low)
  783. candleStrings[4] = fmt.Sprintf("%f", easyforexCandles[index].Close)
  784. } else {
  785. candleStrings[1] = fmt.Sprintf("%f", 0.0)
  786. candleStrings[2] = fmt.Sprintf("%f", 0.0)
  787. candleStrings[3] = fmt.Sprintf("%f", 0.0)
  788. candleStrings[4] = fmt.Sprintf("%f", 0.0)
  789. }
  790. }
  791. candleStrings[0] = fmt.Sprintf("%d", iMain/1000)
  792. candleStrings[5] = fmt.Sprintf("%d", 0)
  793. hisData.Easyforex = append(hisData.Easyforex, candleStrings)
  794. }
  795. }
  796. if v == "oanda" {
  797. index := -1 //var index int
  798. //for _, vtmp := range oandaCandles {
  799. //log.Println("test3", vtmp)
  800. //}
  801. //log.Println("test3", len(oandaTimestampMap), len(oandaCandles))
  802. for _, iMain := range mainTimestamps {
  803. var candleStrings [6]string
  804. vOanda, ok := oandaTimestampMap[iMain]
  805. if ok {
  806. //log.Println(vOanda, iMain, oandaCandles[vOanda].Timestamp)
  807. candleStrings[1] = fmt.Sprintf("%f", oandaCandles[vOanda].Open)
  808. candleStrings[2] = fmt.Sprintf("%f", oandaCandles[vOanda].High)
  809. candleStrings[3] = fmt.Sprintf("%f", oandaCandles[vOanda].Low)
  810. candleStrings[4] = fmt.Sprintf("%f", oandaCandles[vOanda].Close)
  811. index = vOanda
  812. } else {
  813. /*if index < (len(oandaCandles) - 1) {
  814. candleStrings[1] = fmt.Sprintf("%f", oandaCandles[index+1].Open)
  815. candleStrings[2] = fmt.Sprintf("%f", oandaCandles[index+1].High)
  816. candleStrings[3] = fmt.Sprintf("%f", oandaCandles[index+1].Low)
  817. candleStrings[4] = fmt.Sprintf("%f", oandaCandles[index+1].Close)
  818. } else {
  819. candleStrings[1] = fmt.Sprintf("%f", 0.0)
  820. candleStrings[2] = fmt.Sprintf("%f", 0.0)
  821. candleStrings[3] = fmt.Sprintf("%f", 0.0)
  822. candleStrings[4] = fmt.Sprintf("%f", 0.0)
  823. }*/
  824. if index != -1 {
  825. candleStrings[1] = fmt.Sprintf("%f", oandaCandles[index].Open)
  826. candleStrings[2] = fmt.Sprintf("%f", oandaCandles[index].High)
  827. candleStrings[3] = fmt.Sprintf("%f", oandaCandles[index].Low)
  828. candleStrings[4] = fmt.Sprintf("%f", oandaCandles[index].Close)
  829. } else {
  830. candleStrings[1] = fmt.Sprintf("%f", 0.0)
  831. candleStrings[2] = fmt.Sprintf("%f", 0.0)
  832. candleStrings[3] = fmt.Sprintf("%f", 0.0)
  833. candleStrings[4] = fmt.Sprintf("%f", 0.0)
  834. }
  835. }
  836. candleStrings[0] = fmt.Sprintf("%d", iMain/1000)
  837. candleStrings[5] = fmt.Sprintf("%d", 0)
  838. hisData.Oanda = append(hisData.Oanda, candleStrings)
  839. }
  840. }
  841. done <- true
  842. }()
  843. }
  844. for i := 0; i < typeCount; i++ {
  845. <-done
  846. }
  847. output := getDownOutput(cb, &hisData)
  848. io.WriteString(w, output)
  849. }
  850. func symbolsHandler(w http.ResponseWriter, r *http.Request) {
  851. cb := r.FormValue("callback")
  852. //log.Println(cb)
  853. var symbols []SymbolData
  854. /*for i := markinfo.EURUSD; i < markinfo.CurrencyCount; i++ {
  855. var symbol SymbolData
  856. symbol.Symbol = i
  857. symbol.Name, _ = markinfo.SymbolName(i)
  858. symbol.PriceIncrement, _ = markinfo.SymbolUint(symbol.Name)
  859. symbol.Unit = int64(1 / symbol.PriceIncrement)
  860. if (symbol.Unit % 10) == 9 {
  861. symbol.Unit++
  862. }
  863. symbols = append(symbols, symbol)
  864. }*/
  865. symbol1 := SymbolData{Unit: 500, PriceIncrement: 0.001, Symbol: 20, Name: "XAGUSD"}
  866. symbols = append(symbols, symbol1)
  867. symbol2 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 38, Name: "EURMXN"}
  868. symbols = append(symbols, symbol2)
  869. symbol3 := SymbolData{Unit: 100, PriceIncrement: 0.01, Symbol: 22, Name: "OILUSD"}
  870. symbols = append(symbols, symbol3)
  871. symbol4 := SymbolData{Unit: 10000, PriceIncrement: 0.0001, Symbol: 26, Name: "EURCZK"}
  872. symbols = append(symbols, symbol4)
  873. symbol5 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 39, Name: "GBPMXN"}
  874. symbols = append(symbols, symbol5)
  875. symbol6 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 62, Name: "NZDCAD"}
  876. symbols = append(symbols, symbol6)
  877. symbol7 := SymbolData{Unit: 10, PriceIncrement: 0.01, Symbol: 21, Name: "XAUUSD"}
  878. symbols = append(symbols, symbol7)
  879. symbol8 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 56, Name: "EURZAR"}
  880. symbols = append(symbols, symbol8)
  881. symbol9 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 52, Name: "GBPSGD"}
  882. symbols = append(symbols, symbol9)
  883. symbol10 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 25, Name: "GBPCAD"}
  884. symbols = append(symbols, symbol10)
  885. symbol11 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 58, Name: "USDZAR"}
  886. symbols = append(symbols, symbol11)
  887. symbol12 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 50, Name: "USDSEK"}
  888. symbols = append(symbols, symbol12)
  889. symbol13 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 23, Name: "USDTRY"}
  890. symbols = append(symbols, symbol13)
  891. symbol14 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 6, Name: "NZDUSD"}
  892. symbols = append(symbols, symbol14)
  893. symbol15 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 18, Name: "USDMXN"}
  894. symbols = append(symbols, symbol15)
  895. symbol16 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 42, Name: "USDNOK"}
  896. symbols = append(symbols, symbol16)
  897. symbol17 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 32, Name: "EURHKD"}
  898. symbols = append(symbols, symbol17)
  899. symbol18 := SymbolData{Unit: 10000, PriceIncrement: 0.001, Symbol: 35, Name: "EURHUF"}
  900. symbols = append(symbols, symbol18)
  901. symbol19 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 55, Name: "GBPTRY"}
  902. symbols = append(symbols, symbol19)
  903. symbol20 := SymbolData{Unit: 10000, PriceIncrement: 0.0001, Symbol: 28, Name: "USDCZK"}
  904. symbols = append(symbols, symbol20)
  905. symbol21 := SymbolData{Unit: 10000, PriceIncrement: 0.001, Symbol: 37, Name: "USDHUF"}
  906. symbols = append(symbols, symbol21)
  907. symbol22 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 4, Name: "AUDUSD"}
  908. symbols = append(symbols, symbol22)
  909. symbol23 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 5, Name: "USDCAD"}
  910. symbols = append(symbols, symbol23)
  911. symbol24 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 60, Name: "AUDCHF"}
  912. symbols = append(symbols, symbol24)
  913. symbol25 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 29, Name: "EURDKK"}
  914. symbols = append(symbols, symbol25)
  915. symbol26 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 47, Name: "USDPLN"}
  916. symbols = append(symbols, symbol26)
  917. symbol27 := SymbolData{Unit: 10000, PriceIncrement: 0.0001, Symbol: 27, Name: "GBPCZK"}
  918. symbols = append(symbols, symbol27)
  919. symbol28 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 41, Name: "GBPNOK"}
  920. symbols = append(symbols, symbol28)
  921. symbol29 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 1, Name: "GBPUSD"}
  922. symbols = append(symbols, symbol29)
  923. symbol30 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 3, Name: "USDCHF"}
  924. symbols = append(symbols, symbol30)
  925. symbol31 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 51, Name: "EURSGD"}
  926. symbols = append(symbols, symbol31)
  927. symbol32 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 24, Name: "GBPAUD"}
  928. symbols = append(symbols, symbol32)
  929. symbol33 := SymbolData{Unit: 10000, PriceIncrement: 0.001, Symbol: 14, Name: "CHFJPY"}
  930. symbols = append(symbols, symbol33)
  931. symbol34 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 30, Name: "GBPDKK"}
  932. symbols = append(symbols, symbol34)
  933. symbol35 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 57, Name: "GBPZAR"}
  934. symbols = append(symbols, symbol35)
  935. symbol36 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 63, Name: "NZDCHF"}
  936. symbols = append(symbols, symbol36)
  937. symbol37 := SymbolData{Unit: 1, PriceIncrement: 0.1, Symbol: 68, Name: "UK100"}
  938. symbols = append(symbols, symbol37)
  939. symbol38 := SymbolData{Unit: 25, PriceIncrement: 0.1, Symbol: 70, Name: "SPX"}
  940. symbols = append(symbols, symbol38)
  941. symbol39 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 0, Name: "EURUSD"}
  942. symbols = append(symbols, symbol39)
  943. symbol40 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 12, Name: "GBPCHF"}
  944. symbols = append(symbols, symbol40)
  945. symbol41 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 46, Name: "GBPPLN"}
  946. symbols = append(symbols, symbol41)
  947. symbol42 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 7, Name: "EURGBP"}
  948. symbols = append(symbols, symbol42)
  949. symbol43 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 17, Name: "AUDCAD"}
  950. symbols = append(symbols, symbol43)
  951. symbol44 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 44, Name: "GBPNZD"}
  952. symbols = append(symbols, symbol44)
  953. symbol45 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 64, Name: "NZDSGD"}
  954. symbols = append(symbols, symbol45)
  955. symbol46 := SymbolData{Unit: 10000, PriceIncrement: 0.001, Symbol: 16, Name: "AUDJPY"}
  956. symbols = append(symbols, symbol46)
  957. symbol47 := SymbolData{Unit: 1, PriceIncrement: 0.1, Symbol: 74, Name: "STOXX50E"}
  958. symbols = append(symbols, symbol47)
  959. symbol48 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 53, Name: "USDSGD"}
  960. symbols = append(symbols, symbol48)
  961. symbol49 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 9, Name: "EURCHF"}
  962. symbols = append(symbols, symbol49)
  963. symbol50 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 40, Name: "EURNOK"}
  964. symbols = append(symbols, symbol50)
  965. symbol51 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 43, Name: "EURNZD"}
  966. symbols = append(symbols, symbol51)
  967. symbol52 := SymbolData{Unit: 10000, PriceIncrement: 0.001, Symbol: 59, Name: "NZDJPY"}
  968. symbols = append(symbols, symbol52)
  969. symbol53 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 34, Name: "USDHKD"}
  970. symbols = append(symbols, symbol53)
  971. symbol54 := SymbolData{Unit: 10000, PriceIncrement: 0.001, Symbol: 2, Name: "USDJPY"}
  972. symbols = append(symbols, symbol54)
  973. symbol55 := SymbolData{Unit: 10000, PriceIncrement: 0.001, Symbol: 15, Name: "CADJPY"}
  974. symbols = append(symbols, symbol55)
  975. symbol56 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 45, Name: "EURPLN"}
  976. symbols = append(symbols, symbol56)
  977. symbol57 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 33, Name: "GBPHKD"}
  978. symbols = append(symbols, symbol57)
  979. symbol58 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 48, Name: "EURSEK"}
  980. symbols = append(symbols, symbol58)
  981. symbol59 := SymbolData{Unit: 1, PriceIncrement: 0.1, Symbol: 73, Name: "FCHI"}
  982. symbols = append(symbols, symbol59)
  983. symbol60 := SymbolData{Unit: 10, PriceIncrement: 0.1, Symbol: 71, Name: "NDX"}
  984. symbols = append(symbols, symbol60)
  985. symbol61 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 10, Name: "EURAUD"}
  986. symbols = append(symbols, symbol61)
  987. symbol62 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 19, Name: "AUDNZD"}
  988. symbols = append(symbols, symbol62)
  989. symbol63 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 54, Name: "EURTRY"}
  990. symbols = append(symbols, symbol63)
  991. symbol64 := SymbolData{Unit: 10000, PriceIncrement: 0.001, Symbol: 36, Name: "GBPHUF"}
  992. symbols = append(symbols, symbol64)
  993. symbol65 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 49, Name: "GBPSEK"}
  994. symbols = append(symbols, symbol65)
  995. symbol66 := SymbolData{Unit: 2.5, PriceIncrement: 0.1, Symbol: 72, Name: "GDAXI"}
  996. symbols = append(symbols, symbol66)
  997. symbol67 := SymbolData{Unit: 10000, PriceIncrement: 0.001, Symbol: 8, Name: "EURJPY"}
  998. symbols = append(symbols, symbol67)
  999. symbol68 := SymbolData{Unit: 10000, PriceIncrement: 0.001, Symbol: 13, Name: "GBPJPY"}
  1000. symbols = append(symbols, symbol68)
  1001. symbol69 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 11, Name: "EURCAD"}
  1002. symbols = append(symbols, symbol69)
  1003. symbol70 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 61, Name: "CADCHF"}
  1004. symbols = append(symbols, symbol70)
  1005. symbol71 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 31, Name: "USDDKK"}
  1006. symbols = append(symbols, symbol71)
  1007. symbol72 := SymbolData{Unit: 1, PriceIncrement: 1, Symbol: 69, Name: "WS30"}
  1008. symbols = append(symbols, symbol72)
  1009. symbol73 := SymbolData{Unit: 10000, PriceIncrement: 1e-05, Symbol: 65, Name: "LTCUSD"}
  1010. symbols = append(symbols, symbol73)
  1011. symbol74 := SymbolData{Unit: 10000, PriceIncrement: 0.001, Symbol: 66, Name: "BTCUSD"}
  1012. symbols = append(symbols, symbol74)
  1013. b, _ := json.Marshal(symbols)
  1014. output := fmt.Sprintf("if (%s) %s(%s)\n", cb, cb, string(b))
  1015. io.WriteString(w, output)
  1016. }
  1017. /*
  1018. func testHandler(w http.ResponseWriter, r *http.Request) {
  1019. insId := r.FormValue("insid")
  1020. period := r.FormValue("period")
  1021. st := r.FormValue("st")
  1022. et := r.FormValue("et")
  1023. log.Println(insId, period, st, et)
  1024. periodId, ok := market.PeriodIdMap[period]
  1025. if !ok {
  1026. http.Error(w, "webserver doesn't support period", http.StatusBadRequest)
  1027. return
  1028. }
  1029. st64, _ := strconv.ParseInt(st, 10, 64)
  1030. et64, _ := strconv.ParseInt(et, 10, 64)
  1031. fnames, err := clientDown.GetHisEx(insId, periodId, st64, et64, false)
  1032. if err != nil {
  1033. http.Error(w, "webserver can't get data", http.StatusBadRequest)
  1034. return
  1035. }
  1036. sort.Sort(byDlInfo(fnames))
  1037. var output string
  1038. for i, v := range fnames {
  1039. output += fmt.Sprintf("%d %s %s %d %d %d", i, v.Fname, v.Reply.Url, v.Reply.St, v.Reply.Et, v.Reply.N)
  1040. }
  1041. io.WriteString(w, output)
  1042. }
  1043. */
  1044. type gzipResponseWriter struct {
  1045. io.Writer
  1046. http.ResponseWriter
  1047. }
  1048. func (w gzipResponseWriter) Write(b []byte) (int, error) {
  1049. return w.Writer.Write(b)
  1050. }
  1051. func (w gzipResponseWriter) Flush() {
  1052. w.Writer.(*gzip.Writer).Flush()
  1053. w.ResponseWriter.(http.Flusher).Flush()
  1054. }
  1055. func makeGzipHandler(fn http.HandlerFunc) http.HandlerFunc {
  1056. return func(w http.ResponseWriter, r *http.Request) {
  1057. if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
  1058. fn(w, r)
  1059. return
  1060. }
  1061. w.Header().Set("Content-Encoding", "gzip")
  1062. w.Header().Set("Content-Type", "text/javascript")
  1063. gz := gzip.NewWriter(w)
  1064. defer gz.Close()
  1065. fn(gzipResponseWriter{Writer: gz, ResponseWriter: w}, r)
  1066. }
  1067. }
  1068. func main() {
  1069. runtime.GOMAXPROCS(runtime.NumCPU())
  1070. conf, err := readConf()
  1071. if err != nil {
  1072. flag.Parse()
  1073. } else {
  1074. *saddr1 = conf.Saddr1
  1075. *saddr2 = conf.Saddr2
  1076. *saddr3 = conf.Saddr3
  1077. *saddr4 = conf.Saddr4
  1078. }
  1079. err = connectServer()
  1080. if err != nil {
  1081. log.Fatal("connect server", err)
  1082. }
  1083. //go updateTick()
  1084. s := &http.Server{
  1085. Addr: ":6062",
  1086. ReadTimeout: 10 * time.Second,
  1087. WriteTimeout: 10 * time.Second,
  1088. MaxHeaderBytes: 1 << 20,
  1089. }
  1090. //http.HandleFunc("/tickdata", tickHandler)
  1091. //http.HandleFunc("/api.php", makeGzipHandler(downHandler))
  1092. //http.HandleFunc("/symbols", symbolsHandler)
  1093. http.HandleFunc("/daydata", dayHandler)
  1094. http.HandleFunc("/h24data", h24Handler)
  1095. //http.HandleFunc("/test", testHandler)
  1096. log.Fatal(s.ListenAndServe())
  1097. }