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 )