package dto

import (
	"errors"
	"fmt"
	"strconv"

	"go-admin/app/admin/models"
	"go-admin/common/dto"
	common "go-admin/common/models"

	"github.com/shopspring/decimal"
)

type LinePreOrderGetPageReq struct {
	dto.Pagination    `search:"-"`
	ExchangeType      string   `json:"exchangeType" form:"exchangeType" search:"type:exact;column:exchange_type;table:line_pre_order" comment:"交易所类型 字典exchange_type"`
	SymbolType        int      `json:"symbolType" form:"symbolType" search:"type:exact;column:symbol_type;table:line_pre_order"`
	ApiId             string   `form:"apiId"  search:"type:exact;column:api_id;table:line_pre_order" comment:"api用户"`
	Symbol            string   `form:"symbol"  search:"type:exact;column:symbol;table:line_pre_order" comment:"交易对"`
	QuoteSymbol       string   `form:"quoteSymbol"  search:"type:exact;column:quote_symbol;table:line_pre_order" comment:"计较货币"`
	SignPriceType     string   `form:"signPriceType"  search:"type:exact;column:sign_price_type;table:line_pre_order" comment:"对标价类型: new=最新价格;tall=24小时最高;low=24小时最低;mixture=标记价;entrust=委托实价;add=补仓"`
	Rate              string   `form:"rate"  search:"type:exact;column:rate;table:line_pre_order" comment:"下单百分比"`
	Site              string   `form:"site"  search:"type:exact;column:site;table:line_pre_order" comment:"购买方向:BUY=买;SELL=卖"`
	OrderSn           string   `form:"orderSn"  search:"type:exact;column:order_sn;table:line_pre_order" comment:"订单号"`
	Status            string   `form:"status"  search:"type:exact;column:status;table:line_pre_order" comment:"是否被触发:0=待触发;1=已触发;2=下单失败;3=已记录;4=已取消;5=委托中;6=已平仓;7=已补单;8=补单失败;9=现货已成交；10=合约已补单;11=合约补单失败;12=合约已成交;13=已开仓"`
	OrderType         string   `form:"orderType"  search:"type:exact;column:order_type;table:line_pre_order" comment:"订单类型:1=现货;2=合约;3=合约止盈;4=合约止损;5=现货止盈;6=现货止损;7=止损补仓;8=现货加仓；9=现货平仓;10 = 合约止损补仓,11=合约加仓；12=合约平仓"`
	AddPositionStatus int      `form:"addPositionStatus" search:"-"`
	HedgeStatus       int      `form:"hedgeStatus" search:"-"`
	PercentStart      *float64 `form:"percentStart" search:"-"`
	PercentEnd        *float64 `form:"percentEnd" search:"-"`
	LinePreOrderOrder
}

type LinePreOrderOrder struct {
	Id            string `form:"idOrder"  search:"type:order;column:id;table:line_pre_order"`
	Pid           string `form:"pidOrder"  search:"type:order;column:pid;table:line_pre_order"`
	ApiId         string `form:"apiIdOrder"  search:"type:order;column:api_id;table:line_pre_order"`
	GroupId       string `form:"groupIdOrder"  search:"type:order;column:group_id;table:line_pre_order"`
	Symbol        string `form:"symbolOrder"  search:"type:order;column:symbol;table:line_pre_order"`
	QuoteSymbol   string `form:"quoteSymbolOrder"  search:"type:order;column:quote_symbol;table:line_pre_order"`
	SignPrice     string `form:"signPriceOrder"  search:"type:order;column:sign_price;table:line_pre_order"`
	SignPriceType string `form:"signPriceTypeOrder"  search:"type:order;column:sign_price_type;table:line_pre_order"`
	Rate          string `form:"rateOrder"  search:"type:order;column:rate;table:line_pre_order"`
	Price         string `form:"priceOrder"  search:"type:order;column:price;table:line_pre_order"`
	Num           string `form:"numOrder"  search:"type:order;column:num;table:line_pre_order"`
	BuyPrice      string `form:"buyPriceOrder"  search:"type:order;column:buy_price;table:line_pre_order"`
	Site          string `form:"siteOrder"  search:"type:order;column:site;table:line_pre_order"`
	OrderSn       string `form:"orderSnOrder"  search:"type:order;column:order_sn;table:line_pre_order"`
	OrderType     string `form:"orderTypeOrder"  search:"type:order;column:order_type;table:line_pre_order"`
	CoverRate     string `form:"coverRateOrder"  search:"type:order;column:cover_rate;table:line_pre_order"`
	Desc          string `form:"descOrder"  search:"type:order;column:desc;table:line_pre_order"`
	Status        string `form:"statusOrder"  search:"type:order;column:status;table:line_pre_order"`
	CreatedAt     string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_pre_order"`
	UpdatedAt     string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_pre_order"`
	DeletedAt     string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_pre_order"`
	CreateBy      string `form:"createByOrder"  search:"type:order;column:create_by;table:line_pre_order"`
	UpdateBy      string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_pre_order"`
	Direction     string `form:"directionOrder"  search:"type:order;column:direction;table:line_pre_order"`
	UpdateTime    string `form:"updateTimeOrder"  search:"type:order;column:update_time;table:line_pre_order"`
}

