func (w *Huobi) trade(emaShort, emaLong []float64, EMAMinThreshold float64, TresholdLevel int, length int, tradeOnlyAfterSwitch int, tradeAmount string) { currentTrend := getTrendAtIndex(emaShort, emaLong, EMAMinThreshold, TresholdLevel, length-1) logger.Debugln("currentTrend is ", currentTrend) if currentTrend > 1 { // Trend is up if currentTrend == 3 { // Trend is up, also according to the "Buy after X samples"-setting if (tradeOnlyAfterSwitch == 1) && (w.latestSolidTrend == 3) { // tradeOnlyAfterSwitch==true but the trend has not switched: Don't trade logger.Debugln("Trend has not switched (still up). The setting \"tradeOnlyAfterSwitch==true\", so do not trade...") return } w.latestSolidTrend = 3 if Option["disable_trading"] == "1" { logger.Debugln("Simulted BUY (Simulation only: no trade was made)") } else { logger.Infoln("Trend has switched, 探测到买入点") go service.TriggerTrender("探测到买入点") w.Do_buy(w.getTradePrice("buy"), tradeAmount) } //logger.Infoln("Trend is up, but no " + currency + " to spend..."); } else { logger.Debugf("Trend is up, but not for long enough (needs to be \"up\" for at least %d samples)\n", TresholdLevel) } } else if currentTrend < -1 { // Trend is down if currentTrend == -3 { // Trend is down, also according to the "Sell after X samples"-setting if (tradeOnlyAfterSwitch == 1) && (w.latestSolidTrend == -3) { // tradeOnlyAfterSwitch==true but the trend has not switched: Don't trade logger.Debugln("Trend has not switched (still down). The setting \"tradeOnlyAfterSwitch==true\", so do not trade...") return } w.latestSolidTrend = -3 if Option["disable_trading"] == "1" { logger.Infoln("Simulted SELL (Simulation only: no trade was made)") } else { logger.Infoln("Trend has switched, 探测到卖出点") go service.TriggerTrender("探测到卖出点") w.Do_sell(w.getTradePrice("sell"), tradeAmount) } //logger.Infoln("Trend is down, but no BTC to sell..."); } else { logger.Debugf("Trend is down, but not for long enough (needs to be \"down\" for at least t %d samples)\n", TresholdLevel) } } else { logger.Debugln("Trend is undefined/weak") } }
func RunCreateVm(ctx context.Context, vmDeviceId uint) error { repo, ok := middleware.RepoFromContext(ctx) if !ok { return errors.New("内部服务器错误") } logger, ok := middleware.LoggerFromContext(ctx) if !ok { return errors.New("内部服务器错误") } vmDevice, err := repo.GetVmDeviceById(vmDeviceId) if err != nil { return err } device, err := repo.GetDeviceById(vmDevice.DeviceID) if err != nil { return err } var cmdFormat = `LANG=C virt-install --connect qemu+ssh://root@%s/system \ --name=%s \ --os-type=windows \ --vcpus=%d \ --ram=%d \ --hvm \ --boot hd,network,menu=on \ --accelerate \ --graphics vnc,listen=0.0.0.0,port=%s \ --noautoconsole \ --autostart \ --network bridge=br0,model=virtio,mac=%s \ --disk path=/dev/VolGroup0/%s,device=disk,bus=virtio,cache=none,sparse=false,format=raw` var cmd = fmt.Sprintf(cmdFormat, device.Ip, vmDevice.Hostname, vmDevice.CpuCoresNumber, vmDevice.MemoryCurrent, vmDevice.VncPort, vmDevice.Mac, vmDevice.Hostname) logger.Debugf("create vm:%s", cmd) var runResult = "执行脚本:\n" + cmd bytes, err := util.ExecScript(cmd) logger.Debugf("create result:%s", string(bytes)) runResult += "\n\n" + "执行结果:\n" + string(bytes) if err != nil { logger.Errorf("create error:%s", err.Error()) runResult += "\n\n" + "错误信息:\n" + err.Error() return errors.New(runResult) } return nil }
func RunCreateVol(ctx context.Context, vmDeviceId uint) error { repo, ok := middleware.RepoFromContext(ctx) if !ok { return errors.New("内部服务器错误") } logger, ok := middleware.LoggerFromContext(ctx) if !ok { return errors.New("内部服务器错误") } conf, ok := middleware.ConfigFromContext(ctx) if !ok { return errors.New("内部服务器错误") } vmDevice, err := repo.GetVmDeviceById(vmDeviceId) if err != nil { return err } device, err := repo.GetDeviceById(vmDevice.DeviceID) if err != nil { return err } storage := conf.Vm.Storage if storage == "" { storage = "guest_images_lvm" } var cmdFormat = `LANG=C virsh --connect qemu+ssh://root@%s/system vol-create-as %s %s %dG` var cmd = fmt.Sprintf(cmdFormat, device.Ip, storage, vmDevice.Hostname, vmDevice.DiskSize) logger.Debugf("vm create vol:%s", cmd) var runResult = "执行脚本:\n" + cmd bytes, err := util.ExecScript(cmd) logger.Debugf("create result:%s", string(bytes)) runResult += "\n\n" + "执行结果:\n" + string(bytes) if err != nil { logger.Errorf("create error:%s", err.Error()) runResult += "\n\n" + "错误信息:\n" + err.Error() return errors.New(runResult) } return nil }
// 发表评论。入topics_reply库,更新topics和topics_ex库 // objname 注册的评论对象名 func PostComment(objid, objtype, uid int, content string, objname string) error { comment := model.NewComment() comment.Objid = objid comment.Objtype = objtype comment.Uid = uid comment.Content = content // TODO:评论楼层怎么处理,避免冲突?最后的楼层信息保存在内存中? // 暂时只是从数据库中取出最后的评论楼层 stringBuilder := util.NewBuffer() stringBuilder.Append("objid=").AppendInt(objid).Append(" AND objtype=").AppendInt(objtype) tmpCmt, err := model.NewComment().Where(stringBuilder.String()).Order("ctime DESC").Find() if err != nil { logger.Errorln("post comment service error:", err) return err } else { comment.Floor = tmpCmt.Floor + 1 } // 入评论库 cid, err := comment.Insert() if err != nil { logger.Errorln("post comment service error:", err) return err } // 回调,不关心处理结果(有些对象可能不需要回调) if commenter, ok := commenters[objname]; ok { logger.Debugf("评论[objid:%d] [objtype:%d] [uid:%d] 成功,通知被评论者更新", objid, objtype, uid) go commenter.UpdateComment(cid, objid, uid, time.Now().Format("2006-01-02 15:04:05")) } return nil }
// 登录;成功返回用户登录信息(user_login) func Login(username, passwd string) (*model.UserLogin, error) { userLogin := model.NewUserLogin() err := userLogin.Where("username="******" OR email=" + username).Find() if err != nil { logger.Errorf("用户 %s 登录错误:%s", username, err) return nil, errors.New("内部错误,请稍后再试!") } // 校验用户 if userLogin.Uid == 0 { logger.Infof("用户名 %s 不存在", username) return nil, ErrUsername } passcode := userLogin.GetPasscode() md5Passwd := util.Md5(passwd + passcode) logger.Debugf("passwd: %s, passcode: %s, md5passwd: %s, dbpasswd: %s", passwd, passcode, md5Passwd, userLogin.Passwd) if md5Passwd != userLogin.Passwd { logger.Infof("用户名 %s 填写的密码错误", username) return nil, ErrPasswd } // 登录,活跃度+1 go IncUserWeight("uid="+strconv.Itoa(userLogin.Uid), 1) return userLogin, nil }
// Increment 增加/减少 某个字段的值 func (this *Dao) Increment(field string, num int) error { if num == 0 { return errors.New("dao Increment(`num`不能为0)") } where := this.where if where != "" { where = "WHERE " + where } setClause := fmt.Sprintf("`%s`=`%s`", field, field) if num > 0 { setClause += fmt.Sprintf("+%d", num) } else { setClause += fmt.Sprintf("-%d", num) } strSql := fmt.Sprintf("UPDATE `%s` SET %s %s", this.tablename, setClause, where) logger.Debugln("Increment sql:", strSql) err := this.Open() if err != nil { return err } defer this.Close() result, err := this.Exec(strSql, this.whereVal...) if err != nil { return err } affected, err := result.RowsAffected() if err != nil { return err } if affected == 0 { return errors.New("dao Increment 没有更新任何数据!") } logger.Debugf("成功 increment `%s`表 %d 条记录", this.tablename, affected) return nil }
func parse_trade(trades []interface{}, trades_data *[60]Trade) bool { for k, v := range trades { switch vt := v.(type) { case map[string]interface{}: logger.Debugln(k, " is a map:") logger.Debugf("trades[%d]\n", k) for ik, iv := range vt { switch ik { case "time": trades_data[k].Time = iv.(string) case "price": trades_data[k].Price = util.InterfaceToFloat64(iv) case "amount": trades_data[k].Amount = util.InterfaceToFloat64(iv) case "type": trades_data[k].Type = iv.(string) } } default: logger.Errorln(k, v) logger.Fatalln("don't know the type, crash!") return false } } return true }
// 登录 // uri : /account/login func LoginHandler(rw http.ResponseWriter, req *http.Request) { username := req.FormValue("username") if username == "" || req.Method != "POST" { req.Form.Set(filter.CONTENT_TPL_KEY, "/template/login.html") return } // 处理用户登录 passwd := req.FormValue("passwd") userLogin, err := service.Login(username, passwd) if err != nil { req.Form.Set(filter.CONTENT_TPL_KEY, "/template/login.html") filter.SetData(req, map[string]interface{}{"username": username, "error": err.Error()}) return } logger.Debugf("remember_me is %q\n", req.FormValue("remember_me")) // 登录成功,种cookie setCookie(rw, req, userLogin.Username) // 支持跳转到源页面 uri := "/" values := filter.NewFlash(rw, req).Flashes("uri") if values != nil { uri = values[0].(string) } logger.Debugln("uri===", uri) util.Redirect(rw, req, uri) }
func parse_buy_sell(sells_buys []interface{}, sells_buys_data *[10]SellBuy) bool { for k, v := range sells_buys { switch vt := v.(type) { case map[string]interface{}: logger.Debugln(k, " is a map:") logger.Debugf("sells/buys[%d]\n", k) for ik, iv := range vt { switch ik { case "price": sells_buys_data[k].Price = util.InterfaceToFloat64(iv) case "level": sells_buys_data[k].Level = util.InterfaceToFloat64(iv) case "amount": sells_buys_data[k].Amount = util.InterfaceToFloat64(iv) } } default: logger.Errorln(k, v) logger.Fatalln("don't know the type, crash!") return false } } return true }
// just f**k the huobi old shit bug func parse_topsell(topsells map[string]interface{}, topsells_data *[5]Top_buy_sell) bool { index := 4 for k, v := range topsells { switch vt := v.(type) { case map[string]interface{}: logger.Debugln(k, " is a map:") logger.Debugf("topsells[%s]\n", k) for ik, iv := range vt { logger.Debugln(ik, iv) switch ik { case "price": topsells_data[index].Price = util.InterfaceToFloat64(iv) case "amount": topsells_data[index].Amount = util.InterfaceToFloat64(iv) case "level": topsells_data[index].Level = util.InterfaceToFloat64(iv) case "accu": topsells_data[index].Accu = util.InterfaceToFloat64(iv) } } index-- default: logger.Errorln(k, v) logger.Fatalln("don't know the type, crash!") return false } } return true }
// 持久化 entity 到数据库 func (this *Dao) Persist(entity interface{}) error { strSql, args, err := genPersistParams(entity) if err != nil { logger.Errorln("Persist error:", err) return err } logger.Debugln("Persist sql:", strSql, ";args:", args) err = this.Open() if err != nil { return err } defer this.Close() result, err := this.Exec(strSql, args...) if err != nil { return err } affected, err := result.RowsAffected() if err != nil { return err } logger.Debugf("成功更新了`%s`表 %d 条记录", this.tablename, affected) return nil }
// 发表评论(或回复)。 // objid 注册的评论对象 // uid 评论人 func PostComment(uid, objid int, form url.Values) (*model.Comment, error) { comment := model.NewComment() comment.Objid = objid objtype := util.MustInt(form.Get("objtype")) comment.Objtype = objtype comment.Uid = uid comment.Content = form.Get("content") // TODO:评论楼层怎么处理,避免冲突?最后的楼层信息保存在内存中? // 暂时只是从数据库中取出最后的评论楼层 stringBuilder := util.NewBuffer() stringBuilder.Append("objid=").AppendInt(objid).Append(" AND objtype=").AppendInt(objtype) tmpCmt, err := model.NewComment().Where(stringBuilder.String()).Order("ctime DESC").Find() if err != nil { logger.Errorln("post comment service error:", err) return nil, err } else { comment.Floor = tmpCmt.Floor + 1 } // 入评论库 cid, err := comment.Insert() if err != nil { logger.Errorln("post comment service error:", err) return nil, err } comment.Cid = cid comment.Ctime = util.TimeNow() decodeCmtContent(comment) // 回调,不关心处理结果(有些对象可能不需要回调) if commenter, ok := commenters[objtype]; ok { logger.Debugf("评论[objid:%d] [objtype:%d] [uid:%d] 成功,通知被评论者更新", objid, objtype, uid) go commenter.UpdateComment(cid, objid, uid, time.Now().Format("2006-01-02 15:04:05")) } // 发评论,活跃度+5 go IncUserWeight("uid="+strconv.Itoa(uid), 5) // 给被评论对象所有者发系统消息 ext := map[string]interface{}{ "objid": objid, "objtype": objtype, "cid": cid, "uid": uid, } go SendSystemMsgTo(0, objtype, ext) // @某人 发系统消息 go SendSysMsgAtUids(form.Get("uid"), ext) go SendSysMsgAtUsernames(form.Get("usernames"), ext) return comment, nil }
//restart vm func RunReStartVm(ctx context.Context, vmDeviceId uint) error { repo, ok := middleware.RepoFromContext(ctx) if !ok { return errors.New("内部服务器错误") } logger, ok := middleware.LoggerFromContext(ctx) if !ok { return errors.New("内部服务器错误") } vmDevice, err := repo.GetVmDeviceById(vmDeviceId) if err != nil { return err } device, err := repo.GetDeviceById(vmDevice.DeviceID) if err != nil { return err } var cmdFormat = `LANG=C virsh --connect qemu+ssh://root@%s/system 'destroy %s; start %s'` var cmd = fmt.Sprintf(cmdFormat, device.Ip, vmDevice.Hostname, vmDevice.Hostname) logger.Debugf("restart vm:%s", cmd) var runResult = "执行脚本:\n" + cmd bytes, err := util.ExecScript(cmd) logger.Debugf("restart result:%s", string(bytes)) runResult += "\n\n" + "执行结果:\n" + string(bytes) if err != nil { logger.Errorf("restart error:%s", err.Error()) runResult += "\n\n" + "错误信息:\n" + err.Error() return errors.New(runResult) } return nil }
// 登录 // uri : /account/login{json:(|.json)} func LoginHandler(rw http.ResponseWriter, req *http.Request) { username := req.PostFormValue("username") if username == "" || req.Method != "POST" { filter.SetData(req, map[string]interface{}{"error": "非法请求"}) req.Form.Set(filter.CONTENT_TPL_KEY, "/template/login.html") return } vars := mux.Vars(req) suffix := vars["json"] // 处理用户登录 passwd := req.PostFormValue("passwd") userLogin, err := service.Login(username, passwd) if err != nil { if suffix != "" { logger.Errorln("login error:", err) fmt.Fprint(rw, `{"ok":0,"error":"`+err.Error()+`"}`) return } req.Form.Set(filter.CONTENT_TPL_KEY, "/template/login.html") filter.SetData(req, map[string]interface{}{"username": username, "error": err.Error()}) return } logger.Debugf("remember_me is %q\n", req.FormValue("remember_me")) // 登录成功,种cookie setCookie(rw, req, userLogin.Username) if suffix != "" { fmt.Fprint(rw, `{"ok":1,"msg":"success"}`) return } // 支持跳转到源页面 uri := "/" values := filter.NewFlash(rw, req).Flashes("uri") if values != nil { uri = values[0].(string) } logger.Debugln("uri===", uri) util.Redirect(rw, req, uri) }
func (this *Dao) Delete() error { strSql := util.DeleteSql(this) logger.Debugln("Delete sql:", strSql) err := this.Open() if err != nil { return err } defer this.Close() result, err := this.Exec(strSql, append(this.colValues, this.whereVal...)...) if err != nil { return err } affected, err := result.RowsAffected() if err != nil { return err } logger.Debugf("成功删除了`%s`表 %d 条记录", this.tablename, affected) return nil }
// 将node组织成一定结构,方便前端展示 func genNodes() []map[string][]map[string]interface{} { sameParent := make(map[string][]map[string]interface{}) allParentNodes := make([]string, 0) for _, node := range model.AllNode { if node["pid"].(int) != 0 { if len(sameParent[node["parent"].(string)]) == 0 { sameParent[node["parent"].(string)] = []map[string]interface{}{node} } else { sameParent[node["parent"].(string)] = append(sameParent[node["parent"].(string)], node) } } else { allParentNodes = append(allParentNodes, node["name"].(string)) } } nodes := make([]map[string][]map[string]interface{}, 0) for _, parent := range allParentNodes { tmpMap := make(map[string][]map[string]interface{}) tmpMap[parent] = sameParent[parent] nodes = append(nodes, tmpMap) } logger.Debugf("%v\n", nodes) return nodes }
// Update 更新数据 func (this *Dao) Update() error { strSql := util.UpdateSql(this) if strSql == "" { // 没有字段需要更新,当作更新成功 logger.Errorln("no field need update") return nil } logger.Debugln("Update sql:", strSql) err := this.Open() if err != nil { return err } defer this.Close() result, err := this.Exec(strSql, append(this.colValues, this.whereVal...)...) if err != nil { return err } affected, err := result.RowsAffected() if err != nil { return err } logger.Debugf("成功更新了`%s`表 %d 条记录", this.tablename, affected) return nil }
func InterfaceToFloat64(iv interface{}) (retV float64) { logger.Debugf("iv=%v\n", iv) switch ivTo := iv.(type) { case float64: logger.Traceln(ivTo, "is float64") retV = ivTo case string: logger.Traceln(ivTo, "is string") { var err error retV, err = strconv.ParseFloat(ivTo, 64) if err != nil { logger.Fatalln("convert failed, crash!") return 0 } } default: logger.Fatalln("don't know the type, crash!") return 0 } return retV }