be-components 3.0.3 → 3.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/lib/commonjs/Components/Button.js +6 -4
  2. package/lib/commonjs/Components/Button.js.map +1 -1
  3. package/lib/commonjs/Components/ConfirmationModal.js +83 -0
  4. package/lib/commonjs/Components/ConfirmationModal.js.map +1 -0
  5. package/lib/commonjs/MarketComponents/api/index.js +107 -20
  6. package/lib/commonjs/MarketComponents/api/index.js.map +1 -1
  7. package/lib/commonjs/MarketComponents/components/BestAvailableOrderCard.js +152 -0
  8. package/lib/commonjs/MarketComponents/components/BestAvailableOrderCard.js.map +1 -0
  9. package/lib/commonjs/MarketComponents/components/ContestOrderStatsCard.js +241 -0
  10. package/lib/commonjs/MarketComponents/components/ContestOrderStatsCard.js.map +1 -0
  11. package/lib/commonjs/MarketComponents/components/MyOrderList/api/index.js +503 -0
  12. package/lib/commonjs/MarketComponents/components/MyOrderList/api/index.js.map +1 -0
  13. package/lib/commonjs/MarketComponents/components/MyOrderList/index.js +276 -0
  14. package/lib/commonjs/MarketComponents/components/MyOrderList/index.js.map +1 -0
  15. package/lib/commonjs/MarketComponents/components/OrderBook.js +200 -0
  16. package/lib/commonjs/MarketComponents/components/OrderBook.js.map +1 -0
  17. package/lib/commonjs/MarketComponents/components/OrderBookChart.js +276 -0
  18. package/lib/commonjs/MarketComponents/components/OrderBookChart.js.map +1 -0
  19. package/lib/commonjs/MarketComponents/components/OrderGradeBar.js +2 -1
  20. package/lib/commonjs/MarketComponents/components/OrderGradeBar.js.map +1 -1
  21. package/lib/commonjs/MarketComponents/index.js +11 -1
  22. package/lib/commonjs/MarketComponents/index.js.map +1 -1
  23. package/lib/commonjs/Socket/index.js +0 -1
  24. package/lib/commonjs/Socket/index.js.map +1 -1
  25. package/lib/module/Components/Button.js +6 -4
  26. package/lib/module/Components/Button.js.map +1 -1
  27. package/lib/module/Components/ConfirmationModal.js +76 -0
  28. package/lib/module/Components/ConfirmationModal.js.map +1 -0
  29. package/lib/module/MarketComponents/api/index.js +107 -20
  30. package/lib/module/MarketComponents/api/index.js.map +1 -1
  31. package/lib/module/MarketComponents/components/BestAvailableOrderCard.js +145 -0
  32. package/lib/module/MarketComponents/components/BestAvailableOrderCard.js.map +1 -0
  33. package/lib/module/MarketComponents/components/ContestOrderStatsCard.js +232 -0
  34. package/lib/module/MarketComponents/components/ContestOrderStatsCard.js.map +1 -0
  35. package/lib/module/MarketComponents/components/MyOrderList/api/index.js +496 -0
  36. package/lib/module/MarketComponents/components/MyOrderList/api/index.js.map +1 -0
  37. package/lib/module/MarketComponents/components/MyOrderList/index.js +268 -0
  38. package/lib/module/MarketComponents/components/MyOrderList/index.js.map +1 -0
  39. package/lib/module/MarketComponents/components/OrderBook.js +193 -0
  40. package/lib/module/MarketComponents/components/OrderBook.js.map +1 -0
  41. package/lib/module/MarketComponents/components/OrderBookChart.js +267 -0
  42. package/lib/module/MarketComponents/components/OrderBookChart.js.map +1 -0
  43. package/lib/module/MarketComponents/components/OrderGradeBar.js +2 -1
  44. package/lib/module/MarketComponents/components/OrderGradeBar.js.map +1 -1
  45. package/lib/module/MarketComponents/index.js +11 -1
  46. package/lib/module/MarketComponents/index.js.map +1 -1
  47. package/lib/module/Socket/index.js +0 -1
  48. package/lib/module/Socket/index.js.map +1 -1
  49. package/lib/typescript/src/Components/Button.d.ts.map +1 -1
  50. package/lib/typescript/src/Components/ConfirmationModal.d.ts +13 -0
  51. package/lib/typescript/src/Components/ConfirmationModal.d.ts.map +1 -0
  52. package/lib/typescript/src/MarketComponents/api/index.d.ts +9 -2
  53. package/lib/typescript/src/MarketComponents/api/index.d.ts.map +1 -1
  54. package/lib/typescript/src/MarketComponents/components/BestAvailableOrderCard.d.ts +13 -0
  55. package/lib/typescript/src/MarketComponents/components/BestAvailableOrderCard.d.ts.map +1 -0
  56. package/lib/typescript/src/MarketComponents/components/ContestOrderStatsCard.d.ts +15 -0
  57. package/lib/typescript/src/MarketComponents/components/ContestOrderStatsCard.d.ts.map +1 -0
  58. package/lib/typescript/src/MarketComponents/components/MyOrderList/api/index.d.ts +18 -0
  59. package/lib/typescript/src/MarketComponents/components/MyOrderList/api/index.d.ts.map +1 -0
  60. package/lib/typescript/src/MarketComponents/components/MyOrderList/index.d.ts +10 -0
  61. package/lib/typescript/src/MarketComponents/components/MyOrderList/index.d.ts.map +1 -0
  62. package/lib/typescript/src/MarketComponents/components/OrderBook.d.ts +13 -0
  63. package/lib/typescript/src/MarketComponents/components/OrderBook.d.ts.map +1 -0
  64. package/lib/typescript/src/MarketComponents/components/OrderBookChart.d.ts +16 -0
  65. package/lib/typescript/src/MarketComponents/components/OrderBookChart.d.ts.map +1 -0
  66. package/lib/typescript/src/MarketComponents/components/OrderGradeBar.d.ts.map +1 -1
  67. package/lib/typescript/src/MarketComponents/index.d.ts +57 -0
  68. package/lib/typescript/src/MarketComponents/index.d.ts.map +1 -1
  69. package/lib/typescript/src/Socket/index.d.ts.map +1 -1
  70. package/package.json +1 -1
  71. package/src/Components/Button.tsx +2 -3
  72. package/src/Components/ConfirmationModal.tsx +57 -0
  73. package/src/MarketComponents/api/index.ts +80 -15
  74. package/src/MarketComponents/components/BestAvailableOrderCard.tsx +84 -0
  75. package/src/MarketComponents/components/ContestOrderStatsCard.tsx +154 -0
  76. package/src/MarketComponents/components/MyOrderList/api/index.ts +406 -0
  77. package/src/MarketComponents/components/MyOrderList/index.tsx +192 -0
  78. package/src/MarketComponents/components/OrderBook.tsx +99 -0
  79. package/src/MarketComponents/components/OrderBookChart.tsx +139 -0
  80. package/src/MarketComponents/components/OrderGradeBar.tsx +2 -1
  81. package/src/MarketComponents/index.tsx +11 -1
  82. package/src/Socket/index.tsx +0 -1
  83. package/src/types.d.ts +56 -0