func (m *LinePreOrderGetPageReq) GetNeedSearch() interface{} {
	return *m
}

type LinePreOrderInsertReq struct {
	Id            int    `json:"-" comment:"id"` // id
	ExchangeType  string `json:"exchangeType" comment:"交易所类型 字典exchange_type"`
	Pid           string `json:"pid" comment:"pid"`
	ApiId         string `json:"apiId" comment:"api用户"`
	GroupId       string `json:"groupId" comment:"交易对组id"`
	Symbol        string `json:"symbol" comment:"交易对"`
	QuoteSymbol   string `json:"quoteSymbol" comment:"计较货币"`
	SignPrice     string `json:"signPrice" comment:"对标价"`
	SignPriceType string `json:"signPriceType" comment:"对标价类型: new=最新价格;tall=24小时最高;low=24小时最低;mixture=标记价;entrust=委托实价;add=补仓"`
	Rate          string `json:"rate" comment:"下单百分比"`
	Price         string `json:"price" comment:"触发价格"`
	Num           string `json:"num" comment:"购买数量"`
	BuyPrice      string `json:"buyPrice" comment:"购买金额"`
	Site          string `json:"site" comment:"购买方向:BUY=买;SELL=卖"`
	OrderSn       string `json:"orderSn" comment:"订单号"`
	OrderType     int    `json:"orderType" comment:"订单类型:0=主单;1=止盈;2=止损;3=平仓"`
	Desc          string `json:"desc" comment:"订单描述"`
	Status        int    `json:"status" comment:"是否被触发:0=待触发;1=已触发;2=下单失败;4=已取消;5=委托中;6=已成交;9=已平仓"`
	common.ControlBy
}

func (s *LinePreOrderInsertReq) Generate(model *models.LinePreOrder) {
	if s.Id == 0 {
		model.Model = common.Model{Id: s.Id}
	}
	pid, _ := strconv.Atoi(s.Pid)
	model.Pid = pid
	model.ApiId, _ = strconv.Atoi(s.ApiId)
	model.GroupId = s.GroupId
	model.Symbol = s.Symbol
	model.QuoteSymbol = s.QuoteSymbol
	model.SignPrice = s.SignPrice
	model.SignPriceType = s.SignPriceType
	model.Rate = s.Rate
	model.Price = s.Price
	model.Num = s.Num
	model.BuyPrice = s.BuyPrice
	model.Site = s.Site
	model.OrderSn = s.OrderSn
	model.OrderType = s.OrderType
	model.Desc = s.Desc
	model.Status = s.Status
	model.CreateBy = s.CreateBy // 添加这而，需要记录是被谁创建的
}

func (s *LinePreOrderInsertReq) GetId() interface{} {
	return s.Id
}

type LinePreOrderUpdateReq struct {
	Id            int    `uri:"id" comment:"id"` // id
	ExchangeType  string `json:"exchangeType" comment:"交易所类型 字典exchange_type"`
	Pid           string `json:"pid" comment:"pid"`
	MainId        int    `json:"mainId" comment:"mainId"`
	ApiId         string `json:"apiId" comment:"api用户"`
	GroupId       string `json:"groupId" comment:"交易对组id"`
	Symbol        string `json:"symbol" comment:"交易对"`
	QuoteSymbol   string `json:"quoteSymbol" comment:"计较货币"`
	SignPrice     string `json:"signPrice" comment:"对标价"`
	SignPriceType string `json:"signPriceType" comment:"对标价类型: new=最新价格;tall=24小时最高;low=24小时最低;mixture=标记价;entrust=委托实价;add=补仓"`
	Rate          string `json:"rate" comment:"下单百分比"`
	Price         string `json:"price" comment:"触发价格"`
	Num           string `json:"num" comment:"购买数量"`
	BuyPrice      string `json:"buyPrice" comment:"购买金额"`
	Site          string `json:"site" comment:"购买方向:BUY=买;SELL=卖"`
	OrderSn       string `json:"orderSn" comment:"订单号"`
	OrderType     int    `json:"orderType" comment:"订单类型:0=主单;1=止盈;2=止损;3=平仓"`
	Desc          string `json:"desc" comment:"订单描述"`
	Status        int    `json:"status" comment:"是否被触发:0=待触发;1=已触发;2=下单失败;4=已取消;5=委托中;6=已成交;9=已平仓"`
	common.ControlBy
}

