You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
724 lines
22 KiB
724 lines
22 KiB
2 months ago
|
package selfContract
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"github.com/shopspring/decimal"
|
||
|
"math/rand"
|
||
|
"sync"
|
||
|
"time"
|
||
|
"wss-pool/cmd/common"
|
||
|
"wss-pool/cmd/websocketservice"
|
||
|
"wss-pool/dictionary"
|
||
|
"wss-pool/internal/data/business"
|
||
|
"wss-pool/internal/model"
|
||
|
red "wss-pool/internal/redis"
|
||
|
"wss-pool/logging/applogger"
|
||
|
"wss-pool/pkg/model/market"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
proportion int32 = 10000 //调价原价比例
|
||
|
step int32 = 20 //调价指数
|
||
|
digits int32 = 4 //保留小数位数
|
||
|
numPrices int = 20 //生成随机价格数量
|
||
|
defaultStep float64 = 0.001 // 默认波动率
|
||
|
PushFrequency int = 3 //S
|
||
|
TimeRemaining int64 = 20 //s
|
||
|
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
contractChan = make(chan string)
|
||
|
SelfContractCode string //合约代码
|
||
|
FaceValue decimal.Decimal // 面值合约
|
||
|
InitialPrice decimal.Decimal // 初始价格
|
||
|
KLineMap = make(map[string]KlineLowHigh)
|
||
|
ClosePrices decimal.Decimal //当前价格 //做调价终止值使用
|
||
|
OldFiveMin int64 //记录K线时间搓
|
||
|
OldFifteenMin int64
|
||
|
OldThirtyMin int64
|
||
|
OldOneHour int64
|
||
|
OldFourHour int64
|
||
|
OldDay int64
|
||
|
OldWeek int64
|
||
|
OldMon int64
|
||
|
IsRun bool
|
||
|
ContractMap = make(map[string]bool) //保存领取的任务
|
||
|
lock sync.Mutex
|
||
|
endChan = make(chan string)
|
||
|
)
|
||
|
|
||
|
type KlineLowHigh struct {
|
||
|
Low decimal.Decimal
|
||
|
High decimal.Decimal
|
||
|
ID int64
|
||
|
Vol decimal.Decimal
|
||
|
Amount decimal.Decimal
|
||
|
Count decimal.Decimal
|
||
|
TradeTurnover decimal.Decimal
|
||
|
Open decimal.Decimal
|
||
|
}
|
||
|
|
||
|
type ConstructorContract struct {
|
||
|
SelfContractCode string `json:"selfContractCode"` //虚拟合约
|
||
|
BeginTime string `json:"beginTime"` //开始时间
|
||
|
EndTime string `json:"endTime"` //结束时间
|
||
|
MaxPrice decimal.Decimal `json:"maxPrices"`
|
||
|
MinPrice decimal.Decimal `json:"minPrice"`
|
||
|
MaxPriceStr string `json:"maxPrice"`
|
||
|
}
|
||
|
|
||
|
func NewSelfContract() {
|
||
|
//首次启动
|
||
|
go func() {
|
||
|
this := new(ConstructorContract)
|
||
|
this.MinPrice = InitialPrice
|
||
|
this.SelfContractCode = SelfContractCode
|
||
|
this.defaultContract()
|
||
|
}()
|
||
|
for {
|
||
|
t := time.NewTimer(1 * time.Minute)
|
||
|
<-t.C
|
||
|
go func() {
|
||
|
if IsRun {
|
||
|
applogger.Info("已有调价在运行, 该次调价不能运行")
|
||
|
return
|
||
|
}
|
||
|
result := getData()
|
||
|
fmt.Println(result)
|
||
|
for _, v := range result {
|
||
|
if v.TradeName != SelfContractCode {
|
||
|
applogger.Info("parametric inequality")
|
||
|
continue
|
||
|
}
|
||
|
end, _ := common.TimeStrToTimes(v.EndTime)
|
||
|
if end.Unix() <= time.Now().Unix() {
|
||
|
applogger.Info("该调价已过期")
|
||
|
continue
|
||
|
}
|
||
|
if _, ok := ContractMap[fmt.Sprintf("%s-%d", v.TradeName, end.Unix())]; ok {
|
||
|
applogger.Info("该任务正在运行", fmt.Sprintf("%s-%d", v.TradeName, end.Unix()))
|
||
|
continue
|
||
|
}
|
||
|
ContractMap[fmt.Sprintf("%s-%d", v.TradeName, end.Unix())] = true //保存任务
|
||
|
begin, _ := common.TimeStrToTimes(v.BeginTime)
|
||
|
if begin.Unix() < common.TimeToNow() {
|
||
|
applogger.Info("该调价已过期")
|
||
|
continue
|
||
|
} else if end.Unix() <= begin.Unix() {
|
||
|
applogger.Info("begin end 有误")
|
||
|
continue
|
||
|
}
|
||
|
maxPrice, _ := decimal.NewFromString(v.MaxPrice)
|
||
|
//if maxPrice.LessThan(InitialPrice) {
|
||
|
// applogger.Info("调价有误",v.MaxPrice)
|
||
|
// continue
|
||
|
//}
|
||
|
//等待到开始时间
|
||
|
applogger.Info("等待到begin time ", v.BeginTime, v.EndTime)
|
||
|
IsRun = true // 调价任务已开启
|
||
|
time.Sleep(begin.Sub(common.TimeToNows()))
|
||
|
contractChan <- "constructorStart"
|
||
|
this := new(ConstructorContract)
|
||
|
this.SelfContractCode = SelfContractCode
|
||
|
this.EndTime = v.EndTime
|
||
|
this.MinPrice = InitialPrice
|
||
|
this.MaxPrice = maxPrice
|
||
|
this.BeginTime = v.BeginTime
|
||
|
this.constructor(begin, end)
|
||
|
//更改状态
|
||
|
contract := model.NewContractMarket()
|
||
|
contract.ID = v.ID
|
||
|
contract.UpdateIsGetOne()
|
||
|
}
|
||
|
if len(result) > 0 && IsRun {
|
||
|
IsRun = false
|
||
|
this := new(ConstructorContract)
|
||
|
this.MinPrice = InitialPrice
|
||
|
this.SelfContractCode = SelfContractCode
|
||
|
this.defaultContract()
|
||
|
}
|
||
|
}()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func getData() []model.ContractMarket {
|
||
|
contract := model.NewContractMarket()
|
||
|
contract.IsType = model.Contract
|
||
|
contract.TradeName = SelfContractCode
|
||
|
result := contract.List()
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
// 规定启动
|
||
|
func (this *ConstructorContract) constructor(begin, end time.Time) {
|
||
|
applogger.Info("开始调价。。。", "结束时间:", this.EndTime, "当前价格:", this.MinPrice, "最终价格", this.MaxPrice)
|
||
|
totalDuration := end.Sub(common.TimeToNows())
|
||
|
closePrice := this.MinPrice
|
||
|
highPrice := this.MinPrice
|
||
|
lowPrice := this.MinPrice
|
||
|
oldPrice := this.MinPrice
|
||
|
var openPrice decimal.Decimal
|
||
|
//var temporalFrequency = time.Duration(PushFrequency) * time.Second
|
||
|
timeInterval := float64(totalDuration) / float64(time.Minute)
|
||
|
delta := this.MaxPrice.Sub(closePrice).Div(decimal.NewFromFloat(timeInterval))
|
||
|
applogger.Debug("-------------------------delta", delta)
|
||
|
fluctuation := closePrice.Mul(decimal.NewFromInt32(step).Div(decimal.NewFromInt32(proportion))).Round(digits)
|
||
|
applogger.Info("timeInterval", timeInterval, "delta", delta, "fluctuation", fluctuation)
|
||
|
// 开始进行调价
|
||
|
for !this.MaxPrice.Equal(InitialPrice) || end.Unix() > common.TimeToNows().Unix() {
|
||
|
// 生成随机价格波动
|
||
|
fmt.Println("当前价格", InitialPrice)
|
||
|
prices := this.generateRandomPrices(InitialPrice, fluctuation, delta)
|
||
|
openPrice = InitialPrice
|
||
|
this.GetAllLowHigh(highPrice, lowPrice)
|
||
|
nonVanishing(lowPrice)
|
||
|
numFrequency := int(60) / PushFrequency
|
||
|
ClearTotal()
|
||
|
for i := 1; i <= numFrequency; i++ {
|
||
|
//go func(prices []decimal.Decimal, closePrice, openPrice, highPrice, lowPrice, oldPrice decimal.Decimal, this *ConstructorContract) {
|
||
|
start := time.Now() // 获取当前时间
|
||
|
rand.New(rand.NewSource(time.Now().UnixNano()))
|
||
|
key := rand.Intn(len(prices))
|
||
|
closePrice = prices[key]
|
||
|
// applogger.Info("实际落盘价:", closePrice)
|
||
|
//if (closePrice.Sub(this.MaxPrice)).Mul(delta).GreaterThan(decimal.NewFromInt32(0)){
|
||
|
// closePrice = this.MaxPrice
|
||
|
//}
|
||
|
//当只剩 20 秒
|
||
|
if (end.Unix() - common.TimeToNows().Unix()) < TimeRemaining {
|
||
|
closePrice = this.MaxPrice
|
||
|
}
|
||
|
FaceValue = common.GetFaceValue(closePrice)
|
||
|
//生成深度、Trade Detail 数据
|
||
|
CreateDepth(oldPrice, closePrice)
|
||
|
//k 线 详情
|
||
|
this.pullStorage(closePrice, openPrice, highPrice, lowPrice, oldPrice, prices)
|
||
|
oldPrice = closePrice
|
||
|
applogger.Debug("目标价格", this.MaxPrice, "当前价格", closePrice, "调价结束时间", this.EndTime, "i", i, time.Now().Format("2006-01-02 15:04:05"))
|
||
|
//更新市价
|
||
|
lock.Lock()
|
||
|
InitialPrice = closePrice
|
||
|
lock.Unlock()
|
||
|
if end.Unix() <= common.TimeToNows().Unix() {
|
||
|
break
|
||
|
}
|
||
|
fmt.Println("Run time: ", time.Since(start))
|
||
|
s := float64(PushFrequency) - time.Since(start).Seconds()
|
||
|
if s > float64(0) {
|
||
|
applogger.Debug("停留 秒", s)
|
||
|
time.Sleep(time.Duration(s) * time.Second)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (this *ConstructorContract) defaultContract() {
|
||
|
closePrice := this.MinPrice
|
||
|
highPrice := this.MinPrice
|
||
|
lowPrice := this.MinPrice
|
||
|
oldPrice := this.MinPrice
|
||
|
var openPrice decimal.Decimal
|
||
|
//var temporalFrequency = time.Duration(PushFrequency) * time.Second
|
||
|
for {
|
||
|
select {
|
||
|
case _, ok := <-contractChan: // 从管道接收值
|
||
|
if ok {
|
||
|
applogger.Info("calculateContractPrice start,defaultContract")
|
||
|
return
|
||
|
}
|
||
|
default:
|
||
|
//fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
|
||
|
rand.New(rand.NewSource(time.Now().UnixNano()))
|
||
|
openPrice = InitialPrice
|
||
|
Loop:
|
||
|
prices := calculateContractPrice(InitialPrice)
|
||
|
fmt.Println("开盘价", InitialPrice)
|
||
|
//更新落盘价、开盘价、最高价和最低价
|
||
|
key := rand.Intn(numPrices)
|
||
|
highPrices := this.getMaxPrices(openPrice, prices)
|
||
|
lowPrices := this.getMinPrices(openPrice, prices)
|
||
|
//被2整除 涨
|
||
|
if key%2 == 0 {
|
||
|
highPrice = this.getMaxPrice(openPrice, highPrices)
|
||
|
lowPrice = openPrice
|
||
|
prices = highPrices
|
||
|
} else {
|
||
|
highPrice = openPrice
|
||
|
lowPrice = this.getMinPrice(openPrice, lowPrices)
|
||
|
prices = lowPrices
|
||
|
}
|
||
|
if len(prices) <= 0 {
|
||
|
goto Loop
|
||
|
}
|
||
|
this.GetAllLowHigh(highPrice, lowPrice)
|
||
|
nonVanishing(lowPrice)
|
||
|
numFrequency := int(60) / PushFrequency
|
||
|
ClearTotal()
|
||
|
for i := 1; i <= numFrequency; i++ {
|
||
|
// start := time.Now() // 获取当前时间
|
||
|
// fmt.Println("Run time: ", time.Since(start))
|
||
|
go func(prices []decimal.Decimal, closePrice, openPrice, highPrice, lowPrice, oldPrice decimal.Decimal, this *ConstructorContract) {
|
||
|
//更新市价
|
||
|
//fmt.Println(closePrice)
|
||
|
rand.New(rand.NewSource(time.Now().UnixNano()))
|
||
|
key := rand.Intn(len(prices))
|
||
|
closePrice = prices[key]
|
||
|
lock.Lock()
|
||
|
InitialPrice = closePrice
|
||
|
lock.Unlock()
|
||
|
FaceValue = common.GetFaceValue(closePrice)
|
||
|
//生成深度、Trade Detail 数据
|
||
|
CreateDepth(oldPrice, closePrice)
|
||
|
//fmt.Println("Run time: ", time.Since(start))
|
||
|
this.pullStorage(closePrice, openPrice, highPrice, lowPrice, oldPrice, prices)
|
||
|
//fmt.Println("123123123 ", closePrice,openPrice, highPrice, lowPrice, oldPrice)
|
||
|
oldPrice = closePrice
|
||
|
}(prices, closePrice, openPrice, highPrice, lowPrice, oldPrice, this)
|
||
|
time.Sleep(time.Duration(int64(PushFrequency)) * time.Second)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func generateRandomStep(min, max decimal.Decimal) decimal.Decimal {
|
||
|
rand.New(rand.NewSource(time.Now().UnixNano()))
|
||
|
return min.Add(decimal.NewFromFloat(rand.Float64()).Mul(max.Sub(min)))
|
||
|
}
|
||
|
|
||
|
// 计算虚拟合约价格
|
||
|
func calculateContractPrice(basePrice decimal.Decimal) []decimal.Decimal {
|
||
|
prices := make([]decimal.Decimal, 0)
|
||
|
max := basePrice.Mul(decimal.NewFromFloat(defaultStep)).Round(digits)
|
||
|
min := max.Neg()
|
||
|
for i := 0; i < numPrices; i++ {
|
||
|
price := basePrice.Add(generateRandomStep(max, min)).Round(digits)
|
||
|
prices = append(prices, price)
|
||
|
}
|
||
|
return prices
|
||
|
}
|
||
|
|
||
|
func getOpen(timestamp int64, period string) decimal.Decimal {
|
||
|
tick := GetNewPriceAll(SelfContractCode, period)
|
||
|
open := InitialPrice
|
||
|
if len(tick) > 0 {
|
||
|
switch tick[0].Code {
|
||
|
case timestamp:
|
||
|
open, _ = decimal.NewFromString(tick[0].Open)
|
||
|
default:
|
||
|
open, _ = decimal.NewFromString(tick[0].Close)
|
||
|
}
|
||
|
}
|
||
|
return open
|
||
|
}
|
||
|
|
||
|
func nonVanishing(low decimal.Decimal) {
|
||
|
for k, v := range KLineMap {
|
||
|
if v.Low.IsZero() {
|
||
|
v.Low = low
|
||
|
}
|
||
|
KLineMap[k] = v
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (this *ConstructorContract) GetAllLowHigh(high, low decimal.Decimal) {
|
||
|
//初始化
|
||
|
if len(KLineMap) == 0 {
|
||
|
KLineMap["1min"] = KlineLowHigh{
|
||
|
ID: common.GenerateSingaporeMinuteTimestamp(),
|
||
|
Low: low,
|
||
|
High: high,
|
||
|
Vol: decimal.NewFromInt(0),
|
||
|
Amount: decimal.NewFromInt(0),
|
||
|
Count: decimal.NewFromInt(0),
|
||
|
TradeTurnover: decimal.NewFromInt(0),
|
||
|
Open: InitialPrice,
|
||
|
}
|
||
|
|
||
|
to := common.GenerateSingaporeFiveMinTimestamp()
|
||
|
from := to - int64(5*60)
|
||
|
low, high, vol, amount, count, tradeTurnover := GetTimeNewPrice(this.SelfContractCode, from, to, "1min")
|
||
|
KLineMap["5min"] = KlineLowHigh{
|
||
|
ID: to,
|
||
|
Low: low,
|
||
|
High: high,
|
||
|
Vol: vol,
|
||
|
Amount: amount,
|
||
|
Count: count,
|
||
|
TradeTurnover: tradeTurnover,
|
||
|
Open: getOpen(to, "5min"),
|
||
|
}
|
||
|
OldFiveMin = to
|
||
|
|
||
|
to = common.GenerateSingaporeFifteenMinTimestamp()
|
||
|
from = to - int64(15*60)
|
||
|
low, high, vol, amount, count, tradeTurnover = GetTimeNewPrice(this.SelfContractCode, from, to, "5min")
|
||
|
KLineMap["15min"] = KlineLowHigh{
|
||
|
ID: to,
|
||
|
Low: low,
|
||
|
High: high,
|
||
|
Vol: vol,
|
||
|
Amount: amount,
|
||
|
Count: count,
|
||
|
TradeTurnover: tradeTurnover,
|
||
|
Open: getOpen(to, "15min"),
|
||
|
}
|
||
|
OldFifteenMin = to
|
||
|
|
||
|
to = common.GenerateSingaporeThirtyMinTimestamp()
|
||
|
from = to - int64(30*60)
|
||
|
low, high, vol, amount, count, tradeTurnover = GetTimeNewPrice(this.SelfContractCode, from, to, "15min")
|
||
|
KLineMap["30min"] = KlineLowHigh{
|
||
|
ID: to,
|
||
|
Low: low,
|
||
|
High: high,
|
||
|
Vol: vol,
|
||
|
Amount: amount,
|
||
|
Count: count,
|
||
|
TradeTurnover: tradeTurnover,
|
||
|
Open: getOpen(to, "30min"),
|
||
|
}
|
||
|
OldThirtyMin = to
|
||
|
|
||
|
from = common.GenerateSingaporeHourTimestamp()
|
||
|
to = from + int64(60*59)
|
||
|
low, high, vol, amount, count, tradeTurnover = GetTimeNewPrice(this.SelfContractCode, from, to, "30min")
|
||
|
KLineMap["60min"] = KlineLowHigh{
|
||
|
ID: from,
|
||
|
Low: low,
|
||
|
High: high,
|
||
|
Vol: vol,
|
||
|
Amount: amount,
|
||
|
Count: count,
|
||
|
TradeTurnover: tradeTurnover,
|
||
|
Open: getOpen(from, "60min"),
|
||
|
}
|
||
|
OldOneHour = from
|
||
|
|
||
|
to = common.GenerateSingaporeFourHourTimestamp()
|
||
|
from = to - (4 * 60 * 60)
|
||
|
low, high, vol, amount, count, tradeTurnover = GetTimeNewPrice(this.SelfContractCode, from, to, "60min")
|
||
|
KLineMap["4hour"] = KlineLowHigh{
|
||
|
ID: from,
|
||
|
Low: low,
|
||
|
High: high,
|
||
|
Vol: vol,
|
||
|
Amount: amount,
|
||
|
Count: count,
|
||
|
TradeTurnover: tradeTurnover,
|
||
|
Open: getOpen(from, "4hour"),
|
||
|
}
|
||
|
OldFourHour = from
|
||
|
|
||
|
from = common.GenerateSingaporeDayTimestamp("")
|
||
|
to = from + int64(60*60*24-1)
|
||
|
low, high, vol, amount, count, tradeTurnover = GetTimeNewPrice(this.SelfContractCode, from, to, "4hour")
|
||
|
KLineMap["1day"] = KlineLowHigh{
|
||
|
ID: from,
|
||
|
Low: low,
|
||
|
High: high,
|
||
|
Vol: vol,
|
||
|
Amount: amount,
|
||
|
Count: count,
|
||
|
TradeTurnover: tradeTurnover,
|
||
|
Open: getOpen(from, "1day"),
|
||
|
}
|
||
|
OldDay = from
|
||
|
|
||
|
from = common.GenerateSingaporeMonTimestamp()
|
||
|
to = common.TimeToNow()
|
||
|
low, high, vol, amount, count, tradeTurnover = GetTimeNewPrice(this.SelfContractCode, from, to, "1week")
|
||
|
KLineMap["1mon"] = KlineLowHigh{
|
||
|
ID: from,
|
||
|
Low: low,
|
||
|
High: high,
|
||
|
Vol: vol,
|
||
|
Amount: amount,
|
||
|
Count: count,
|
||
|
TradeTurnover: tradeTurnover,
|
||
|
Open: getOpen(from, "1mon"),
|
||
|
}
|
||
|
OldMon = from
|
||
|
|
||
|
from = common.GetWeekTimestamp()
|
||
|
to = common.TimeToNow()
|
||
|
low, high, vol, amount, count, tradeTurnover = GetTimeNewPrice(this.SelfContractCode, from, to, "1day")
|
||
|
KLineMap["1week"] = KlineLowHigh{
|
||
|
ID: from,
|
||
|
Low: low,
|
||
|
High: high,
|
||
|
Vol: vol,
|
||
|
Amount: amount,
|
||
|
Count: count,
|
||
|
TradeTurnover: tradeTurnover,
|
||
|
Open: getOpen(from, "1week"),
|
||
|
}
|
||
|
OldWeek = from
|
||
|
}
|
||
|
|
||
|
for k, v := range KLineMap {
|
||
|
switch k {
|
||
|
case "1min":
|
||
|
v.ID = common.GenerateSingaporeMinuteTimestamp()
|
||
|
v.Vol = decimal.NewFromFloat(0)
|
||
|
v.Amount = decimal.NewFromFloat(0)
|
||
|
v.Count = decimal.NewFromFloat(0)
|
||
|
v.TradeTurnover = decimal.NewFromFloat(0)
|
||
|
v.High = high
|
||
|
v.Low = low
|
||
|
v.Open = InitialPrice
|
||
|
case "5min":
|
||
|
v.ID = common.GenerateSingaporeFiveMinTimestamp()
|
||
|
if v.ID > OldFiveMin {
|
||
|
//新时间节点更新
|
||
|
v.Vol = decimal.NewFromFloat(0)
|
||
|
v.Amount = decimal.NewFromFloat(0)
|
||
|
v.Count = decimal.NewFromFloat(0)
|
||
|
v.TradeTurnover = decimal.NewFromFloat(0)
|
||
|
v.Low = low
|
||
|
v.High = high
|
||
|
v.Open = getOpen(v.ID, k)
|
||
|
OldFiveMin = v.ID
|
||
|
}
|
||
|
if v.Low.GreaterThan(low) {
|
||
|
v.Low = low
|
||
|
}
|
||
|
if v.High.LessThan(high) {
|
||
|
v.High = high
|
||
|
}
|
||
|
case "15min":
|
||
|
v.ID = common.GenerateSingaporeFifteenMinTimestamp()
|
||
|
if v.ID > OldFifteenMin {
|
||
|
v.Vol = decimal.NewFromFloat(0)
|
||
|
v.Amount = decimal.NewFromFloat(0)
|
||
|
v.Count = decimal.NewFromFloat(0)
|
||
|
v.TradeTurnover = decimal.NewFromFloat(0)
|
||
|
v.Low = low
|
||
|
v.High = high
|
||
|
v.Open = getOpen(v.ID, k)
|
||
|
OldFifteenMin = v.ID
|
||
|
}
|
||
|
if v.Low.GreaterThan(low) {
|
||
|
v.Low = low
|
||
|
}
|
||
|
if v.High.LessThan(high) {
|
||
|
v.High = high
|
||
|
}
|
||
|
case "30min":
|
||
|
v.ID = common.GenerateSingaporeThirtyMinTimestamp()
|
||
|
if v.ID > OldThirtyMin {
|
||
|
v.Vol = decimal.NewFromFloat(0)
|
||
|
v.Amount = decimal.NewFromFloat(0)
|
||
|
v.Count = decimal.NewFromFloat(0)
|
||
|
v.TradeTurnover = decimal.NewFromFloat(0)
|
||
|
v.Low = low
|
||
|
v.High = high
|
||
|
v.Open = getOpen(v.ID, k)
|
||
|
OldThirtyMin = v.ID
|
||
|
}
|
||
|
if v.Low.GreaterThan(low) {
|
||
|
v.Low = low
|
||
|
}
|
||
|
if v.High.LessThan(high) {
|
||
|
v.High = high
|
||
|
}
|
||
|
case "60min":
|
||
|
v.ID = common.GenerateSingaporeHourTimestamp()
|
||
|
if v.ID > OldOneHour {
|
||
|
v.Vol = decimal.NewFromFloat(0)
|
||
|
v.Amount = decimal.NewFromFloat(0)
|
||
|
v.Count = decimal.NewFromFloat(0)
|
||
|
v.TradeTurnover = decimal.NewFromFloat(0)
|
||
|
v.Low = low
|
||
|
v.High = high
|
||
|
v.Open = getOpen(v.ID, k)
|
||
|
OldOneHour = v.ID
|
||
|
}
|
||
|
if v.Low.GreaterThan(low) {
|
||
|
v.Low = low
|
||
|
}
|
||
|
if v.High.LessThan(high) {
|
||
|
v.High = high
|
||
|
}
|
||
|
case "4hour":
|
||
|
v.ID = common.GenerateSingaporeFourHourTimestamp() - (4 * 60 * 60)
|
||
|
if v.ID > OldFourHour {
|
||
|
v.Vol = decimal.NewFromFloat(0)
|
||
|
v.Amount = decimal.NewFromFloat(0)
|
||
|
v.Count = decimal.NewFromFloat(0)
|
||
|
v.TradeTurnover = decimal.NewFromFloat(0)
|
||
|
v.Low = low
|
||
|
v.High = high
|
||
|
v.Open = getOpen(v.ID, k)
|
||
|
OldFourHour = v.ID
|
||
|
}
|
||
|
if v.Low.GreaterThan(low) {
|
||
|
v.Low = low
|
||
|
}
|
||
|
if v.High.LessThan(high) {
|
||
|
v.High = high
|
||
|
}
|
||
|
case "1day":
|
||
|
v.ID = common.GenerateSingaporeDayTimestamp("")
|
||
|
if v.ID > OldDay {
|
||
|
v.Vol = decimal.NewFromFloat(0)
|
||
|
v.Amount = decimal.NewFromFloat(0)
|
||
|
v.Count = decimal.NewFromFloat(0)
|
||
|
v.TradeTurnover = decimal.NewFromFloat(0)
|
||
|
v.Low = low
|
||
|
v.High = high
|
||
|
v.Open = getOpen(v.ID, k)
|
||
|
OldDay = v.ID
|
||
|
}
|
||
|
if v.Low.GreaterThan(low) {
|
||
|
v.Low = low
|
||
|
}
|
||
|
if v.High.LessThan(high) {
|
||
|
v.High = high
|
||
|
}
|
||
|
case "1week":
|
||
|
v.ID = common.GetWeekTimestamp()
|
||
|
if v.ID > OldWeek {
|
||
|
v.Vol = decimal.NewFromFloat(0)
|
||
|
v.Amount = decimal.NewFromFloat(0)
|
||
|
v.Count = decimal.NewFromFloat(0)
|
||
|
v.TradeTurnover = decimal.NewFromFloat(0)
|
||
|
v.Low = low
|
||
|
v.High = high
|
||
|
v.Open = getOpen(v.ID, k)
|
||
|
OldWeek = v.ID
|
||
|
}
|
||
|
if v.Low.GreaterThan(low) {
|
||
|
v.Low = low
|
||
|
}
|
||
|
if v.High.LessThan(high) {
|
||
|
v.High = high
|
||
|
}
|
||
|
case "1mon":
|
||
|
v.ID = common.GenerateSingaporeMonTimestamp()
|
||
|
if v.ID > OldMon {
|
||
|
v.Vol = decimal.NewFromFloat(0)
|
||
|
v.Amount = decimal.NewFromFloat(0)
|
||
|
v.Count = decimal.NewFromFloat(0)
|
||
|
v.TradeTurnover = decimal.NewFromFloat(0)
|
||
|
v.Low = low
|
||
|
v.High = high
|
||
|
v.Open = getOpen(v.ID, k)
|
||
|
OldMon = v.ID
|
||
|
}
|
||
|
if v.Low.GreaterThan(low) {
|
||
|
v.Low = low
|
||
|
}
|
||
|
if v.High.LessThan(high) {
|
||
|
v.High = high
|
||
|
}
|
||
|
}
|
||
|
KLineMap[k] = v
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (this *ConstructorContract) pullStorage(close, open, high, low, oldPrice decimal.Decimal, prices []decimal.Decimal) {
|
||
|
for _, v := range dictionary.ContractPriceTime {
|
||
|
resp := market.SubscribeCtKlineResponse{
|
||
|
Channel: fmt.Sprintf("market.%s.kline.%s", this.SelfContractCode, v),
|
||
|
Timestamp: KLineMap[v].ID,
|
||
|
Tick: &market.CtKlineTick{
|
||
|
Open: KLineMap[v].Open,
|
||
|
High: KLineMap[v].High,
|
||
|
Low: KLineMap[v].Low,
|
||
|
Close: close,
|
||
|
Id: KLineMap[v].ID,
|
||
|
Vol: TotalVol.Add(KLineMap[v].Vol),
|
||
|
Count: TotalCount.Add(KLineMap[v].Count),
|
||
|
Amount: TotalAmount.Add(KLineMap[v].Amount),
|
||
|
Rrade_Turnover: TotalTradeTurnover.Add(KLineMap[v].TradeTurnover),
|
||
|
Mrid: int64(rand.Intn(99999999999999) + 99999),
|
||
|
},
|
||
|
}
|
||
|
|
||
|
if v == "1day" {
|
||
|
go OneDayDetailMerged(resp)
|
||
|
}
|
||
|
jsonMessage, _ := json.Marshal(websocketservice.Message{
|
||
|
ServersId: resp.Channel,
|
||
|
Content: resp,
|
||
|
Symbol: resp.Channel})
|
||
|
//applogger.Info("SubscribeCtKline %s:", string(jsonMessage), v)
|
||
|
red.RedisClient.Publish(resp.Channel, string(jsonMessage))
|
||
|
go business.UpdateSubscribeCtKline(resp)
|
||
|
}
|
||
|
//合约详情
|
||
|
detail := market.SubscribeCtDetailResponse{
|
||
|
Channel: fmt.Sprintf("market.%s.detail", this.SelfContractCode),
|
||
|
Timestamp: time.Now().Unix(),
|
||
|
Tick: &market.CtDetailTick{
|
||
|
Open: open,
|
||
|
High: high,
|
||
|
Low: low,
|
||
|
Close: close,
|
||
|
Id: time.Now().Unix(),
|
||
|
Vol: TotalVol,
|
||
|
Count: TotalCount.IntPart(),
|
||
|
Amount: TotalAmount,
|
||
|
TradeTurnover: TotalTradeTurnover,
|
||
|
},
|
||
|
}
|
||
|
jsonMessages, _ := json.Marshal(websocketservice.Message{
|
||
|
ServersId: detail.Channel,
|
||
|
Content: detail,
|
||
|
Symbol: detail.Channel})
|
||
|
//applogger.Info("detail :", string(jsonMessages))
|
||
|
red.RedisClient.Publish(detail.Channel, string(jsonMessages))
|
||
|
}
|
||
|
|
||
|
// 生成随机价格波动
|
||
|
func (this *ConstructorContract) generateRandomPrices(currentPrice, fluctuation, delta decimal.Decimal) []decimal.Decimal {
|
||
|
prices := make([]decimal.Decimal, 0)
|
||
|
rand.New(rand.NewSource(time.Now().UnixNano()))
|
||
|
for i := 0; i < numPrices; i++ {
|
||
|
price := currentPrice.Add(delta.Add(fluctuation.Mul(decimal.NewFromFloat(2*rand.Float64() - 1)))).Round(digits)
|
||
|
prices = append(prices, price)
|
||
|
}
|
||
|
return prices
|
||
|
}
|
||
|
|
||
|
// 获取最高价
|
||
|
func (this *ConstructorContract) getMaxPrices(highPrice decimal.Decimal, prices []decimal.Decimal) []decimal.Decimal {
|
||
|
res := make([]decimal.Decimal, 0)
|
||
|
for _, price := range prices {
|
||
|
if price.GreaterThan(highPrice) {
|
||
|
res = append(res, price)
|
||
|
}
|
||
|
}
|
||
|
return res
|
||
|
}
|
||
|
func (this *ConstructorContract) getMaxPrice(highPrice decimal.Decimal, prices []decimal.Decimal) decimal.Decimal {
|
||
|
for _, price := range prices {
|
||
|
if price.GreaterThan(highPrice) {
|
||
|
highPrice = price
|
||
|
}
|
||
|
}
|
||
|
return highPrice
|
||
|
}
|
||
|
|
||
|
// 获取最低价
|
||
|
func (this *ConstructorContract) getMinPrices(lowPrice decimal.Decimal, prices []decimal.Decimal) []decimal.Decimal {
|
||
|
res := make([]decimal.Decimal, 0)
|
||
|
for _, price := range prices {
|
||
|
if price.LessThan(lowPrice) {
|
||
|
res = append(res, price)
|
||
|
}
|
||
|
}
|
||
|
return res
|
||
|
}
|
||
|
|
||
|
func (this *ConstructorContract) getMinPrice(lowPrice decimal.Decimal, prices []decimal.Decimal) decimal.Decimal {
|
||
|
for _, price := range prices {
|
||
|
if price.LessThan(lowPrice) {
|
||
|
lowPrice = price
|
||
|
}
|
||
|
}
|
||
|
return lowPrice
|
||
|
}
|