Appendix A
import pandas as pd
import numpy as np
import random
import matplotlib.pyplot as plt
# --- 1. Defining constants and functions ---
# Fee
SF = 0.05 # 5% Sellary fee
PF = 0.05 # 5% Purchase fee
# COA calculation
def calculate_coa(stake_1, k_total, k_rest):
return stake_1 * (k_total / k_rest) * (0.4 + 4 / (k_rest + 8))
# Optimal price
def calculate_price_opt(stake_1, k_total, k_rest, coa, sf, pf):
return ((stake_1 * k_total) / k_rest + coa)/(2 + pf - sf)
# --- 2.Profit definition for each exit for each player ---
# Exit 1
def profit_p1_e1(stake_1): return -stake_1
def profit_p2_e1(stake_1, k_total, k_rest): return -stake_1 * k_total / k_rest
# Exit 2
def profit_p1_e2(stake_1): return -stake_1
def profit_p2_e2(stake_1, k_total, k_rest): return ((stake_1 * k_total) / k_rest) * (k_rest - 1)
# Exit 3
def profit_p1_e3(stake_1): return -stake_1
def profit_p2_e3(stake_1, k_total, k_rest): return -stake_1 * k_total / k_rest
# Exit 4
def profit_p1_e4(stake_1, k_total): return stake_1 * (k_total - 1)
def profit_p2_e4(stake_1, k_total, k_rest): return stake_1 * k_total / k_rest * (k_rest - 1)
# Exit 5
def profit_p1_e5(stake_1, coa): return coa - stake_1
def profit_p2_e5(stake_1, k_total, k_rest): return -stake_1 * k_total / k_rest
# Exit 6
def profit_p1_e6(stake_1, coa): return coa - stake_1
def profit_p2_e6(stake_1, k_total, k_rest): return stake_1 * k_total * (1 - 1 / k_rest)
# Exit 7
def profit_p1_e7(stake_1, price_opt, sf): return price_opt * (1 - sf) - stake_1
def profit_p2_e7(price_opt, pf): return -price_opt * (1 + pf)
# Exit 8
def profit_p1_e8(stake_1, price_opt, sf, k_total): return price_opt * (1 - sf) - stake_1
def profit_p2_e8(stake_1, k_total, price_opt, pf): return stake_1 * k_total - price_opt * (1 + pf)
# --- 3. Parameters of the simulation ---
num_iterations = 1000 # Number of simulations for each loop
# P_C2_Yes scope & P_C3_Cl2 scope
p_c2_yes_range = np.arange(0, 0.61, 0.03) # Probability Player 1 to sell Option 1
p_c3_cl2_range = np.arange(0, 0.61, 0.03) # Probability Player 1 to sell Option 1 to Player 2
# --- 4. RNG Function ---
def probability_generator():
max_odds_count = 50
min_odds = 1.05
max_odds = 2.20
margin = 0.05
min_stake = 10
max_stake = 10000
max_K_total = 100
found = False
while not found:
# RNG: Stake
stake = np.exp(random.uniform(np.log(min_stake), np.log(max_stake)))
# RNG: Count of games (The total count & The rest count)
N = int(np.exp(random.uniform(np.log(2), np.log(max_odds_count))))
M = int(random.uniform(1, N - 1))
# RNG: A list of N odds
odds_list = np.exp(np.random.uniform(np.log(min_odds), np.log(max_odds), N))
# Calculating: K total
K_total1 = np.prod(odds_list)
# Calculating: K rest
K_rest1 = np.prod(odds_list[(N - M):])
if (K_total1 < max_K_total) & (stake * K_total1 / K_rest1 < max_stake):
found = True
# Calculating: Probability to win N games, The last (N-M+1) games, the first (N-M) games
P_M = 1 / (K_rest1 * (1 + margin)**(N - M + 1))
P_N_M = 1 / ((K_total1 / K_rest1) * (1 + margin)**(N - M))
return stake, K_total1, K_rest1, P_M, P_N_M
# --- 5. Main simulation -------------------------------------------------
results_no_innovation = [] # To preserve average profits without innovation
results_with_innovation = [] # To preserve average profits with innovation
for p_c2_yes_val in p_c2_yes_range:
for p_c3_cl2_val in p_c3_cl2_range:
# Totals for winnings for the current cycle
total_profit_p1_no_inn = 0
total_profit_p2_no_inn = 0
total_profit_p1_with_inn = 0
total_profit_p2_with_inn = 0
for _ in range(num_iterations):
stake1, K_total1, K_rest, P_M, P_N_M = probability_generator()
stake_1 = stake1
k_total = K_total1
k_rest = K_rest
p_c1_yes_game = P_N_M # Probability of Option 1 being liquid after Phase 1
p_c4_yes_game = P_M # Probability of Option 2 being liquid after Phase 3
# COA и Price_Opt calculations
coa = calculate_coa(stake_1, k_total, k_rest)
price_opt = calculate_price_opt(stake_1, k_total, k_rest, coa, SF, PF)
# Generation of probability for each condition
p1 = random.random()
p2 = random.random()
p3 = random.random()
p4 = random.random()
# Profit initialisation
current_profit_p1_no_inn = 0
current_profit_p2_no_inn = 0
current_profit_p3_no_inn = 0
# ========================================
# === Simulation WITHOUT the inovation ===
# ========================================
if p1 < p_c1_yes_game: # Condition 1
# C1_yes (Bet 1 is alive)
if p2 < p_c2_yes_val: # Condition 2
# C1_Yes -> C2_Yes (Player 1 make cash out, Player 2 place a bet 2)
if p4 < p_c4_yes_game: # Condition 5
# Exit 6 | C1_Yes -> C2_Yes -> C5_Yes (Bet 1 is cashed out, Bet 2 is won)
current_profit_p1_no_inn = profit_p1_e6(stake_1, coa)
current_profit_p2_no_inn = profit_p2_e6(stake_1, k_total, k_rest)
else: # Exit 5 | C1_Yes -> C2_Yes -> C5_No (Bet 1 is cashed out, Bet 2 is lost)
current_profit_p1_no_inn = profit_p1_e5(stake_1, coa)
current_profit_p2_no_inn = profit_p2_e5(stake_1, k_total, k_rest)
else: # C1_Yes -> C2_No (The Payer 1 doesn't sell)
if p4 < p_c4_yes_game: # Condition 5:
# Exit 4 | C1_Yes -> C2_No -> C4_Yes (Bet 1 is won, Bet 2 is Won)
current_profit_p1_no_inn = profit_p1_e4(stake_1, k_total)
current_profit_p2_no_inn = profit_p2_e4(stake_1, k_total, k_rest)
else: # Exit 3 | C1_Yes -> C2_No -> C4_No (Bet 1 is lost, Bet 2 is lost)
current_profit_p1_no_inn = profit_p1_e3(stake_1)
current_profit_p2_no_inn = profit_p2_e3(stake_1, k_total, k_rest)
else: # C1_No
if p4 < p_c4_yes_game: # Condition 5:
# Exit 2 | C1_No -> C5_Yes
current_profit_p1_no_inn = profit_p1_e2(stake_1)
current_profit_p2_no_inn = profit_p2_e2(stake_1, k_total, k_rest)
else: # Exit 1 | C1_No -> C5_No
current_profit_p1_no_inn = profit_p1_e1(stake_1)
current_profit_p2_no_inn = profit_p2_e1(stake_1, k_total, k_rest)
total_profit_p1_no_inn += current_profit_p1_no_inn
total_profit_p2_no_inn += current_profit_p2_no_inn
# ======================================
# === Simulation WITH the inovation ===
# ======================================
current_profit_p1_with_inn = 0
current_profit_p2_with_inn = 0
current_profit_p3_with_inn = 0
if p1 < p_c1_yes_game: # Condition 1:
# C1_Yes (Bet 1 is alive)
if p2 < p_c2_yes_val: # Condition 2
# C1_Yes -> C2_Yes (Player 1 wants to sell Bet 1)
if p3 < p_c3_cl2_val: # Condition 3
# C1_Yes -> C2_Yes -> C3_Client2 (Player 1 sells Bet 1 to Player 2)
if p4 < p_c4_yes_game: # Condition 5:
# Exit 8 | C1_Yes -> C2_Yes -> C3_Client2 -> C4_Yes (Bet 1 is won)
current_profit_p1_with_inn = profit_p1_e8(stake_1, price_opt, SF, k_total)
current_profit_p2_with_inn = profit_p2_e8(stake_1, k_total, price_opt, PF)
else: # Exit 7 | C1_Yes -> C2_Yes -> C3_Client2 -> C4_No (Bet 1 is lost)
current_profit_p1_with_inn = profit_p1_e7(stake_1, price_opt, SF)
current_profit_p2_with_inn = profit_p2_e7(price_opt, PF)
else: # C1_Yes -> C2_Yes -> C3_Bookmaker (Player 1 maked cash out, Player 2 place Bet 2)
if p4 < p_c4_yes_game: # Condition 5:
# Exit 6 | C1_Yes -> C2_Yes -> C3_Bookmaker -> C5_Yes (Bet 1 is cashed out, Bet 2 is Won)
current_profit_p1_with_inn = profit_p1_e6(stake_1, coa)
current_profit_p2_with_inn = profit_p2_e6(stake_1, k_total, k_rest)
else: # Exit 5 | C1_Yes -> C2_Yes -> C3_Bookmaker -> C5_No(Bet 1 is cashed out, Bet 2 is Lost)
current_profit_p1_with_inn = profit_p1_e5(stake_1, coa)
current_profit_p2_with_inn = profit_p2_e5(stake_1, k_total, k_rest)
else: # 1_Yes -> C2_No (Player 1 doesn't wants to sell Bet 1, Player 2 place a Bet 2)
if p4 < p_c4_yes_game: # Condition 5:
# Exit 4 | 1_Yes -> C2_No -> C4_Yes (Bet 1 is won, Bet 2 is won)
current_profit_p1_with_inn = profit_p1_e4(stake_1, k_total)
current_profit_p2_with_inn = profit_p2_e4(stake_1, k_total, k_rest)
else: # Exit 3 | 1_Yes -> C2_No -> C4_No (Bet 1 is lost, Bet 2 is lost)
current_profit_p1_with_inn = profit_p1_e3(stake_1)
current_profit_p2_with_inn = profit_p2_e3(stake_1, k_total, k_rest)
else: # C1_No (Bet 1 is lost)
if p4 < p_c4_yes_game: # Condition 5: Опция 2 ликвидна ли е на падежа?
# Exit 2 | {Bet 1 is lost, Bet 2 is won}
current_profit_p1_with_inn = profit_p1_e2(stake_1)
current_profit_p2_with_inn = profit_p2_e2(stake_1, k_total, k_rest)
else: # Exit 1 | {Bet 1 is lost, Bet 2 is lost}
current_profit_p1_with_inn = profit_p1_e1(stake_1)
current_profit_p2_with_inn = profit_p2_e1(stake_1, k_total, k_rest)
total_profit_p1_with_inn += current_profit_p1_with_inn
total_profit_p2_with_inn += current_profit_p2_with_inn
# Bookmaker's profit = - (Player 1 profit + Player 2 profit)
total_profit_p3_no_inn = -(total_profit_p1_no_inn + total_profit_p2_no_inn)
total_profit_p3_with_inn = -(total_profit_p1_with_inn + total_profit_p2_with_inn)
# Storing average profits for the current cycle
results_no_innovation.append({
'P_C2_Yes': p_c2_yes_val,
'P_C3_Cl2': p_c3_cl2_val,
'Avg_P1_Profit': total_profit_p1_no_inn / num_iterations,
'Avg_P2_Profit': total_profit_p2_no_inn / num_iterations,
'Avg_P3_Profit': total_profit_p3_no_inn / num_iterations
})
results_with_innovation.append({
'P_C2_Yes': p_c2_yes_val,
'P_C3_Cl2': p_c3_cl2_val,
'Avg_P1_Profit': total_profit_p1_with_inn / num_iterations,
'Avg_P2_Profit': total_profit_p2_with_inn / num_iterations,
'Avg_P3_Profit': total_profit_p3_with_inn / num_iterations
})
# Total results_no_innovation
sum_p1_no = sum(item['Avg_P1_Profit'] for item in results_no_innovation)
sum_p2_no = sum(item['Avg_P2_Profit'] for item in results_no_innovation)
sum_p3_no = sum(item['Avg_P3_Profit'] for item in results_no_innovation)
# Total results_with_innovation
sum_p1_with = sum(item['Avg_P1_Profit'] for item in results_with_innovation)
sum_p2_with = sum(item['Avg_P2_Profit'] for item in results_with_innovation)
sum_p3_with = sum(item['Avg_P3_Profit'] for item in results_with_innovation)
# Profit comparing
print(f"Player 1, Avg Profit, Without inovation = {round(sum_p1_no,0)}")
print(f"Player 1, Avg Profit, With inovation = {round(sum_p1_with,0)}")
print("Diferences: Avg Profit, With inovation - Avg Profit, Without inovation =",round(sum_p1_with - sum_p1_no,0))
print("Diferences / Avg Profit, Without inovation =",round(-(sum_p1_with - sum_p1_no) / sum_p1_no,4)*100, "%")
print("----------------------------------------------------------------")
print(f"Player 2, Avg Profit, Without inovation = {round(sum_p2_no,0)}")
print(f"Player 2, Avg Profit, With inovation = {round(sum_p2_with,0)}")
print("Diferences: Avg Profit, With inovation - Avg Profit, Without inovation =",round(sum_p2_with - sum_p2_no,0))
print("Diferences / Avg Profit, Without inovation =",round(-(sum_p2_with - sum_p2_no) / sum_p2_no,4)*100, "%")
print("----------------------------------------------------------------")
print(f"Bookmaker, Avg Profit, Without inovation = {round(sum_p3_no,0)}")
print(f"Bookmaker, Avg Profit, With inovation = {round(sum_p3_with,0)}")
print("Diferences: Avg Profit, With inovation - Avg Profit, Without inovation =",round(sum_p3_with - sum_p3_no,0))
print("Diferences / Avg Profit, Without inovation =",round(-(sum_p3_with - sum_p3_no) / sum_p3_no,4)*100, "%")
print("----------------------------------------------------------------")
#--- 6. Visualization of results ---
p1_profits_no_inn = [r['Avg_P1_Profit'] for r in results_no_innovation]
p1_profits_with_inn = [r['Avg_P1_Profit'] for r in results_with_innovation]
p2_profits_no_inn = [r['Avg_P2_Profit'] for r in results_no_innovation]
p2_profits_with_inn = [r['Avg_P2_Profit'] for r in results_with_innovation]
p3_profits_no_inn = [r['Avg_P3_Profit'] for r in results_no_innovation]
p3_profits_with_inn = [r['Avg_P3_Profit'] for r in results_with_innovation]
# Function about Plotting profits
def show_chart(player, no_inn, with_inn):
plt.figure(figsize=(12, 6))
plt.plot(
no_inn,
label=f'{player} Profit (No Innovation)',
color='black'
)
plt.plot(
with_inn,
label=f'{player} Profit (With Innovation)',
color=(251/255, 199/255, 83/255)
)
plt.title(f'Average {player} Profit')
plt.xlabel('Simulation Cycle (P_C2_Yes, P_C3_Cl2 combinations)')
plt.ylabel('Average Profit')
plt.grid(True, alpha=0.3)
plt.legend()
plt.tight_layout()
plt.show()
return
# visualisation
sh = show_chart ("Player 1", p1_profits_no_inn, p1_profits_with_inn)
sh = show_chart ("Player 2", p2_profits_no_inn, p2_profits_with_inn)
sh = show_chart ("BM", p3_profits_no_inn, p3_profits_with_inn)