func (s *LinePreOrderUpdateReq) Generate(model *models.LinePreOrder) {
	if s.Id == 0 {
		model.Model = common.Model{Id: s.Id}
	}
	pid, _ := strconv.Atoi(s.Pid)
	model.Pid = pid
	model.ExchangeType = s.ExchangeType
	model.ApiId, _ = strconv.Atoi(s.ApiId)
	model.GroupId = s.GroupId
	model.Symbol = s.Symbol
	model.QuoteSymbol = s.QuoteSymbol
	model.SignPrice = s.SignPrice
	model.SignPriceType = s.SignPriceType
	model.Rate = s.Rate
	model.Price = s.Price
	model.Num = s.Num
	model.BuyPrice = s.BuyPrice
	model.Site = s.Site
	model.OrderSn = s.OrderSn
	model.OrderType = s.OrderType
	model.Desc = s.Desc
	model.Status = s.Status
	model.UpdateBy = s.UpdateBy // 添加这而，需要记录是被谁更新的
}

func (s *LinePreOrderUpdateReq) GetId() interface{} {
	return s.Id
}

// LinePreOrderGetReq 功能获取请求参数
type LinePreOrderGetReq struct {
	Id int `uri:"id"`
}

func (s *LinePreOrderGetReq) GetId() interface{} {
	return s.Id
}

// LinePreOrderDeleteReq 功能删除请求参数
type LinePreOrderDeleteReq struct {
	Ids []int `json:"ids"`
}

func (s *LinePreOrderDeleteReq) GetId() interface{} {
	return s.Ids
}

type LineAddPreOrderReq struct {
	ExchangeType            string          `json:"exchange_type" vd:"len($)>0"` //交易所类型
	StrategyTemplateType    int             `json:"strategy_template_type"`      //策略类型 0-无 1-波段涨跌幅
	StrategyTemplateId      int             `json:"strategy_template_id"`        //策略id
	ReduceStrategyId        int             `json:"reduce_strategy_id"`          //减仓策略id
	OrderType               int             `json:"order_type"`                  //订单类型
	Symbol                  string          `json:"symbol"`                      //交易对
	ApiUserId               string          `json:"api_id" `                     //下单用户
	ApiIdType               int             `json:"api_id_type"`                 //下单用户类型
	ApiUserGroupId          int             `json:"api_user_group_id"`           //下单用户组
	Site                    string          `json:"site" `                       //购买方向
	BuyPrice                string          `json:"buy_price" vd:"$>0"`          //购买金额 U
	PricePattern            string          `json:"price_pattern"`               //价格模式
	Price                   string          `json:"price" vd:"$>0"`              //下单价百分比
	Profit                  string          `json:"profit" vd:"$>0"`             //止盈价
	ProfitNumRatio          decimal.Decimal `json:"profit_num_ratio"`            //止盈数量百分比
	ProfitTpTpPriceRatio    decimal.Decimal `json:"profit_tp_tp_price_ratio"`    //止盈后止盈价百分比
	ProfitTpSlPriceRatio    decimal.Decimal `json:"profit_tp_sl_price_ratio"`    //止盈后止损价百分比
	StopLoss                decimal.Decimal `json:"stop_loss"`                   //止损价
	PriceType               string          `json:"price_type"`                  //价格类型
	SaveTemplate            string          `json:"save_template"`               //是否保存模板
	TemplateName            string          `json:"template_name"`               //模板名字
	SymbolType              int             `json:"symbol_type" vd:"$>0"`        //交易对类型 1-现货 2-合约
	CoverType               int             `json:"cover_type"`                  //对冲类型 0=无对冲 1= 现货对合约 2=合约对合约 3 合约对现货
	ExpireHour              int             `json:"expire_hour"`                 // 过期时间 单位小时
	MainOrderType           string          `json:"main_order_type" `            //主单类型：限价(LIMIT)或市价(MARKET)
	ReducePriceRatio        decimal.Decimal `json:"reduce_price" `               //主单减仓价格百分比
	ReduceNumRatio          decimal.Decimal `json:"reduce_num" `                 //主单减仓数量百分比
	ReduceTakeProfitRatio   decimal.Decimal `json:"reduce_take_profit"`          //主单减仓后止盈价百分比
	ReduceStopLossRatio     decimal.Decimal `json:"reduce_stop_price"`           //主单减仓后止损价百分比
	ReduceReTakeProfitRatio decimal.Decimal `json:"re_take_profit_ratio" comment:"减仓后亏损回本止盈百分比"`

	Ext []LineAddPreOrderExtReq `json:"ext" ` //拓展字段
	common.ControlBy
}

