code.vegaprotocol.io/vega@v0.79.0/core/types/risk.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package types
    17  
    18  import (
    19  	"fmt"
    20  
    21  	"code.vegaprotocol.io/vega/libs/num"
    22  	"code.vegaprotocol.io/vega/libs/ptr"
    23  	"code.vegaprotocol.io/vega/libs/stringer"
    24  	proto "code.vegaprotocol.io/vega/protos/vega"
    25  )
    26  
    27  type RiskFactorOverride struct {
    28  	Short num.Decimal
    29  	Long  num.Decimal
    30  }
    31  
    32  type LogNormalModelParams struct {
    33  	Mu    num.Decimal
    34  	R     num.Decimal
    35  	Sigma num.Decimal
    36  }
    37  
    38  type LogNormalRiskModel struct {
    39  	RiskAversionParameter num.Decimal
    40  	Tau                   num.Decimal
    41  	Params                *LogNormalModelParams
    42  	// nil if no override
    43  	RiskFactorOverride *RiskFactorOverride
    44  }
    45  
    46  func (l LogNormalModelParams) IntoProto() *proto.LogNormalModelParams {
    47  	mu, _ := l.Mu.Float64()
    48  	r, _ := l.R.Float64()
    49  	sigma, _ := l.Sigma.Float64()
    50  	return &proto.LogNormalModelParams{
    51  		Mu:    mu,
    52  		R:     r,
    53  		Sigma: sigma,
    54  	}
    55  }
    56  
    57  func (l LogNormalModelParams) String() string {
    58  	return fmt.Sprintf(
    59  		"mu(%s) r(%s) sigma(%s)",
    60  		l.Mu.String(),
    61  		l.R.String(),
    62  		l.Sigma.String(),
    63  	)
    64  }
    65  
    66  func (l LogNormalModelParams) DeepClone() *LogNormalModelParams {
    67  	return &LogNormalModelParams{
    68  		Mu:    l.Mu,
    69  		R:     l.R,
    70  		Sigma: l.Sigma,
    71  	}
    72  }
    73  
    74  func (l LogNormalRiskModel) IntoProto() *proto.LogNormalRiskModel {
    75  	ra, _ := l.RiskAversionParameter.Float64()
    76  	t, _ := l.Tau.Float64()
    77  	var params *proto.LogNormalModelParams
    78  	if l.Params != nil {
    79  		params = l.Params.IntoProto()
    80  	}
    81  	var riskFactorOverride *proto.RiskFactorOverride
    82  	if l.RiskFactorOverride != nil {
    83  		riskFactorOverride = &proto.RiskFactorOverride{
    84  			Short: l.RiskFactorOverride.Short.String(),
    85  			Long:  l.RiskFactorOverride.Long.String(),
    86  		}
    87  	}
    88  	return &proto.LogNormalRiskModel{
    89  		RiskAversionParameter: ra,
    90  		Tau:                   t,
    91  		Params:                params,
    92  		RiskFactorOverride:    riskFactorOverride,
    93  	}
    94  }
    95  
    96  func (l LogNormalRiskModel) DeepClone() *LogNormalRiskModel {
    97  	cpy := LogNormalRiskModel{
    98  		RiskAversionParameter: l.RiskAversionParameter,
    99  		Tau:                   l.Tau,
   100  	}
   101  	if l.Params != nil {
   102  		cpy.Params = l.Params.DeepClone()
   103  	}
   104  	if l.RiskFactorOverride != nil {
   105  		cpy.RiskFactorOverride = &RiskFactorOverride{
   106  			Short: l.RiskFactorOverride.Short,
   107  			Long:  l.RiskFactorOverride.Long,
   108  		}
   109  	}
   110  	return &cpy
   111  }
   112  
   113  func (l LogNormalRiskModel) String() string {
   114  	return fmt.Sprintf(
   115  		"tau(%s) riskAversionParameter(%s) params(%s)",
   116  		l.Tau.String(),
   117  		l.RiskAversionParameter.String(),
   118  		stringer.PtrToString(l.Params),
   119  	)
   120  }
   121  
   122  type TradableInstrumentLogNormalRiskModel struct {
   123  	LogNormalRiskModel *LogNormalRiskModel
   124  }
   125  
   126  func (t TradableInstrumentLogNormalRiskModel) String() string {
   127  	return fmt.Sprintf(
   128  		"logNormalRiskModel(%s)",
   129  		stringer.PtrToString(t.LogNormalRiskModel),
   130  	)
   131  }
   132  
   133  func (t TradableInstrumentLogNormalRiskModel) IntoProto() *proto.TradableInstrument_LogNormalRiskModel {
   134  	return &proto.TradableInstrument_LogNormalRiskModel{
   135  		LogNormalRiskModel: t.LogNormalRiskModel.IntoProto(),
   136  	}
   137  }
   138  
   139  func (TradableInstrumentLogNormalRiskModel) isTRM() {}
   140  
   141  func (t TradableInstrumentLogNormalRiskModel) trmIntoProto() interface{} {
   142  	return t.IntoProto()
   143  }
   144  
   145  func (TradableInstrumentLogNormalRiskModel) rmType() rmType {
   146  	return LogNormalRiskModelType
   147  }
   148  
   149  func (t TradableInstrumentLogNormalRiskModel) Equal(trm isTRM) bool {
   150  	var ct *TradableInstrumentLogNormalRiskModel
   151  	switch et := trm.(type) {
   152  	case *TradableInstrumentLogNormalRiskModel:
   153  		ct = et
   154  	case TradableInstrumentLogNormalRiskModel:
   155  		ct = &et
   156  	}
   157  	if ct == nil {
   158  		return false
   159  	}
   160  	if !t.LogNormalRiskModel.Tau.Equal(ct.LogNormalRiskModel.Tau) || !t.LogNormalRiskModel.RiskAversionParameter.Equal(ct.LogNormalRiskModel.RiskAversionParameter) {
   161  		return false
   162  	}
   163  
   164  	if t.LogNormalRiskModel.RiskFactorOverride != nil {
   165  		if ct.LogNormalRiskModel.RiskFactorOverride == nil {
   166  			return false
   167  		}
   168  
   169  		if !t.LogNormalRiskModel.RiskFactorOverride.Short.Equal(ct.LogNormalRiskModel.RiskFactorOverride.Short) ||
   170  			!t.LogNormalRiskModel.RiskFactorOverride.Long.Equal(ct.LogNormalRiskModel.RiskFactorOverride.Long) {
   171  			return false
   172  		}
   173  	} else if ct.LogNormalRiskModel.RiskFactorOverride != nil {
   174  		return false
   175  	}
   176  
   177  	// check params
   178  	p, cp := t.LogNormalRiskModel.Params, ct.LogNormalRiskModel.Params
   179  	// check if all params match
   180  	return p.Mu.Equal(cp.Mu) && p.R.Equal(cp.R) && p.Sigma.Equal(cp.Sigma)
   181  }
   182  
   183  func MarginCalculatorFromProto(p *proto.MarginCalculator) *MarginCalculator {
   184  	if p == nil {
   185  		return nil
   186  	}
   187  	return &MarginCalculator{
   188  		ScalingFactors:      ScalingFactorsFromProto(p.ScalingFactors),
   189  		FullyCollateralised: ptr.UnBox(p.FullyCollateralised),
   190  	}
   191  }
   192  
   193  func ScalingFactorsFromProto(p *proto.ScalingFactors) *ScalingFactors {
   194  	return &ScalingFactors{
   195  		SearchLevel:       num.DecimalFromFloat(p.SearchLevel),
   196  		InitialMargin:     num.DecimalFromFloat(p.InitialMargin),
   197  		CollateralRelease: num.DecimalFromFloat(p.CollateralRelease),
   198  	}
   199  }
   200  
   201  type MarginCalculator struct {
   202  	ScalingFactors      *ScalingFactors
   203  	FullyCollateralised bool
   204  }
   205  
   206  func (m MarginCalculator) DeepClone() *MarginCalculator {
   207  	return &MarginCalculator{
   208  		ScalingFactors:      m.ScalingFactors.DeepClone(),
   209  		FullyCollateralised: m.FullyCollateralised,
   210  	}
   211  }
   212  
   213  type ScalingFactors struct {
   214  	SearchLevel       num.Decimal
   215  	InitialMargin     num.Decimal
   216  	CollateralRelease num.Decimal
   217  }
   218  
   219  func (s ScalingFactors) DeepClone() *ScalingFactors {
   220  	return &ScalingFactors{
   221  		SearchLevel:       s.SearchLevel,
   222  		InitialMargin:     s.InitialMargin,
   223  		CollateralRelease: s.CollateralRelease,
   224  	}
   225  }
   226  
   227  type MarginLevels struct {
   228  	MaintenanceMargin      *num.Uint
   229  	SearchLevel            *num.Uint
   230  	InitialMargin          *num.Uint
   231  	CollateralReleaseLevel *num.Uint
   232  	OrderMargin            *num.Uint
   233  	Party                  string
   234  	MarketID               string
   235  	Asset                  string
   236  	Timestamp              int64
   237  	MarginMode             MarginMode
   238  	MarginFactor           num.Decimal
   239  }
   240  
   241  type RiskFactor struct {
   242  	Market string
   243  	Short  num.Decimal
   244  	Long   num.Decimal
   245  }
   246  
   247  func (m MarginLevels) IntoProto() *proto.MarginLevels {
   248  	return &proto.MarginLevels{
   249  		MaintenanceMargin:      num.UintToString(m.MaintenanceMargin),
   250  		SearchLevel:            num.UintToString(m.SearchLevel),
   251  		InitialMargin:          num.UintToString(m.InitialMargin),
   252  		CollateralReleaseLevel: num.UintToString(m.CollateralReleaseLevel),
   253  		OrderMargin:            num.UintToString(m.OrderMargin),
   254  		PartyId:                m.Party,
   255  		MarketId:               m.MarketID,
   256  		Asset:                  m.Asset,
   257  		Timestamp:              m.Timestamp,
   258  		MarginMode:             m.MarginMode,
   259  		MarginFactor:           m.MarginFactor.String(),
   260  	}
   261  }
   262  
   263  func (m MarginLevels) String() string {
   264  	return fmt.Sprintf(
   265  		"marketID(%s) asset(%s) party(%s) intialMargin(%s) maintenanceMargin(%s) collateralReleaseLevel(%s) searchLevel(%s) orderMargin(%s) timestamp(%v) marginMode(%d) marginFactor(%s)",
   266  		m.MarketID,
   267  		m.Asset,
   268  		m.Party,
   269  		stringer.PtrToString(m.InitialMargin),
   270  		stringer.PtrToString(m.MaintenanceMargin),
   271  		stringer.PtrToString(m.CollateralReleaseLevel),
   272  		stringer.PtrToString(m.SearchLevel),
   273  		stringer.PtrToString(m.OrderMargin),
   274  		m.Timestamp,
   275  		m.MarginMode,
   276  		m.MarginFactor.String(),
   277  	)
   278  }
   279  
   280  func (r RiskFactor) IntoProto() *proto.RiskFactor {
   281  	return &proto.RiskFactor{
   282  		Market: r.Market,
   283  		Short:  r.Short.String(),
   284  		Long:   r.Long.String(),
   285  	}
   286  }
   287  
   288  func (r RiskFactor) String() string {
   289  	return fmt.Sprintf(
   290  		"marketID(%s) short(%s) long(%s)",
   291  		r.Market,
   292  		r.Short.String(),
   293  		r.Long.String(),
   294  	)
   295  }
   296  
   297  func (m MarginCalculator) IntoProto() *proto.MarginCalculator {
   298  	return &proto.MarginCalculator{
   299  		ScalingFactors:      m.ScalingFactors.IntoProto(),
   300  		FullyCollateralised: ptr.From(m.FullyCollateralised),
   301  	}
   302  }
   303  
   304  func (m MarginCalculator) String() string {
   305  	return fmt.Sprintf(
   306  		"scalingFactors(%s) fully collateralised(%T)",
   307  		stringer.PtrToString(m.ScalingFactors),
   308  		m.FullyCollateralised,
   309  	)
   310  }
   311  
   312  func (s ScalingFactors) IntoProto() *proto.ScalingFactors {
   313  	sl, _ := s.SearchLevel.Float64()
   314  	im, _ := s.InitialMargin.Float64()
   315  	cr, _ := s.CollateralRelease.Float64()
   316  	return &proto.ScalingFactors{
   317  		SearchLevel:       sl,
   318  		InitialMargin:     im,
   319  		CollateralRelease: cr,
   320  	}
   321  }
   322  
   323  func (s ScalingFactors) String() string {
   324  	return fmt.Sprintf(
   325  		"searchLevel(%s) initialMargin(%s) collateralRelease(%s)",
   326  		s.SearchLevel.String(),
   327  		s.InitialMargin.String(),
   328  		s.CollateralRelease.String(),
   329  	)
   330  }
   331  
   332  func (s *ScalingFactors) Reset() {
   333  	*s = ScalingFactors{}
   334  }
   335  
   336  type SimpleModelParams struct {
   337  	FactorLong           num.Decimal
   338  	FactorShort          num.Decimal
   339  	MaxMoveUp            num.Decimal
   340  	MinMoveDown          num.Decimal
   341  	ProbabilityOfTrading num.Decimal
   342  }
   343  
   344  func isTRMFromProto(p interface{}) isTRM {
   345  	switch tirm := p.(type) {
   346  	case *proto.TradableInstrument_SimpleRiskModel:
   347  		return TradableInstrumentSimpleFromProto(tirm)
   348  	case *proto.TradableInstrument_LogNormalRiskModel:
   349  		return TradableInstrumentLogNormalFromProto(tirm)
   350  	}
   351  	// default to nil simple params
   352  	return TradableInstrumentSimpleFromProto(nil)
   353  }
   354  
   355  func LogNormalParamsFromProto(p *proto.LogNormalModelParams) *LogNormalModelParams {
   356  	if p == nil {
   357  		return nil
   358  	}
   359  	return &LogNormalModelParams{
   360  		Mu:    num.DecimalFromFloat(p.Mu),
   361  		R:     num.DecimalFromFloat(p.R),
   362  		Sigma: num.DecimalFromFloat(p.Sigma),
   363  	}
   364  }
   365  
   366  func TradableInstrumentLogNormalFromProto(p *proto.TradableInstrument_LogNormalRiskModel) *TradableInstrumentLogNormalRiskModel {
   367  	if p == nil {
   368  		return nil
   369  	}
   370  	var override *RiskFactorOverride
   371  	if p.LogNormalRiskModel.RiskFactorOverride != nil {
   372  		override = &RiskFactorOverride{
   373  			Short: num.MustDecimalFromString(p.LogNormalRiskModel.RiskFactorOverride.Short),
   374  			Long:  num.MustDecimalFromString(p.LogNormalRiskModel.RiskFactorOverride.Long),
   375  		}
   376  	}
   377  
   378  	return &TradableInstrumentLogNormalRiskModel{
   379  		LogNormalRiskModel: &LogNormalRiskModel{
   380  			RiskAversionParameter: num.DecimalFromFloat(p.LogNormalRiskModel.RiskAversionParameter),
   381  			Tau:                   num.DecimalFromFloat(p.LogNormalRiskModel.Tau),
   382  			Params:                LogNormalParamsFromProto(p.LogNormalRiskModel.Params),
   383  			RiskFactorOverride:    override,
   384  		},
   385  	}
   386  }
   387  
   388  func SimpleModelParamsFromProto(p *proto.SimpleModelParams) *SimpleModelParams {
   389  	return &SimpleModelParams{
   390  		FactorLong:           num.DecimalFromFloat(p.FactorLong),
   391  		FactorShort:          num.DecimalFromFloat(p.FactorShort),
   392  		MaxMoveUp:            num.DecimalFromFloat(p.MaxMoveUp),
   393  		MinMoveDown:          num.DecimalFromFloat(p.MinMoveDown),
   394  		ProbabilityOfTrading: num.DecimalFromFloat(p.ProbabilityOfTrading),
   395  	}
   396  }
   397  
   398  type TradableInstrumentSimpleRiskModel struct {
   399  	SimpleRiskModel *SimpleRiskModel
   400  }
   401  
   402  func (t TradableInstrumentSimpleRiskModel) String() string {
   403  	return fmt.Sprintf(
   404  		"simpleRiskModel(%s)",
   405  		stringer.PtrToString(t.SimpleRiskModel),
   406  	)
   407  }
   408  
   409  func (TradableInstrumentSimpleRiskModel) isTRM() {}
   410  
   411  func (t TradableInstrumentSimpleRiskModel) IntoProto() *proto.TradableInstrument_SimpleRiskModel {
   412  	return &proto.TradableInstrument_SimpleRiskModel{
   413  		SimpleRiskModel: t.SimpleRiskModel.IntoProto(),
   414  	}
   415  }
   416  
   417  func (t TradableInstrumentSimpleRiskModel) trmIntoProto() interface{} {
   418  	return t.IntoProto()
   419  }
   420  
   421  func (TradableInstrumentSimpleRiskModel) rmType() rmType {
   422  	return SimpleRiskModelType
   423  }
   424  
   425  // Equal returns true if the risk models match.
   426  func (t TradableInstrumentSimpleRiskModel) Equal(trm isTRM) bool {
   427  	var ct *TradableInstrumentSimpleRiskModel
   428  	switch et := trm.(type) {
   429  	case *TradableInstrumentSimpleRiskModel:
   430  		ct = et
   431  	case TradableInstrumentSimpleRiskModel:
   432  		ct = &et
   433  	}
   434  	if ct == nil {
   435  		return false
   436  	}
   437  	if !t.SimpleRiskModel.Params.FactorLong.Equal(ct.SimpleRiskModel.Params.FactorLong) {
   438  		return false
   439  	}
   440  	if !t.SimpleRiskModel.Params.FactorShort.Equal(ct.SimpleRiskModel.Params.FactorShort) {
   441  		return false
   442  	}
   443  	if !t.SimpleRiskModel.Params.MinMoveDown.Equal(ct.SimpleRiskModel.Params.MinMoveDown) {
   444  		return false
   445  	}
   446  	if !t.SimpleRiskModel.Params.MaxMoveUp.Equal(ct.SimpleRiskModel.Params.MaxMoveUp) {
   447  		return false
   448  	}
   449  	return t.SimpleRiskModel.Params.ProbabilityOfTrading.Equal(ct.SimpleRiskModel.Params.ProbabilityOfTrading)
   450  }
   451  
   452  func TradableInstrumentSimpleFromProto(p *proto.TradableInstrument_SimpleRiskModel) *TradableInstrumentSimpleRiskModel {
   453  	if p == nil {
   454  		return nil
   455  	}
   456  	return &TradableInstrumentSimpleRiskModel{
   457  		SimpleRiskModel: &SimpleRiskModel{
   458  			Params: SimpleModelParamsFromProto(p.SimpleRiskModel.Params),
   459  		},
   460  	}
   461  }
   462  
   463  type SimpleRiskModel struct {
   464  	Params *SimpleModelParams
   465  }
   466  
   467  func (s SimpleRiskModel) IntoProto() *proto.SimpleRiskModel {
   468  	return &proto.SimpleRiskModel{
   469  		Params: s.Params.IntoProto(),
   470  	}
   471  }
   472  
   473  func (s SimpleRiskModel) String() string {
   474  	return fmt.Sprintf(
   475  		"params(%s)",
   476  		stringer.PtrToString(s.Params),
   477  	)
   478  }
   479  
   480  func (s SimpleModelParams) IntoProto() *proto.SimpleModelParams {
   481  	lng, _ := s.FactorLong.Float64()
   482  	sht, _ := s.FactorShort.Float64()
   483  	up, _ := s.MaxMoveUp.Float64()
   484  	down, _ := s.MinMoveDown.Float64()
   485  	prob, _ := s.ProbabilityOfTrading.Float64()
   486  	return &proto.SimpleModelParams{
   487  		FactorLong:           lng,
   488  		FactorShort:          sht,
   489  		MaxMoveUp:            up,
   490  		MinMoveDown:          down,
   491  		ProbabilityOfTrading: prob,
   492  	}
   493  }
   494  
   495  func (s SimpleModelParams) String() string {
   496  	return fmt.Sprintf(
   497  		"probabilityOfTrading(%s) factor(short(%s) long(%s)) minMoveDown(%s) maxMoveUp(%s)",
   498  		s.ProbabilityOfTrading.String(),
   499  		s.FactorShort.String(),
   500  		s.FactorLong.String(),
   501  		s.MinMoveDown.String(),
   502  		s.MaxMoveUp.String(),
   503  	)
   504  }
   505  
   506  func (s SimpleModelParams) DeepClone() *SimpleModelParams {
   507  	return &SimpleModelParams{
   508  		FactorLong:           s.FactorLong,
   509  		FactorShort:          s.FactorShort,
   510  		MaxMoveUp:            s.MaxMoveUp,
   511  		MinMoveDown:          s.MinMoveDown,
   512  		ProbabilityOfTrading: s.ProbabilityOfTrading,
   513  	}
   514  }
   515  
   516  type MarginMode = proto.MarginMode
   517  
   518  const (
   519  	MarginModeUnspecified    MarginMode = proto.MarginMode_MARGIN_MODE_UNSPECIFIED
   520  	MarginModeCrossMargin    MarginMode = proto.MarginMode_MARGIN_MODE_CROSS_MARGIN
   521  	MarginModeIsolatedMargin MarginMode = proto.MarginMode_MARGIN_MODE_ISOLATED_MARGIN
   522  )