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.
- package/lib/commonjs/Components/Button.js +6 -4
- package/lib/commonjs/Components/Button.js.map +1 -1
- package/lib/commonjs/Components/ConfirmationModal.js +83 -0
- package/lib/commonjs/Components/ConfirmationModal.js.map +1 -0
- package/lib/commonjs/MarketComponents/api/index.js +107 -20
- package/lib/commonjs/MarketComponents/api/index.js.map +1 -1
- package/lib/commonjs/MarketComponents/components/BestAvailableOrderCard.js +152 -0
- package/lib/commonjs/MarketComponents/components/BestAvailableOrderCard.js.map +1 -0
- package/lib/commonjs/MarketComponents/components/ContestOrderStatsCard.js +241 -0
- package/lib/commonjs/MarketComponents/components/ContestOrderStatsCard.js.map +1 -0
- package/lib/commonjs/MarketComponents/components/MyOrderList/api/index.js +503 -0
- package/lib/commonjs/MarketComponents/components/MyOrderList/api/index.js.map +1 -0
- package/lib/commonjs/MarketComponents/components/MyOrderList/index.js +276 -0
- package/lib/commonjs/MarketComponents/components/MyOrderList/index.js.map +1 -0
- package/lib/commonjs/MarketComponents/components/OrderBook.js +200 -0
- package/lib/commonjs/MarketComponents/components/OrderBook.js.map +1 -0
- package/lib/commonjs/MarketComponents/components/OrderBookChart.js +276 -0
- package/lib/commonjs/MarketComponents/components/OrderBookChart.js.map +1 -0
- package/lib/commonjs/MarketComponents/components/OrderGradeBar.js +2 -1
- package/lib/commonjs/MarketComponents/components/OrderGradeBar.js.map +1 -1
- package/lib/commonjs/MarketComponents/index.js +11 -1
- package/lib/commonjs/MarketComponents/index.js.map +1 -1
- package/lib/commonjs/Socket/index.js +0 -1
- package/lib/commonjs/Socket/index.js.map +1 -1
- package/lib/module/Components/Button.js +6 -4
- package/lib/module/Components/Button.js.map +1 -1
- package/lib/module/Components/ConfirmationModal.js +76 -0
- package/lib/module/Components/ConfirmationModal.js.map +1 -0
- package/lib/module/MarketComponents/api/index.js +107 -20
- package/lib/module/MarketComponents/api/index.js.map +1 -1
- package/lib/module/MarketComponents/components/BestAvailableOrderCard.js +145 -0
- package/lib/module/MarketComponents/components/BestAvailableOrderCard.js.map +1 -0
- package/lib/module/MarketComponents/components/ContestOrderStatsCard.js +232 -0
- package/lib/module/MarketComponents/components/ContestOrderStatsCard.js.map +1 -0
- package/lib/module/MarketComponents/components/MyOrderList/api/index.js +496 -0
- package/lib/module/MarketComponents/components/MyOrderList/api/index.js.map +1 -0
- package/lib/module/MarketComponents/components/MyOrderList/index.js +268 -0
- package/lib/module/MarketComponents/components/MyOrderList/index.js.map +1 -0
- package/lib/module/MarketComponents/components/OrderBook.js +193 -0
- package/lib/module/MarketComponents/components/OrderBook.js.map +1 -0
- package/lib/module/MarketComponents/components/OrderBookChart.js +267 -0
- package/lib/module/MarketComponents/components/OrderBookChart.js.map +1 -0
- package/lib/module/MarketComponents/components/OrderGradeBar.js +2 -1
- package/lib/module/MarketComponents/components/OrderGradeBar.js.map +1 -1
- package/lib/module/MarketComponents/index.js +11 -1
- package/lib/module/MarketComponents/index.js.map +1 -1
- package/lib/module/Socket/index.js +0 -1
- package/lib/module/Socket/index.js.map +1 -1
- package/lib/typescript/src/Components/Button.d.ts.map +1 -1
- package/lib/typescript/src/Components/ConfirmationModal.d.ts +13 -0
- package/lib/typescript/src/Components/ConfirmationModal.d.ts.map +1 -0
- package/lib/typescript/src/MarketComponents/api/index.d.ts +9 -2
- package/lib/typescript/src/MarketComponents/api/index.d.ts.map +1 -1
- package/lib/typescript/src/MarketComponents/components/BestAvailableOrderCard.d.ts +13 -0
- package/lib/typescript/src/MarketComponents/components/BestAvailableOrderCard.d.ts.map +1 -0
- package/lib/typescript/src/MarketComponents/components/ContestOrderStatsCard.d.ts +15 -0
- package/lib/typescript/src/MarketComponents/components/ContestOrderStatsCard.d.ts.map +1 -0
- package/lib/typescript/src/MarketComponents/components/MyOrderList/api/index.d.ts +18 -0
- package/lib/typescript/src/MarketComponents/components/MyOrderList/api/index.d.ts.map +1 -0
- package/lib/typescript/src/MarketComponents/components/MyOrderList/index.d.ts +10 -0
- package/lib/typescript/src/MarketComponents/components/MyOrderList/index.d.ts.map +1 -0
- package/lib/typescript/src/MarketComponents/components/OrderBook.d.ts +13 -0
- package/lib/typescript/src/MarketComponents/components/OrderBook.d.ts.map +1 -0
- package/lib/typescript/src/MarketComponents/components/OrderBookChart.d.ts +16 -0
- package/lib/typescript/src/MarketComponents/components/OrderBookChart.d.ts.map +1 -0
- package/lib/typescript/src/MarketComponents/components/OrderGradeBar.d.ts.map +1 -1
- package/lib/typescript/src/MarketComponents/index.d.ts +57 -0
- package/lib/typescript/src/MarketComponents/index.d.ts.map +1 -1
- package/lib/typescript/src/Socket/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Components/Button.tsx +2 -3
- package/src/Components/ConfirmationModal.tsx +57 -0
- package/src/MarketComponents/api/index.ts +80 -15
- package/src/MarketComponents/components/BestAvailableOrderCard.tsx +84 -0
- package/src/MarketComponents/components/ContestOrderStatsCard.tsx +154 -0
- package/src/MarketComponents/components/MyOrderList/api/index.ts +406 -0
- package/src/MarketComponents/components/MyOrderList/index.tsx +192 -0
- package/src/MarketComponents/components/OrderBook.tsx +99 -0
- package/src/MarketComponents/components/OrderBookChart.tsx +139 -0
- package/src/MarketComponents/components/OrderGradeBar.tsx +2 -1
- package/src/MarketComponents/index.tsx +11 -1
- package/src/Socket/index.tsx +0 -1
- 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
|