type LinePreOrderAddPositionReq struct {
	ExchangeType string          `json:"exchangeType" vd:"len($)>0"` //交易所类型
	OrderType    int             `json:"orderType"`                  //订单类型
	Symbol       string          `json:"symbol"`                     //交易对
	ApiUserId    int             `json:"apiId" `                     //下单用户
	Site         string          `json:"site" `                      //购买方向
	BuyPrice     decimal.Decimal `json:"buyPrice" vd:"$>0"`          //购买金额 U
	PricePattern string          `json:"pricePattern"`               //价格模式
	Price        decimal.Decimal `json:"price" vd:"$>0"`             //下单价百分比
	Profit       decimal.Decimal `json:"profit" vd:"$>0"`            //止盈价
	// StopPrice             string                  `json:"stop_price"`         //止损价
	AddPositionOrderType  string          `json:"addPositionOrderType" comment:"加仓订单类型 LIMIT-限价 MARKET-市价"`
	PriceType             string          `json:"priceType"` //价格类型
	ReTakeProfitRatio     decimal.Decimal `json:"reTakeProfitRatio" comment:"亏损回本止盈百分比"`
	ReducePriceRatio      decimal.Decimal `json:"reducePriceRatio" comment:"减仓价格百分比" `
	ReduceNumRatio        decimal.Decimal `json:"reduceNumRatio" comment:"减仓数量百分比" `
	ReduceTakeProfitRatio decimal.Decimal `json:"reduceTakeProfitRatio" comment:"减仓后止盈百分比" `
	ReduceStopLossRatio   decimal.Decimal `json:"reduceStopLossRatio" comment:"减仓后止损百分比"`
}

// 校验
func (req *LinePreOrderAddPositionReq) Valid() error {
	if req.ExchangeType == "" {
		return errors.New("交易所类型不能为空")
	}

	if req.OrderType <= 0 || req.OrderType > 2 {
		return errors.New("订单类型错误")
	}

	if req.Symbol == "" {
		return errors.New("交易对不能为空")
	}

	if req.AddPositionOrderType == "" {
		return errors.New("加仓订单类型不能为空")
	}

	if req.PriceType == "" {
		return errors.New("价格类型不能为空")
	}

	if req.ReducePriceRatio.IsZero() {
		return errors.New("主单减仓价格百分比不能为空")
	}

	if req.ReduceNumRatio.IsZero() {
		return errors.New("主单减仓数量百分比不能为空")
	}

	if req.ReduceTakeProfitRatio.IsZero() {
		return errors.New("减仓后止盈百分比不能为空")
	}

	//减仓100%
	if req.ReduceNumRatio.Cmp(decimal.NewFromInt(100)) == 0 {
		return errors.New("减仓数量百分百,后面的节点不需要添加")
	}

	return nil
}

func (req LineAddPreOrderReq) Valid() error {
	if req.ReducePriceRatio.IsZero() {
		return errors.New("主单减仓价格百分比不能为空")
	}

	if req.StrategyTemplateType == 1 && req.StrategyTemplateId == 0 {
		return errors.New("请选择策略")
	}

	if req.ReduceNumRatio.IsZero() {
		return errors.New("主单减仓数量百分比不能为空")
	}

	if req.ReducePriceRatio.IsZero() || req.ReducePriceRatio.Cmp(decimal.NewFromInt(100)) >= 0 {
		return errors.New("主单减仓价格百分比错误")
	}

	//减仓100%
	if req.ReduceNumRatio.Cmp(decimal.NewFromInt(100)) == 0 && len(req.Ext) > 0 {
		return errors.New("减仓数量百分百,后面的节点不需要添加")
	}

	for index, v := range req.Ext {
		name := "加仓"

		if v.AddType < 1 || v.AddType > 2 {
			return errors.New("加、减仓单类型错误")
		}

		if v.AddType == 2 {
			name = "减仓"
		}

		if v.AddType == 2 && v.AddPositionVal.Cmp(decimal.NewFromInt(100)) >= 0 && index < len(req.Ext)-1 {
			return fmt.Errorf("减仓数量百分百,第%v节点 后面的节点不需要添加", index+1)
		}

		if v.AddPositionVal.IsZero() {
			return fmt.Errorf("%s单数量不能为空", name)
		}
		if v.PriceRatio.Cmp(decimal.Zero) <= 0 || v.PriceRatio.Cmp(decimal.NewFromInt(100)) >= 0 {
			return fmt.Errorf("%s单下跌价格不能为空", name)
		}

		if (v.AddType == 2 && v.AddPositionVal.Cmp(decimal.NewFromInt(100)) < 0 && v.TakeProfitRatio.IsZero()) ||
			(v.AddType == 1 && v.TakeProfitRatio.IsZero()) ||
			v.TakeProfitRatio.Cmp(decimal.NewFromInt(100)) > 0 {
			return errors.New("止盈价格不正确")
		}

		if v.AddType == 1 && v.TakeProfitNumRatio.Cmp(decimal.NewFromInt(100)) < 0 &&
			v.TakeProfitNumRatio.Cmp(decimal.Zero) > 0 &&
			(v.TpTpPriceRatio.IsZero() || v.TpTpPriceRatio.Cmp(decimal.NewFromInt(100)) > 0) {
			return errors.New("第二止盈价格不正确")
		}
	}

	return nil
}