@@ -0,0 +1,406 @@
1
+ import moment from "moment-mini";
2
+ import type { EventProps, HedgedPositionProps, HedgeProps, MarketProps, MatchProps, OrderProps, OrderStatsProps, PositionProps, TournamentProps } from "../../../../types";
3
+ import { MarketComponentHelpers } from "../../../api";
4
+
5
+
6
+ export const MyOrdersHelpers = {
7
+ getContestsFromOrders: (orders:OrderProps[]) => {
8
+ let event_ids = [ ...new Set(orders.filter(o => o.event_type == 'team').map(o => o.event_id))]
9
+ let tournament_ids = [ ...new Set(orders.filter(o => o.event_type == 'tournament').map(o => o.event_id))]
10
+ let match_ids = [ ...new Set(orders.filter(o => o.event_type == 'match').map(o => o.event_id))]
11
+ return { event_ids, tournament_ids, match_ids }
12
+ },
13
+ getHedgesFromPositions: (orders:OrderProps[], markets:MarketProps[]):HedgeProps[] => {
14
+ //1) Set up arrays to store hedges
15
+ let hedges:HedgeProps[] = []
16
+ let hedgeable_positions:Array<OrderProps[]> = []
17
+ //Only allow real money orders for hedging
18
+ orders = orders.filter(o => o.market_type === 'FOR_MONEY' && o.resolution_status !== 'closed')
19
+
20
+ //2) Get the unique markets (and common var_1s) that are eligible to be hedged
21
+ let orders_with_positions = orders.filter(o => o.positions[0])
22
+ let unique_markets = [ ...new Set(orders_with_positions.map(o => `${o.event_id}:${o.event_type}:${o.market_id}:${Math.abs(o.var_1)}`)) ]
23
+
24
+ //3) For each unique market and var_1 combo, determin if there are positions on the opposite side of each other
25
+ //If so, then store them into an array of orders
26
+ unique_markets.map(id => {
27
+ //1) Get orders that are associated with the market
28
+ let market_orders = orders_with_positions.filter(o => `${o.event_id}:${o.event_type}:${o.market_id}:${Math.abs(o.var_1)}` == id)
29
+ if(market_orders.length < 2){ return } //Impossible to hedge with less than 2 orders
30
+ let unique_sides = [ ...new Set(market_orders.map(o => o.side)) ]
31
+ if(unique_sides.length < 0){ return } //Must have more than 1 side
32
+
33
+ hedgeable_positions.push(market_orders)
34
+ })
35
+
36
+ //Return nothing if there are no hedgeable positions
37
+ if(hedgeable_positions.length === 0){ return [] }
38
+
39
+ //Awesome! We have some hedgeable positions
40
+ hedgeable_positions.map(hp => {
41
+ //Get an empty hedge object to store our hedges
42
+ let hedge = MyOrdersHelpers.getEmptyHedge()
43
+ let market = markets.find(m => m.market_id == hp[0]?.market_id)
44
+ if(!market){ return } //Error out if there is no market
45
+ if(market.level !== 'event'){ return } //Dont if level is not event
46
+
47
+ let trade_side_orders = hp.filter(o => o.side == market?.trade_side)
48
+ let o_side_orders = hp.filter(o => o.side != market?.trade_side)
49
+
50
+ //New
51
+ if(market.type == 'Spread'){
52
+ let this_order = trade_side_orders[0]
53
+ if(!this_order){ return } //Make sure there is at least 1 trade side order
54
+ o_side_orders = o_side_orders.filter(o => o.var_1 == this_order.var_1 * -1)
55
+ }
56
+
57
+ if(trade_side_orders.length === 0 || o_side_orders.length === 0){ return }
58
+
59
+ if(!hp[0]){ return }
60
+
61
+
62
+ hedge.market_id = market.market_id
63
+ hedge.market_type = hp[0].market_type
64
+ hedge.var_1 = Math.abs(hp[0].var_1)
65
+ hedge.player_id = hp[0].player_id
66
+ hedge.event_id = hp[0].event_id
67
+ hedge.event_type = hp[0].event_type
68
+ hedge.market_id = hp[0].market_id
69
+
70
+
71
+
72
+ //Set up arrays to store the positions on each side of the hedge
73
+ let trade_side_positions:PositionProps[] = []
74
+ let o_side_positions:PositionProps[] = []
75
+ trade_side_orders.map(o => {
76
+ trade_side_positions = trade_side_positions.concat(o.positions)
77
+ })
78
+ o_side_orders.map(o => {
79
+ o_side_positions = o_side_positions.concat(o.positions)
80
+ })
81
+
82
+ //Calculate the winnings from each outcome (side a wins, side b wins, or draw)
83
+ let trade_side_pot_winnings = trade_side_positions.reduce((a,b) => a + b.potential_winnings, 0)
84
+ let o_side_pot_winnings = o_side_positions.reduce((a,b) => a + b.potential_winnings, 0)
85
+ let draw_winnings = trade_side_positions.concat(o_side_positions).reduce((a,b) => a + b.stake, 0)
86
+
87
+ //Get the minimum payout possible of the 3 outcomes which is the hedged amount
88
+ let hedged_amt = Math.min(trade_side_pot_winnings, o_side_pot_winnings)
89
+ if(isNaN(hedged_amt)){ return }
90
+ hedge.hedged_amt = hedged_amt
91
+
92
+ //Now lets cals out hedged positions
93
+ let hedged_positions:HedgedPositionProps[] = []
94
+
95
+ trade_side_positions.map(p => {
96
+ //Need to determine the weight of the position on the total potential winnings and reduce the stake proportionately
97
+ let pct = p.potential_winnings / trade_side_pot_winnings
98
+ //console.log(hedged_amt, pct, p.probability)
99
+ let stake_from_hedge = hedged_amt * pct * p.probability
100
+ hedge.stake_reduction += stake_from_hedge
101
+ let new_stake = p.stake - stake_from_hedge
102
+ hedged_positions.push({
103
+ hedge_id:'',
104
+ hedged_position_id: '',
105
+ position_id: p.position_id,
106
+ original_stake: p.stake,
107
+ new_stake,
108
+ delayed_cash_draw: 0,
109
+ delayed_cash_no_draw: 0,
110
+ original_potential_winnings: p.potential_winnings,
111
+ new_potential_winnings: new_stake / p.probability,
112
+ status: 'pending',
113
+ create_datetime:'',
114
+ last_update_datetime:''
115
+ })
116
+ })
117
+
118
+ o_side_positions.map(p => {
119
+ let pct = p.potential_winnings / o_side_pot_winnings
120
+ let stake_from_hedge = hedged_amt * pct * p.probability
121
+ hedge.stake_reduction += stake_from_hedge
122
+ let new_stake = p.stake - stake_from_hedge
123
+ hedged_positions.push({
124
+ hedge_id:'',
125
+ hedged_position_id: '',
126
+ position_id: p.position_id,
127
+ original_stake: p.stake,
128
+ new_stake,
129
+ delayed_cash_draw: 0,
130
+ delayed_cash_no_draw: 0,
131
+ original_potential_winnings: p.potential_winnings,
132
+ new_potential_winnings: new_stake / p.probability,
133
+ status: 'pending',
134
+ create_datetime:'',
135
+ last_update_datetime:''
136
+ })
137
+ })
138
+
139
+
140
+ //Cash rcvd will be the lower of the hedged amount or the reduction in stake
141
+ let cash_rcvd = Math.min(hedge.stake_reduction, hedged_amt, draw_winnings)
142
+ if(isNaN(cash_rcvd) || cash_rcvd < 0.01){ return }
143
+ hedge.cash_rcvd = cash_rcvd
144
+ let delayed_cash = hedged_amt - hedge.stake_reduction
145
+ let total_og_stake = hedged_positions.reduce((a,b) => a + b.original_stake, 0)
146
+ let delayed_cash_draw = 0, delayed_cash_no_draw = 0;
147
+ if(delayed_cash < 0){
148
+ delayed_cash_draw = delayed_cash * -1
149
+ //hedge.delayed_cash_draw = delayed_cash * -1 //Need to make positive
150
+ } else {
151
+ delayed_cash_no_draw = delayed_cash
152
+ //hedge.delayed_cash_no_draw = delayed_cash
153
+ }
154
+ hedge.delayed_cash_draw = delayed_cash_draw
155
+ hedge.delayed_cash_no_draw = delayed_cash_no_draw
156
+
157
+ hedged_positions.map(hp => {
158
+ let pct_of_total = hp.original_stake / total_og_stake
159
+ hp.delayed_cash_draw = pct_of_total * delayed_cash_draw
160
+ hp.delayed_cash_no_draw = pct_of_total * delayed_cash_no_draw
161
+ return hp
162
+ })
163
+
164
+ hedges.push({ ...hedge, hedged_positions:hedged_positions })
165
+ })
166
+
167
+ return hedges
168
+ },
169
+ getEmptyHedge: ():HedgeProps => {
170
+ let uuid = Math.floor(Math.random() * 100000000)
171
+ return {
172
+ hedge_id: uuid.toString(),
173
+ hedged_amt: 0,
174
+ event_id: '',
175
+ event_type: '',
176
+ market_id: '',
177
+ var_1: 0,
178
+ delayed_cash_draw: 0,
179
+ delayed_cash_no_draw: 0,
180
+ cash_rcvd: 0,
181
+ stake_reduction: 0,
182
+ market_type: 'FOR_MONEY',
183
+ create_datetime: '',
184
+ last_udpate_datetime:'',
185
+ player_id: '',
186
+ status: 'pending'
187
+ }
188
+ },
189
+ getDetailsForStat: (order_stat:OrderStatsProps, events:EventProps[], tournaments:TournamentProps[], matches:MatchProps[]):{ contest_title:string, contest_time_detail:string, league_id:string } => {
190
+ let fail_response = { contest_title: 'TBD', contest_time_detail: 'TBD', league_id:'' }
191
+ switch(order_stat.event_type){
192
+ case 'team':
193
+ let event = events.find(e => e.event_id == order_stat.event_id);
194
+ if(!event){ return fail_response }
195
+ return {
196
+ league_id: event.league_id,
197
+ contest_title: `${event.away?.abbr} ${event.away_team_score} - ${event.home?.abbr} ${event.home_team_score}`,
198
+ contest_time_detail: event.time_detail && event.time_detail != 'scheduled' ? event.time_detail : moment(event.scheduled_datetime).format('MM/DD @ hh:mm a')
199
+ }
200
+ case 'tournament':
201
+ let tournament = tournaments.find(t => t.tournament_id == order_stat.event_id)
202
+ if(!tournament) { return fail_response }
203
+ return {
204
+ league_id: tournament.league_id,
205
+ contest_title: tournament.tournament_name,
206
+ contest_time_detail: moment(tournament.scheduled_datetime).format('MM/DD/YYYY')
207
+ }
208
+ case 'match':
209
+ let match = matches.find(m => m.match_id == order_stat.event_id)
210
+ if(!match){ return fail_response }
211
+ let match_tournament = tournaments.find(t => t.tournament_id == match.tournament_id);
212
+ return {
213
+ league_id: match_tournament?.league_id ?? '',
214
+ contest_title: match.match_title,
215
+ contest_time_detail: match.time_detail && match.time_detail != 'scheduled' ? match.time_detail : moment(match.scheduled_datetime).format('MM/DD @ hh:mm a')
216
+ }
217
+ default:
218
+ return fail_response
219
+ }
220
+ },
221
+ calcOrderStats: (orders:OrderProps[], player_id:string):OrderStatsProps[] => {
222
+ let order_stats:OrderStatsProps[] = []
223
+ let unique_headers = [ ...new Set(orders.map(o => `${o.event_id}:${o.event_type}`)) ]
224
+ let wins = 0, losses = 0, draws = 0;
225
+ unique_headers.map(h => {
226
+ let contest_id = h.split(':')[0]
227
+ let contest_type = h.split(':')[1]
228
+ if(!contest_id || !contest_type){ return }
229
+ let found_orders = orders.filter(o => `${o.event_id}:${o.event_type}` === h)
230
+ if(found_orders.length === 0){ return; }
231
+ let max_last_update = found_orders.filter(o => o.status == 'approved').find(o => Math.min(moment(o.expire_datetime).unix()))?.expire_datetime
232
+ if(!max_last_update){ max_last_update = moment().add(1, 'year') }
233
+ let unique_order_titles = [ ...new Set(found_orders.map(o => o.title)) ]
234
+ let open_order_count = 0, open_amt = 0, potential_winnings = 0, called_amt = 0, commission = 0;
235
+ let resolved_stake = 0, original_stake = 0, delayed_cash = 0, winnings = 0, net_winnings = 0, unresolved_stake = 0, resolved_potential_winnings = 0, unresolved_potential_net_winnings = 0, unresolved_potential_winnings = 0, num_trades = 0, cash_rcvd = 0;
236
+ let result_ind:string|undefined = undefined
237
+ let order_ids:string[] = []
238
+ let open_orders:string[] = []
239
+ found_orders.map(o => {
240
+ let commission_pct = 0
241
+ if(o.commission_pct){ commission_pct = o.commission_pct }
242
+ order_ids.push(o.order_id)
243
+ if(o.status === 'approved'){
244
+ open_orders.push(o.order_id)
245
+ open_amt += o.open_amt
246
+ open_order_count += 1
247
+ potential_winnings += o.potential_winnings
248
+ called_amt += o.called_amt
249
+ }
250
+ if(!o.positions){ return }
251
+ o.positions.map(p => {
252
+ if(!p){ return }
253
+ num_trades += 1
254
+ cash_rcvd += p.cash_rcvd
255
+ if(!p.result_ind){
256
+ delayed_cash += p.delayed_cash
257
+ unresolved_stake += p.stake
258
+ unresolved_potential_winnings += p.potential_winnings
259
+ unresolved_potential_net_winnings += (p.potential_winnings - ((p.potential_winnings - p.stake) * commission_pct))
260
+ } else {
261
+ resolved_stake += p.stake
262
+ original_stake += p.original_stake
263
+ winnings += p.winnings
264
+ net_winnings += p.net_winnings
265
+ result_ind = p.result_ind
266
+ commission += p.commission
267
+ resolved_potential_winnings += p.potential_winnings
268
+ }
269
+ })
270
+ })
271
+ if(result_ind == 'win'){ wins += 1 }
272
+ if(result_ind == 'lose'){ losses += 1 }
273
+ if(result_ind == 'draw'){ draws += 1 }
274
+ let unresolved_position_probability = unresolved_stake / unresolved_potential_winnings
275
+ let resolved_position_probability = resolved_stake / resolved_potential_winnings
276
+ let unresolved_position_odds = MarketComponentHelpers.calcAmericanOddsFromProbability(unresolved_position_probability)
277
+ let resolved_position_odds = MarketComponentHelpers.calcAmericanOddsFromProbability(resolved_position_probability)
278
+
279
+ let offer_probability = open_amt / potential_winnings
280
+ let offer_odds = MarketComponentHelpers.calcAmericanOddsFromProbability(offer_probability)
281
+ let earnings = winnings + cash_rcvd - original_stake
282
+ let roi = earnings / original_stake
283
+ return order_stats.push({
284
+ stat_id: h,
285
+ unresolved_stake,
286
+ earnings,
287
+ resolved_stake,
288
+ unique_order_titles,
289
+ original_stake,
290
+ roi,
291
+ wins,
292
+ net_winnings,
293
+ commission,
294
+ unresolved_potential_net_winnings,
295
+ losses,
296
+ draws,
297
+ unresolved_position_odds,
298
+ resolved_position_odds,
299
+ result_ind,
300
+ delayed_cash,
301
+ unresolved_potential_winnings,
302
+ resolved_potential_winnings,
303
+ resolved_position_probability,
304
+ unresolved_position_probability,
305
+ num_trades,
306
+ cash_rcvd,
307
+ winnings,
308
+ player_id,
309
+ event_id: contest_id,
310
+ event_type: contest_type,
311
+ open_amt, potential_winnings, called_amt, offer_odds, offer_probability,
312
+ orders: order_ids,
313
+ open_orders,
314
+ last_update_datetime: max_last_update
315
+ })
316
+ })
317
+ return order_stats
318
+ },
319
+ calcAllOrderStats: (orders:OrderProps[]):OrderStatsProps => {
320
+ let open_order_count = 0, open_amt = 0, potential_winnings = 0, called_amt = 0, commission = 0;
321
+ let resolved_stake = 0, original_stake = 0, delayed_cash = 0, winnings = 0, net_winnings = 0, unresolved_stake = 0, resolved_potential_winnings = 0, unresolved_potential_winnings = 0, unresolved_potential_net_winnings = 0, num_trades = 0, cash_rcvd = 0;
322
+ let unique_order_titles = [ ...new Set(orders.map(o => o.title)) ]
323
+ let result_ind:string|undefined = undefined
324
+ let order_ids:string[] = []
325
+ let open_orders:string[] = []
326
+ let wins = 0, losses = 0, draws = 0;
327
+ orders.map(o => {
328
+ let commission_pct = 0
329
+ if(o.commission_pct){ commission_pct = o.commission_pct }
330
+ order_ids.push(o.order_id)
331
+ if(o.status === 'approved'){
332
+ open_orders.push(o.order_id)
333
+ open_amt += o.open_amt
334
+ open_order_count += 1
335
+ potential_winnings += o.potential_winnings
336
+ called_amt += o.called_amt
337
+ }
338
+ if(!o.positions){ return }
339
+ o.positions.map(p => {
340
+ if(!p){ return }
341
+ num_trades += 1
342
+ cash_rcvd += p.cash_rcvd
343
+ if(!p.result_ind){
344
+ delayed_cash += p.delayed_cash
345
+ unresolved_stake += p.stake
346
+ unresolved_potential_winnings += p.potential_winnings
347
+ unresolved_potential_net_winnings += (p.potential_winnings - ((p.potential_winnings - p.stake) * commission_pct))
348
+
349
+ } else {
350
+ resolved_stake += p.stake
351
+ original_stake += p.original_stake
352
+ winnings += p.winnings
353
+ net_winnings += p.net_winnings
354
+ result_ind = p.result_ind
355
+ commission += p.commission
356
+ resolved_potential_winnings += p.potential_winnings
357
+ }
358
+ })
359
+ if(result_ind == 'win'){ wins += 1 }
360
+ if(result_ind == 'lose'){ losses += 1 }
361
+ if(result_ind == 'draw'){ draws += 1 }
362
+ })
363
+
364
+ let unresolved_position_probability = unresolved_stake / unresolved_potential_winnings
365
+ let resolved_position_probability = resolved_stake / resolved_potential_winnings
366
+ let unresolved_position_odds = MarketComponentHelpers.calcAmericanOddsFromProbability(unresolved_position_probability)
367
+ let resolved_position_odds = MarketComponentHelpers.calcAmericanOddsFromProbability(resolved_position_probability)
368
+
369
+ let offer_probability = open_amt / potential_winnings
370
+ let offer_odds = MarketComponentHelpers.calcAmericanOddsFromProbability(offer_probability)
371
+ let earnings = winnings + cash_rcvd - original_stake
372
+ let roi = earnings / resolved_stake
373
+ return {
374
+ stat_id: 'ALL',
375
+ unresolved_stake,
376
+ earnings,
377
+ resolved_stake,
378
+ original_stake,
379
+ roi,
380
+ wins,
381
+ losses,
382
+ commission,
383
+ net_winnings,
384
+ unresolved_potential_net_winnings,
385
+ unique_order_titles,
386
+ draws,
387
+ unresolved_position_odds,
388
+ resolved_position_odds,
389
+ result_ind,
390
+ delayed_cash,
391
+ unresolved_potential_winnings,
392
+ resolved_potential_winnings,
393
+ resolved_position_probability,
394
+ unresolved_position_probability,
395
+ num_trades,
396
+ cash_rcvd,
397
+ winnings,
398
+ player_id: orders[0]?.player_id??'0',
399
+ event_id: 'ALL',
400
+ event_type: 'ALL',
401
+ open_amt, potential_winnings, called_amt, offer_odds, offer_probability,
402
+ orders: order_ids,
403
+ open_orders
404
+ }
405
+ }
406
+ }
@@ -0,0 +1,192 @@
1
+ import React, { useState } from 'react';
2
+ import { useEffect } from "react"
3
+ import { ActivityIndicator, FlatList, useWindowDimensions, View } from "react-native";
4
+ import type { EventProps, LeagueProps, MarketProps, MatchProps, OrderProps, OrderStatsProps, TournamentProps } from '../../../types';
5
+ import { MarketComponentApi } from '../../api';
6
+ import Colors from '../../../constants/colors';
7
+ import { MyOrdersHelpers } from './api';
8
+ import ContestOrderStatsCard from '../ContestOrderStatsCard';
9
+ import SocketManager from '../../../Socket';
10
+ import { Text } from '../../../Components';
11
+
12
+ type MyOrderListProps = {
13
+ player_id:string,
14
+ access_token?:string,
15
+ distinct_id?:string,
16
+ market_type:'FOR_MONEY'|'FREE',
17
+ }
18
+
19
+ const MyOrderList = ({ player_id, market_type, access_token, distinct_id }:MyOrderListProps) => {
20
+ const [ needs_reload, setNeedsReload ] = useState(false);
21
+ const [ socket_order, setSocketOrder ] = useState<OrderProps|undefined>(undefined);
22
+ const [ module_data, setModuleData ] = useState<{
23
+ loading:boolean,
24
+ leagues:LeagueProps[],
25
+ orders:OrderProps[],
26
+ markets:MarketProps[],
27
+ events:EventProps[],
28
+ tournaments:TournamentProps[],
29
+ matches:MatchProps[]
30
+ }>({
31
+ loading:false,
32
+ leagues:[],
33
+ orders:[],
34
+ markets: [],
35
+ tournaments:[],
36
+ matches: [],
37
+ events: []
38
+ });
39
+
40
+ const { loading, orders, leagues, tournaments, matches, events, markets } = module_data;
41
+ const { width } = useWindowDimensions();
42
+ const hedges = MyOrdersHelpers.getHedgesFromPositions(orders, markets)
43
+
44
+ useEffect(() => {
45
+ MarketComponentApi.setEnvironment();
46
+ getDataFromServer();
47
+ },[]);
48
+
49
+ //Everytime an order is added to socket order - we update the local data
50
+ useEffect(() => {
51
+ if(!socket_order){ return }
52
+ updateFromSocket(socket_order)
53
+ },[socket_order])
54
+
55
+ const updateFromSocket = async(order:OrderProps) => {
56
+ const { event_ids, tournament_ids, match_ids } = MyOrdersHelpers.getContestsFromOrders([order]);
57
+ let es = await MarketComponentApi.getEventsByEventIds(event_ids);
58
+ let tourneys = await MarketComponentApi.getTournamentsByTournamentIds(tournament_ids);
59
+ let mtchs = await MarketComponentApi.getMatchesByMatchIds(match_ids);
60
+ setModuleData({
61
+ ...module_data,
62
+ orders: orders.filter(o => o.order_id != order.order_id).concat(order),
63
+ events: events.filter(e => !es.find(ne => ne.event_id == e.event_id)).concat(es),
64
+ tournaments: tournaments.filter(t => !tourneys.find(nt => nt.tournament_id == t.tournament_id)).concat(tourneys),
65
+ matches: matches.filter(m => !mtchs.find(nm => nm.match_id == m.match_id)).concat(mtchs)
66
+ });
67
+ }
68
+
69
+ const getDataFromServer = async() => {
70
+ setModuleData({ ...module_data, loading:true });
71
+ let my_orders = await MarketComponentApi.getMyAction()
72
+ const lgs = await MarketComponentApi.getLeagues();
73
+ const mks = await MarketComponentApi.getMarkets();
74
+ const { event_ids, tournament_ids, match_ids } = MyOrdersHelpers.getContestsFromOrders(my_orders);
75
+ let es = await MarketComponentApi.getEventsByEventIds(event_ids);
76
+ let tourneys = await MarketComponentApi.getTournamentsByTournamentIds(tournament_ids);
77
+ let mtchs = await MarketComponentApi.getMatchesByMatchIds(match_ids);
78
+
79
+ setModuleData({
80
+ ...module_data,
81
+ orders: my_orders,
82
+ events: es,
83
+ tournaments: tourneys,
84
+ leagues:lgs,
85
+ markets: mks,
86
+ matches:mtchs,
87
+ loading:false
88
+ })
89
+ }
90
+
91
+ const renderOrderStats = (data: { item:OrderStatsProps, index:number }) => {
92
+ const { contest_title, contest_time_detail, league_id } = MyOrdersHelpers.getDetailsForStat(data.item, events, tournaments, matches);
93
+ const league = leagues.find(l => l.league_id == league_id);
94
+ const event_hedges = hedges.filter(h => h.event_id == data.item.event_id && h.event_type == data.item.event_type)
95
+
96
+ return (
97
+ <ContestOrderStatsCard
98
+ league={league}
99
+ hedges={event_hedges}
100
+ player_order_stat={data.item}
101
+ contest_title={contest_title}
102
+ contest_time_detail={contest_time_detail}
103
+ onPress={(pos) => console.log(pos)}
104
+ market_type={market_type}
105
+ onOrdersUpdate={(os) => console.log(os)}
106
+ />
107
+ )
108
+ }
109
+
110
+
111
+ const event_order_stats = MyOrdersHelpers.calcOrderStats(orders, player_id).sort((a,b) => {
112
+ let a_open = a.open_amt
113
+ let b_open = b.open_amt
114
+ return b_open - a_open
115
+ });
116
+
117
+ const order_stats = MyOrdersHelpers.calcAllOrderStats(orders);
118
+ const cl = market_type == 'FREE' ? 'E' : '$'
119
+ return (
120
+ <View>
121
+ <View nativeID="order_stats" style={{ flexDirection:'row', justifyContent:'center', flexWrap:'wrap' }}>
122
+ {order_stats.open_amt > 0 ?
123
+ <View style={{ justifyContent:'space-between', width: (width/2) - 20, borderRadius:12, backgroundColor:Colors.shades.shade200, padding:20, margin:8}}>
124
+ <Text size={14} color={Colors.brand.cobalt}>Unfulfilled Order Amount</Text>
125
+ <Text size={16} weight='semibold' color={Colors.brand.cyan} style={{ marginTop:3 }}>{cl}{order_stats.open_amt.toFixed(2)}</Text>
126
+ </View>
127
+ :<></>}
128
+ {order_stats.unresolved_stake > 0 ?
129
+ <View style={{ justifyContent:'space-between', width: (width/2) - 20, borderRadius:12, backgroundColor:Colors.shades.shade200, padding:20, margin:8}}>
130
+ <Text size={14} color={Colors.brand.cobalt}>Unsettled Positions</Text>
131
+ <Text size={16} weight='semibold' color={Colors.brand.midnight} style={{ marginTop:3 }}>{order_stats.unresolved_stake.toFixed(2)} to win {cl}{order_stats.unresolved_potential_winnings.toFixed(2)}</Text>
132
+ </View>
133
+ :<></>}
134
+ {order_stats.resolved_stake > 0 ?
135
+ <View style={{ justifyContent:'space-between', width: (width/2) - 20, borderRadius:12, backgroundColor:Colors.shades.shade200, padding:20, margin:8}}>
136
+ <Text size={14} color={Colors.brand.cobalt}>Settled Positions</Text>
137
+ <Text size={16} weight='semibold' color={Colors.brand.midnight} style={{ marginTop:3 }}>{cl}{order_stats.resolved_stake.toFixed(2)}</Text>
138
+ </View>
139
+ :<></>}
140
+ {order_stats.resolved_stake > 0 ?
141
+ <View style={{ justifyContent:'space-between', width: (width/2) - 20, borderRadius:12, backgroundColor:Colors.shades.shade200, padding:20, margin:8}}>
142
+ <Text size={14} color={Colors.brand.cobalt}>Earnings</Text>
143
+ <Text size={16} weight='semibold' color={Colors.brand.midnight} style={{ marginTop:3 }}>{cl}{order_stats.earnings.toFixed(2)} ({(order_stats.roi * 100).toFixed(2)}%)</Text>
144
+ </View>
145
+ :<></>}
146
+ {order_stats.delayed_cash > 0 ?
147
+ <View style={{ justifyContent:'space-between', width: (width/2) - 20, borderRadius:12, backgroundColor:Colors.shades.shade200, padding:20, margin:8}}>
148
+ <Text size={14} color={Colors.brand.cobalt}>Delayed Cash Out</Text>
149
+ <Text size={16} weight='semibold' color={Colors.brand.midnight} style={{ marginTop:3 }}>{cl}{order_stats.delayed_cash.toFixed(2)}</Text>
150
+ </View>
151
+ :<></>}
152
+ </View>
153
+ <FlatList
154
+ key={`${player_id}_order_stats`}
155
+ data={event_order_stats}
156
+ renderItem={renderOrderStats}
157
+ keyExtractor={(item) => item.event_id.toString()}
158
+ />
159
+ <SocketManager
160
+ subscribed_events={['V1_UPDATE_PLAYER_ORDER']}
161
+ access_token={access_token}
162
+ distinct_id={distinct_id}
163
+ onConnect={() => {
164
+ if(needs_reload){
165
+ getDataFromServer()
166
+ setNeedsReload(false);
167
+ }
168
+ }}
169
+ onDisconnect={() => setNeedsReload(true)}
170
+ onSocketEvent={(ev) => {
171
+ switch(ev.type){
172
+ case 'V1_UPDATE_PLAYER_ORDER':
173
+ if(ev.player_id != player_id){ return }
174
+ return setSocketOrder(ev.data)
175
+ default: return
176
+ }
177
+ }}
178
+ />
179
+ {loading ?
180
+ <View style={{ position:'absolute', top:0, left:0, right:0, bottom:0, backgroundColor:Colors.shades.black_faded, justifyContent:'center', alignItems:'center' }}>
181
+ <ActivityIndicator
182
+ size='large'
183
+ color={Colors.brand.midnight}
184
+ />
185
+ </View>
186
+ :<></>}
187
+ </View>
188
+ )
189
+
190
+ }
191
+
192
+ export default MyOrderList