copy_position.dart 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import '../../../core/utils/avatar_urls.dart';
  2. /// 跟单仓位
  3. class CopyPosition {
  4. final String id;
  5. final String symbol;
  6. final String direction; // 'long' | 'short'
  7. final String positionType; // '全仓' | '逐仓'
  8. final int leverage;
  9. final String traderId;
  10. final String traderName;
  11. final String? traderAvatar;
  12. final double openPrice;
  13. final double currentPrice;
  14. final double quantity;
  15. final double unrealizedPnl;
  16. final double roi;
  17. final DateTime openTime;
  18. final double margin; // 当前保证金 USDT
  19. final bool isNoLoss; // 是否为无损跟单(L5交易员,跟单员不可手动平仓)
  20. final double? closePrice; // 平仓均价(历史跟单)
  21. final DateTime? closeTime; // 平仓时间(历史跟单)
  22. const CopyPosition({
  23. required this.id,
  24. required this.symbol,
  25. required this.direction,
  26. required this.positionType,
  27. required this.leverage,
  28. required this.traderId,
  29. required this.traderName,
  30. this.traderAvatar,
  31. required this.openPrice,
  32. required this.currentPrice,
  33. required this.quantity,
  34. required this.unrealizedPnl,
  35. required this.roi,
  36. required this.openTime,
  37. this.margin = 0,
  38. this.isNoLoss = false,
  39. this.closePrice,
  40. this.closeTime,
  41. });
  42. bool get isLong => direction == 'long';
  43. /// 从 API FollowOrder Map 构建
  44. factory CopyPosition.fromApi(Map<String, dynamic> json) {
  45. double _d(String key) =>
  46. double.tryParse((json[key] ?? '0').toString()) ?? 0.0;
  47. int _i(String key) => int.tryParse((json[key] ?? '0').toString()) ?? 0;
  48. final directionInt = _i('direction');
  49. final direction = directionInt == 0 ? 'long' : 'short';
  50. DateTime _fromMs(dynamic ms) {
  51. if (ms == null) return DateTime.now();
  52. return DateTime.fromMillisecondsSinceEpoch((ms as num).toInt());
  53. }
  54. final closeMs = json['closeTime'];
  55. final closePriceVal = json['closePrice'];
  56. return CopyPosition(
  57. id: json['positionId']?.toString() ?? '',
  58. symbol: json['symbol']?.toString() ?? '',
  59. direction: direction,
  60. positionType: '全仓',
  61. leverage: _i('leverage'),
  62. traderId: json['traderId']?.toString() ?? '',
  63. traderName: json['traderNickname']?.toString() ?? '',
  64. traderAvatar: normalizeAvatarHttpUrl(json['traderAvatar']?.toString() ??
  65. json['avatar']?.toString() ??
  66. json['headImg']?.toString()),
  67. openPrice: _d('openPrice'),
  68. currentPrice: _d('currentPrice'),
  69. quantity: _d('totalPosition'),
  70. unrealizedPnl: _d('profit'),
  71. roi: _d('profitRate'),
  72. openTime: _fromMs(json['openTime']),
  73. margin: _d('principalAmount'),
  74. isNoLoss: json['specialTrader'] == true,
  75. closePrice: closePriceVal != null
  76. ? double.tryParse(closePriceVal.toString())
  77. : null,
  78. closeTime: closeMs != null ? _fromMs(closeMs) : null,
  79. );
  80. }
  81. }