func (req LineAddPreOrderReq) CheckParams() error {
	if req.ExchangeType == "" {
		return errors.New("请选择交易所")
	}

	if req.ApiUserId == "" {
		return errors.New("选择下单用户")
	}
	if req.Symbol == "" {
		return errors.New("请选择交易对")
	}

	if req.Price == "" {
		return errors.New("输出下单价")
	}

	if req.PricePattern == "" {
		return errors.New("请选择价格类型")
	}

	if req.ExchangeType == "" {
		return errors.New("请选择交易所")
	}

	return nil
}

type LineTreeOrder struct {
	models.LinePreOrder
	Childs []models.LinePreOrder `json:"childs"`
}

// LineBatchAddPreOrderReq 批量添加订单请求参数
type LineBatchAddPreOrderReq struct {
	ExchangeType          string                  `json:"exchange_type"`            //交易所类型 字典exchange_type
	StrategyTemplateType  int                     `json:"strategy_template_type"`   //策略类型 0-无 1-波段涨跌幅
	StrategyTemplateId    int                     `json:"strategy_template_id"`     //策略id
	SymbolType            int                     `json:"symbol_type"`              //主单交易对类型 0-现货 1-合约
	OrderType             int                     `json:"order_type"`               //订单类型
	SymbolGroupId         string                  `json:"symbol_group_id"`          //交易对组id
	Symbol                string                  `json:"symbol"`                   //交易对
	ApiUserId             string                  `json:"api_id"`                   //下单用户
	ApiIdType             int                     `json:"api_id_type"`              //下单用户类型
	ApiUserGroupId        int                     `json:"api_user_group_id"`        //下单用户组
	Site                  string                  `json:"site"`                     //购买方向
	BuyPrice              string                  `json:"buy_price"`                //购买金额 U
	PricePattern          string                  `json:"price_pattern"`            //价格模式
	Price                 string                  `json:"price"`                    //下单价百分比
	ProfitNumRatio        decimal.Decimal         `json:"profit_num_ratio"`         //止盈数量百分比
	ProfitTpTpPriceRatio  decimal.Decimal         `json:"profit_tp_tp_price_ratio"` //止盈后止盈价百分比
	ProfitTpSlPriceRatio  decimal.Decimal         `json:"profit_tp_sl_price_ratio"` //止盈后止损价百分比
	Profit                string                  `json:"profit"`                   //止盈价
	StopPrice             string                  `json:"stop_price"`               //止损价
	PriceType             string                  `json:"price_type"`               //价格类型
	SaveTemplate          string                  `json:"save_template"`            //是否保存模板
	TemplateName          string                  `json:"template_name"`            //模板名字
	OrderNum              int                     `json:"order_num"`                //脚本运行次数
	Script                string                  `json:"script"`                   //是否是脚本运行 1 = 是 0= 否
	CoverType             int                     `json:"cover_type"`               //对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货
	ExpireHour            int                     `json:"expire_hour"`              // 过期时间 单位小时
	MainOrderType         string                  `json:"main_order_type"`          //主单类型：限价(LIMIT)或市价(MARKET)
	ReducePriceRatio      decimal.Decimal         `json:"reduce_price"`             //主单减仓价格百分比
	ReduceNumRatio        decimal.Decimal         `json:"reduce_num"`               //主单减仓数量百分比
	ReduceTakeProfitRatio decimal.Decimal         `json:"reduce_take_profit"`       //主单减仓后止盈价百分比
	ReduceStopLossRatio   decimal.Decimal         `json:"reduce_stop_price"`        //主单减仓后止损价百分比
	Ext                   []LineAddPreOrderExtReq `json:"ext"`                      //拓展字段
	common.ControlBy
}

func (req LineBatchAddPreOrderReq) CheckParams() error {
	if req.ExchangeType == "" {
		return errors.New("请选择交易所")
	}

	if req.StrategyTemplateType == 1 && req.StrategyTemplateId == 0 {
		return errors.New("请选择策略")
	}

	if req.ApiUserId == "" {
		return errors.New("选择下单用户")
	}
	if req.SymbolGroupId == "" {
		return errors.New("请选择交易对组")
	}

	if req.Price == "" {
		return errors.New("输出下单价")
	}

	if req.PricePattern == "" {
		return errors.New("请选择价格类型")
	}

	if req.ExchangeType == "" {
		return errors.New("请选择交易所")
	}

	if req.ReducePriceRatio.IsZero() {
		return errors.New("主单减仓价格百分比不能为空")
	}

	if req.ReduceNumRatio.Cmp(decimal.Zero) <= 0 {
		return errors.New("主单减仓数量百分比不能为空")
	}

	if req.ReducePriceRatio.Cmp(decimal.Zero) <= 0 || req.ReducePriceRatio.Cmp(decimal.NewFromInt(100)) >= 0 {
		return errors.New("主单减仓价格百分比错误")
	}

	//减仓100%
	if req.ReduceNumRatio.Cmp(decimal.NewFromInt(100)) == 0 {
		return errors.New("减仓数量百分百,后面的节点不需要添加")
	}

	for index, v := range req.Ext {
		name := "加仓"

		if v.AddType < 1 || v.AddType > 2 {
			return errors.New("加、减仓单类型错误")
		}

		if v.AddType == 2 {
			name = "减仓"
		}

		if v.AddType == 2 && v.AddPositionVal.Cmp(decimal.NewFromInt(100)) >= 0 && index < len(req.Ext)-1 {
			return fmt.Errorf("减仓数量百分百,第%v节点 后面的节点不需要添加", index+1)
		}

		if v.AddPositionVal.IsZero() {
			return fmt.Errorf("%s单数量不能为空", name)
		}
		if v.PriceRatio.Cmp(decimal.Zero) <= 0 || v.PriceRatio.Cmp(decimal.NewFromInt(100)) >= 0 {
			return fmt.Errorf("%s单下跌价格不能为空", name)
		}

		if (v.AddType == 2 && v.AddPositionVal.Cmp(decimal.NewFromInt(100)) < 0 && v.TakeProfitRatio.IsZero()) ||
			(v.AddType == 1 && v.TakeProfitRatio.IsZero()) ||
			v.TakeProfitRatio.Cmp(decimal.NewFromInt(100)) > 0 {
			return errors.New("止盈价格不正确")
		}

		if v.AddType == 1 && v.TakeProfitNumRatio.Cmp(decimal.NewFromInt(100)) < 0 &&
			v.TakeProfitNumRatio.Cmp(decimal.Zero) > 0 &&
			(v.TpTpPriceRatio.IsZero() || v.TpTpPriceRatio.Cmp(decimal.NewFromInt(100)) > 0) {
			return errors.New("第二止盈价格不正确")
		}

		// if v.TpSlPriceRatio.Cmp(decimal.Zero) <= 0 || v.TpSlPriceRatio.Cmp(decimal.NewFromInt(100)) > 0 {
		// 	return errors.New("止盈后止损价格不正确")
		// }
	}

	return nil
}

type Ticker struct {
	Symbol string `json:"symbol"`
	Price  string `json:"price"`
}
type QuickAddPreOrderReq struct {
	Ids string `json:"ids"`
}

// LeverReq 设置杠杆请求
type LeverReq struct {
	ApiUserIds   string `json:"api_user_ids"`
	Symbol       string `json:"symbol"`
	Leverage     int    `json:"leverage"`
	GroupId      int    `json:"group_id"`
	IsAll        int    `json:"is_all"`       // 1= 全部 0=不是全部
	ExchangeType string `json:"exchangeType"` //交易所类型 字典exchange_type
}

func (c LeverReq) CheckParams() error {
	if c.Leverage > 125 || c.Leverage < 1 {
		return errors.New("请输入1-125的杠杆倍数")
	}
	if c.ApiUserIds == "" {
		return errors.New("请选择api用户")
	}
	return nil
}

type MarginTypeReq struct {
	ApiUserIds   string `json:"api_user_ids"`
	Symbol       string `json:"symbol"`       // 交易对
	MarginType   string `json:"margin_type"`  //全仓  CROSSED    逐仓 ISOLATED
	GroupId      int    `json:"group_id"`     // 交易对组id
	IsAll        int    `json:"is_all"`       // 1= 全部 0=不是全部
	ExchangeType string `json:"exchangeType"` //交易所类型 字典exchange_type
}

type CancelOpenOrderReq struct {
	ApiId        int    `json:"api_id"`
	Symbol       string `json:"symbol"`
	OrderSn      string `json:"order_sn"`
	OrderType    int    `json:"order_type"`
	ExchangeType string `json:"exchangeType"` //交易所类型 字典exchange_type
}

type GetChildOrderReq struct {
	Id int `json:"id"` //id
}

type LinePreOrderChildCount struct {
	Id    int `json:"id"`
	Count int `json:"count"`
}

func (c MarginTypeReq) CheckParams() error {
	if c.Symbol == "" && c.GroupId == 0 {
		return errors.New("请选择交易对或交易对组")
	}
	if c.MarginType == "" {
		return errors.New("请选择仓位模式")
	}
	if c.ApiUserIds == "" {
		return errors.New("请选择api用户")
	}
	return nil
}

type PreOrderRedisList struct {
	Id          int    `json:"id"`
	Symbol      string `json:"symbol"`
	Price       string `json:"price"`
	Site        string `json:"site"`
	ApiId       int    `json:"api_id"`
	OrderSn     string `json:"order_sn"`
	QuoteSymbol string `json:"quote_symbol"`
}

type StrategyOrderRedisList struct {
	Id          int    `json:"id"`
	Symbol      string `json:"symbol"`
	Price       string `json:"price"`
	Site        string `json:"site"`
	ApiId       int    `json:"api_id"`
	OrderSn     string `json:"order_sn"`
	QuoteSymbol string `json:"quote_symbol"`
	LineStrategyTemplateRedis
}

type StopLossRedisList struct {
	Id            int             `json:"id"`
	PId           int             `json:"pid"`    //父级id
	MainId        int             `json:"mainId"` //主单id
	OrderTye      int             `json:"orderType"`
	SymbolType    int             `json:"symbolType"`
	OrderCategory int             `json:"orderCategory"`
	Symbol        string          `json:"symbol"`
	Price         decimal.Decimal `json:"price"` //触发价（根据主单价格触发）
	Site          string          `json:"site"`
	ApiId         int             `json:"api_id"`
}

type TakeProfitRedisList struct {
	Id            int             `json:"id"`
	PId           int             `json:"pid"`    //父级id
	MainId        int             `json:"mainId"` //主单id
	OrderTye      int             `json:"orderType"`
	SymbolType    int             `json:"symbolType"`
	OrderCategory int             `json:"orderCategory"`
	Symbol        string          `json:"symbol"`
	Price         decimal.Decimal `json:"price"` //触发价（根据主单价格触发）
	Site          string          `json:"site"`
	ApiId         int             `json:"api_id"`
	OrderSn       string          `json:"订单编号" comment:"订单编号"`
}

// ManuallyCover 手动加仓请求体
type ManuallyCover struct {
	ApiId             int    `json:"api_id"`               //主账号id
	CoverAccount      int    `json:"cover_account"`        // 1=加主账号 2=加付帐号 3=都加
	SymbolType        int    `json:"symbol_type"`          //加仓交易对类型 1=现货 2=合约
	Symbols           string `json:"symbols"`              //加仓交易对 -> ETHUSDT,BTCUSDT
	CoverAccountAType string `json:"cover_account_a_type"` //加仓A账号订单类型 MARKET=市价  LIMIT=限价
	CoverAccountARate string `json:"cover_account_a_rate"` //加仓A账号限价比例 限价才有比例
	CoverAccountBType string `json:"cover_account_b_type"` //加仓b账号订单类型 MARKET=市价  LIMIT=限价
	CoverAccountBRate string `json:"cover_account_b_rate"` //加仓b账号限价比例 限价才有比例
	CoverType         int    `json:"cover_type"`           //1 = 百分比 2=金额
	Value             string `json:"value"`                //加仓数值
}

func (m *ManuallyCover) CheckParams() error {
	if m.ApiId <= 0 {
		return errors.New("请选择主账号")
	}

	if m.CoverAccount <= 0 {
		return errors.New("请选择加仓账号")
	}

	if len(m.Symbols) == 0 {
		return errors.New("请选择加仓交易对")
	}

	if m.CoverType <= 0 {
		return errors.New("请填写加仓类型")
	}
	if len(m.Value) == 0 {
		return errors.New("请填写加仓数值")
	}
	return nil
}

// ClosePosition 平仓请求
type ClosePosition struct {
	ApiId        int    `json:"api_id"`        //api-user 用户id
	Symbol       string `json:"symbol"`        // 交易对
	Rate         string `json:"rate"`          //限价平仓百分比
	CloseType    int    `json:"close_type"`    //现货平仓=1 合约平仓=2
	ExchangeType string `json:"exchange_type"` //交易所类型 字典exchange_type
	Side         string `json:"side"`          //SELL=卖出(空) BUY=买入（多）
}

func (m *ClosePosition) CheckParams() error {
	if m.ApiId <= 0 {
		return errors.New("请选择账号")
	}

	if m.CloseType <= 0 && m.CloseType != 1 && m.CloseType != 2 {
		return errors.New("请选择平仓类型")
	}

	return nil
}

type QueryOrderReq struct {
	OrderType int    `json:"order_type"` // 订单类型
	ApiId     int    `json:"api_id"`     //用户api_id
	OrderSn   string `json:"order_sn"`   //订单号
	Symbol    string `json:"symbol"`     //交易对
}

type QueryAiCoinPriceReq struct {
	Symbol string `json:"symbol"` //交易对
}

// 计算亏损止盈百分比
type CalculateBreakEevenRatioReq struct {
	Price             decimal.Decimal `form:"price"`
	Symbol            string          `form:"symbol"`       //交易对
	ExchangeType      string          `form:"exchangeType"` //交易所类型 字典exchange_type
	SymbolType        int             `form:"symbolType"`
	AddType           int             `form:"addType" comment:"类型 1-加仓 2-减仓"`
	BuyPrice          decimal.Decimal `form:"buyPrice"`          //主单购买总金额
	LossBeginPercent  decimal.Decimal `form:"lossBeginPercent"`  //亏损开始百分比
	LossEndPercent    decimal.Decimal `form:"lossEndPercent"`    //亏损截至百分比
	AddPositionType   int             `form:"addPositionType"`   //加仓/减仓 类型 1-百分比 2-实际金额
	AddPositionVal    decimal.Decimal `form:"addPositionVal"`    //加仓/减仓 金额
	RemainingQuantity decimal.Decimal `form:"remainingQuantity"` //剩余数量
	TotalLossAmountU  decimal.Decimal `form:"totalLossAmountU"`  //累计亏损金额
}

// 计算亏损返回值
type CalculateBreakEvenRatioResp struct {
	RemainingQuantity decimal.Decimal `json:"remainingQuantity"` //剩余数量
	Ratio             decimal.Decimal `json:"ratio"`             //亏损止盈百分比
	TotalLossAmountU  decimal.Decimal `json:"totalLossAmountU"`  //总亏损金额
}

type SpotQueryOrderResp struct {
	Symbol                  string `json:"symbol"`
	OrderId                 int    `json:"orderId"`
	OrderListId             int    `json:"orderListId"`
	ClientOrderId           string `json:"clientOrderId"`
	Price                   string `json:"price"`
	OrigQty                 string `json:"origQty"`
	ExecutedQty             string `json:"executedQty"`
	OrigQuoteOrderQty       string `json:"origQuoteOrderQty"`
	CummulativeQuoteQty     string `json:"cummulativeQuoteQty"`
	Status                  string `json:"status"`
	TimeInForce             string `json:"timeInForce"`
	Type                    string `json:"type"`
	Side                    string `json:"side"`
	StopPrice               string `json:"stopPrice"`
	IcebergQty              string `json:"icebergQty"`
	Time                    int64  `json:"time"`
	UpdateTime              int64  `json:"updateTime"`
	IsWorking               bool   `json:"isWorking"`
	WorkingTime             int64  `json:"workingTime"`
	SelfTradePreventionMode string `json:"selfTradePreventionMode"`
}

type FutQueryOrderResp struct {
	AvgPrice                string `json:"avgPrice"`
	ClientOrderId           string `json:"clientOrderId"`
	CumQuote                string `json:"cumQuote"`
	ExecutedQty             string `json:"executedQty"`
	OrderId                 int    `json:"orderId"`
	OrigQty                 string `json:"origQty"`
	OrigType                string `json:"origType"`
	Price                   string `json:"price"`
	ReduceOnly              bool   `json:"reduceOnly"`
	Side                    string `json:"side"`
	PositionSide            string `json:"positionSide"`
	Status                  string `json:"status"`
	StopPrice               string `json:"stopPrice"`
	ClosePosition           bool   `json:"closePosition"`
	Symbol                  string `json:"symbol"`
	Time                    int64  `json:"time"`
	TimeInForce             string `json:"timeInForce"`
	Type                    string `json:"type"`
	ActivatePrice           string `json:"activatePrice"`
	PriceRate               string `json:"priceRate"`
	UpdateTime              int64  `json:"updateTime"`
	WorkingType             string `json:"workingType"`
	PriceProtect            bool   `json:"priceProtect"`
	PriceMatch              string `json:"priceMatch"`
	SelfTradePreventionMode string `json:"selfTradePreventionMode"`
	GoodTillDate            int    `json:"goodTillDate"`
}
