ห่างหายกันไปนานเหมือนกันนะครับสำหรับบทความ
วันนี้เราจะมาเราจะมาเข้าบ่อนพนันกันบ้างแต่ว่าไม่ใช่บ่อนพนันจริงๆนะครับ มันคือบ่อนพนัน Simulation ของเราเองนะครับเพื่อการศึกษาเท่านั้น โดยเราจะใช้เทคนิค Monte Carlo Simulation ซึ่งเป็นหลักการทางคณิตศาสตร์ Stochastic process เพื่อมาช่วยเราประเมินโอกาสการชนะหรือโอกาสการแพ้จากการเดิมพันในบ่อนคาสิโนกัน โดยเรามาประเมินโอกาสชนะจากการทอยเต๋า, โอกาสถูกรางวัลที่ 1
ซึ่งเราจะเห็นความเชื่อมโยงระหว่างโลกการพนันกับโลกไฟแนนซ์ เราจะเห็น characteristics การสุ่มของมันที่โลกไฟแนนซ์มีมากกว่านี้เยอะ ทำให้เรารู้ว่าทำไม
“การ backtest ด้วย indicator เทพ ซักตัวแล้วได้ผลดีมากๆๆ อาจะเป็นแค่เรื่องไร้สาระจากมุมมอง Stochastic ก็ได้”
โดยมีวีดีโอการทำโปรเจ็คเล็กๆตัวนี้อยู่ในคอร์สฟรี Python programming ของเรา(กำลังอยู่ในขั้นตอนอัพเดตอยู่ครับ)
Stochastic process vs Deterministic process
Monte Carlo Simulation ก็เป็น stochastic process ตัวหนึง
คำว่า “stochastic” ถ้าเราไปดูใน google เราจะเห็นว่า stochastic แปลว่า “สุ่ม” ต่างกับด้านตรงข้ามของมันคือ “deterministic” ซึ่งแปลว่ากำหนดไว้แล้ว
ในด้านการลงทุนหรือด้านไฟแนนซ์โอกาสความเป็นไปได้มันไม่ได้ถูกกำหนดไว้แล้วอย่างเช่นเราทอยลูกเต๋าตอนนี้เราไม่มีทางรู้ได้เลยว่าตาต่อไปเราจะชนะหรือแพ้เราอาจจะประเมินโอกาสความน่าจะเป็นได้แต่เราไม่รู้จริงๆว่าต่อไปจะเกิดอะไรขึ้นฉะนั้นในการซิมูเลชั่นแต่ละครั้งจะเป็นการสร้างความเป็นไปได้ขึ้นมา 1 ความเป็นไปได้ครับ และมันก็ไม่ได้เชื่อถืออะไรได้เลย เรียกว่าไร้ค่าเลยก็ได้ แต่ถ้าเราทำหลายๆครั้ง มันก็จะกลายเป็น Monte Carlo Simulation ขึ้นมาและพอจะเอามาประเมินอนาคตได้
ใครลงเรียน คอร์ส python for Finance กับผมก็จะเคยเห็น การใช้ประเมินอนาคตด้วยการผสมกันของ สิ่งที่เรารู้ Historical characteristics และ สิ่งที่เราไม่รู้ Random Shock นะครับ อันนี้ก็หลักการคล้ายๆกัน
โอเค เรามาเริ่มกันดีกว่า
import matplotlib.pyplot as plt
import numpy as np
import random
plt.xkcd()
เริ่มต้นเราก็ต้องโหลด library ที่จำเป็นก่อน ประกอบไปด้วย matplotlib(พล๊อตรูป) numpy(ดำเนินการทางคณิตศาสตร์) แล้วก็ random(สุ่มตัวเลช) plt.xkcd() เป็นการกำหนดการสร้างรูปของ Python ให้เป็นการสเก็ตภาพซึ่งผมคิดว่ามันน่ารักดีเฉยๆ
MAKE A BET!!!
มาเริ่มต้นคาสิโนกันครับฟังก์ชั่นแรกที่เราจะเขียนคือฟังก์ชันในการเดิมพัน ซึ่งตัวผู้เขียนเองเก็ไม่ค่อยได้ไปเข้าคาสิโนนะครับ ฉะนั้นเราจึงจะมาเริ่มจากอะไรที่มัน Simple กันก่อนคือการทอยลูกเต๋า
โดยเฉพาะลูกเต๋าจะมีโอกาสความเป็นไปได้ในการออกนะครับ 1 ใน 6 (1/6) เพราะลูกเต๋ามี 6 หน้าเราก็จะเดิมพันกันง่ายๆ
- ให้ผู้เล่นเลือกลูกเต๋า 1 ตัวเลข
- จากนั้นให้เจ้ามือทำการทอยลูกเต๋าออกมานะครับ
- ถ้าทอยแล้วเบอร์ตรงกับที่ผู้เล่นได้เลือกไว้ผู้เล่นก็จะได้ไปรับรางวัล อาจจะเป็นลง 10 บาทได้ 20 บาท เป็นต้น
- ถ้าทายผิดก็เสียเงินที่วางเดิมพันไป
random.randint(1,6)
คำสั่ง random.randint(1,6) จะ return ค่าให้เราแบบสุ่มโดยมีโอกาสการออกของแต่ละเลขเท่ากันตั้งแต่เลข 1 จนถึงเลข 6 ถ้าเราลองรันหลายๆครั้ง ค่าที่ได้มาจากการ Random อาจจะไม่เหมือนกัน แต่ก็แน่นอนว่าอาจจะเหมือนกันในบางครั้ง เช่นเราโยนทอยเต๋า 2 ครั้ง ได้เลข 6 ทั้ง 2 ครั้ง หรือ 3,4 ครั้งมันก็เป็นไปได้(แต่น้อย)
ได้ดังนี้ผมจะมาสร้างฟังก์ชันชื่อว่า make a bet
def make_a_bet():
my_bet = random.randint(1,6)
winning = random.randint(1,6)
#print("my betting number:", my_bet)
#print("winning number:", winning)
if my_bet == winning:
return True
else:
return False
ผมก็กำหนดให้
- my_bet = random.randint(1,6) เพราะผู้เล่นสามารถเลือกเลขได้แค่เลือกเดียวเวลาเล่น 1 ครั้งคุณจะกำหนดตั้งเป็น static ไปเลยเช่น จะทายว่า 2 ทุกรอบก็ได้ แต่เพื่อประโยชน์ในการศึกษาผมก็จะให้เราเดาสุ่มทุกรอบดีกว่า
- winning = random.randint(1,6) คือเจ้ามือก็จะทำการทอยเต๋าซึ่งก็มีโอกาสออกได้ 1-6 เหมือนกันนะครับบรรทัดนี้ก็จะรีเทิร์นค่าเป็นตัวเลขเช่นเดียวกับบรรทัดด้านบน
- ปริ้นค่าดูสักหน่อยว่าเราเลือกเลขอะไรแล้วก็เจ้ามือทอยได้เลขอะไรในแต่ละครั้ง
- จากนั้นผมเช็ค if my_bet == winning: ถ้าอาร์กิวเมนต์นี้เป็นจริงแปลว่าผมเลือกเลขตรงกับที่เจ้ามือทอยเต๋าผมชนะฟังก์ชันก็จะรีเทิร์นค่า True ออกไป
- else: คือการบอกว่าเหนือจากนี้ก็แปลว่าเราทายผิด ฟังก์ชั่นจะ return ค่า False ออกไป
มาลองกันดูสักครั้งสองครั้งนะครับว่าเราจะทำลายถูกบ้างไหม


ก็เป็นอย่างที่ถ้าเราทายถูก ก็ Return True ผิด False ตามที่เราคาดหวัง
Simulation
ในส่วนนี้จะเป็นฟังก์ชันของการซิมมูเลชั่นแล้วนะครับ
def simulation(balance, bet, num_play, win_prize):
num_played = []
money = []
num_wins = 0
final_balance = []
for i in range(num_play):
if make_a_bet():
balance = balance + win_prize
num_played.append(i)
money.append(balance)
num_wins += 1
else:
balance = balance - bet
num_played.append(i)
money.append(balance)
plt.plot(num_played, money)
plt.ylabel("Balance")
plt.xlabel("Play round")
final_balance.append(money[-1])
return final_balance, num_wins
เราสร้างฟังก์ชันชื่อ def simulation(balance, bet, num_play, win_prize): จะมีการรับตัวแปรมา 4 ตัวประกอบไปด้วย
- balance : จำนวนเงินทั้งหมดของเรา
- bet: จำนวนเงินที่เราจะเดิมพันในแต่ละครั้ง
- num_play: จำนวนครั้งที่เราจะเล่นเดิมพันกัน
- win_prize: รางวัลถ้าเกิดเราชนะ
num_played = []
money = []
num_wins = 0
final_balance =
เราจะเก็บ statistics money เงินในแต่ละรอบ, num_win ไว้ด้วยกำหนดให้ค่าเริ่มต้นเท่ากับศูนย์ ตัวแปร final_balace จะเอาไว้เก็บเงินที่คงเหลือในแต่ละรอบที่เรา Simulation
for i in range(num_play):
ตรงนี้จะเป็นการวนลูปเท่ากับจำนวนรอบของ num_playซึ่งก็คือรอบที่เราจะเล่นในแต่ละครั้งของการ simulation
for i in range(num_play):
if make_a_bet():
balance = balance + win_prize
num_played.append(i)
money.append(balance)
num_wins += 1
ตรงนี้เรามาเช็คเงื่อนไข if make_a_bet():จะรีเทิร์นค่าเป็น True ก็ต่อเมื่อเราทำนายถูก ถ้าถูกแล้วเราก็ควรจะได้เงินฉะนั้นจึงตามมาที่บรรทัดนี้
balance = balance + win_prize เงินของเราจะถูกบวกเพิ่มด้วยรางวัลในการชนะแต่ละครั้ง
num_played.append(i), money.append(balance) เก็บสถิติว่ารอบไหน เราเหลือเงินเท่าไหร่
num_wins += 1 เก็บสถิติเราชนะไปแล้ว 1 ครั้ง
else:
balance = balance - bet
num_played.append(i)
money.append(balance)
Else ตรงนี้จะทำงานก็ต่อเมื่อฟังก์ชั่นด้านบนไม่รีเทิร์นค่า True ซึ่งก็แปลว่าเราทายผิดนั่นเอง
balance = balance – bet เราก็จะอัพเดทค่าเงินคงเหลือของเราลบด้วยเงินที่เราวางเดิมพันในครั้งนั้น จากนั้นก็เหมือนด้านบนคือเก็บจำนวนครั้งที่เล่นแล้วเก็บจำนวนเงินที่เหลือในรอบนั้น
plt.plot(num_played, money)
plt.ylabel("Balance")
plt.xlabel("Play round")
final_balance.append(money[-1])
เมื่อ simulation เสร็จก็มาวาดรูปเพื่อดูว่าสุดท้ายแล้วเนี่ยหลังจากเล่นไปแล้วจะเหลือเงินเท่าไหร่แล้วก็เราเล่นกี่รอบ
return final_balance, num_wins
ตรงท้ายสุดของฟังก์ชันเราจะ return 2 อย่างคือ final_balance, num_wins เหลือเงินเท่าไหร่ และ ชนะไปกี่ครั้ง
num_play = 100
bet = 100
balance = 5000
win_prize = bet*4
print("Balance:", balance)
simulation(balance=balance, bet=bet,
num_play=num_play, win_prize=win_prize)
เริ่มเขียนการซิมูเลชั่นกันครับ
- num_play = 100 ผมจะเริ่มที่เราเริ่มในการเล่นทอยเต๋า 100 ครั้ง
- bet = 100 เดิมพันครั้งละ 100 บาท
- balance = num_play * bet กำหนดให้มีเงินตั้งต้น 5000 บาท
- win_prize = bet*4 ถ้าเกิดชนะ 1 ครั้งจะได้เงินรางวัล 400 บาท
เรียกใช้ฟังก์ชั่นด้วย simulation(balance=balance, bet=bet, num_play=num_play, win_prize=win_prize) ผลที่ได้ก็คือความน่าจะเป็น 1 ความน่าจะเป็นของการเล่นทอยลูกเต๋า 100 ครั้งซึ่งความน่าจะเป็นที่จะเกิดขึ้นได้เนี่ยมีมหาศาลมากนี่เป็นแค่หนึ่งในนั้น

จะเห็นว่ารอบนี้เราจะแพ้ซะมาก เงินตั้งต้น 5000 บาท เหลือ แค่ 4000 บาท และนี้ก็เป็นโอกาสที่เกิดขึ้นได้ 1 ในไม่รู้เท่าไหร่ที่มันอาจจะเกิดได้ ถ้าเราเดิมพันทอยเต๋า ชนะได้เงิน 4 เท่า เป็นจำนวนร้อยครั้ง (อันนี้มันมีความน่าจะเป็นที่ Finite นะครับ)
แล้วมาลองคิดดูด้านการลงทุนของเราครับถ้าเป็นหุ้นความเป็นไปได้มันไม่ได้น้อยขนาดนี้แน่นอนทอยเต๋าออกได้แค่ 6 อย่างแต่หุ้นจะขึ้นเท่าไหร่เราไม่รู้เลยอาจจะมีขอบบนขอบล่างของการขึ้นในแต่ละวัน แต่ความน่าจะเป็นระหว่างนั้นมหาศาลมากฉะนั้นในสเกลที่เข้ากัน 100 วันของหุ้นกับ 100 วันของการทอยลูกเต๋า “ความน่าจะเป็น” ต่างกันเยอะมาก ทำเป็นเหตุให้เราบอกว่า
การ backtest ด้วย indicator เทพ ซักตัวแล้วได้ผลดีมากๆ อาจจะเป็นแค่เรื่องไร้สาระทางสถิติ
ฉะนั้นเราไม่สามารถยึดถืออะไรได้เลยจากการ simulation แค่ 1 ครั้งเพราะมันอาจจะฟลุ๊คก็ได้ทั้งหุ้นทั้งทอยลูกเต๋าหรือการเดิมพันอื่นๆอะไรก็ตามที่เป็น stochastic ไม่ใช่ deterministic เราอาจะบอกได้ว่า การ backtest ด้วย indicator เทพ ซักตัวแล้วได้ผลดีมากๆ เป็นแค่เรื่องไร้สาระทางสถิติได้เลย เพราะสุดท้ายแล้วคุณนำมาใช้จริง มันก็ไม่ได้เป็นอย่างที่คิด จริงๆมีคำอธิบายทางการ fit curve อยู่แต่ผมขอยกไปพูดในทความเรื่องของมันโดยเฉพาะนะครับ ตอนนี้เอาแค่ว่าการ ซิมมูเลชั่น 1, 2, 3 ครั้ง ไม่มีผลอะไร ไม่มีค่าหรือความหมายอะไรเลย
num_simulations = 1000
finals = []
wins = []
for i in range(num_simulations):
final, win = simulation(balance=balance, bet=bet,
num_play=num_play, win_prize=win_prize)
finals.append(final)
wins.append(win)
ทางแก้คือต้องประเมินมันหลายๆครั้ง บรรทัดนี้ผมจะเขียน for loop เพื่อเพิ่มจำนวนครั้งการ simulation ของการทอยลูกเต๋าของผม เป็น 1000(ก็ยังน้อย) ครั้งแล้วมาดูผลกันครับ

จากรูปจะเห็นว่าไม่มีโอกาสความเป็นไปได้เลยล่ะพี่เราจะได้กำไรจากการทอยเต๋า 100 ครั้ง กำไรก็ดูเหมือนจะเยอะด้วย ทุน 5000 เป็น เกือบ หมื่นบาทแหนะ แต่อย่างที่บอก ครั้งสองครั้งมันไม่มีค่าอะไร โดยส่วนใหญ่แล้วมันจะไปในทิศทางขาดทุนซะมากกว่านั่นก็เป็นเพราะ โอกาสในการแพ้ของการทอยเต๋ามากกว่าโอกาสที่จะชนะเยอะมากคือ
- แพ้ 5 ใน 6
- ชนะแ1 ใน 6
แล้วถ้าชนะได้เงิน 4 เท่าแม้จะดูล่อตาล่อใจแต่พอเราใช้สถิติ ในการประเมินแล้วเห็นว่ามันไม่คุ้ม ลองดูตัวเลขสักหน่อยนึง ว่าเราจะเหลือเงินเท่าไหร่บ้างเมื่อตอนจบการ simulation ในแต่ละรอบและก็เราจะชนะกี่ครั้งด้วยการดูตัวแปร finalsและ wins
finals

wins

แต่ดูด้วยตาไม่พอเราต้องเขียนการประเมินทางสถิติการสักนิด
ตรงนี้ผมก็จะทำง่ายๆคือปริ้นท์ค่าเฉลี่ยของเงินที่เหลือ แล้วก็เปอร์เซ็นต์เทรดกำไรขาดทุนจากนั้นตามด้วยค่าเฉลี่ยการชนะแล้วก็เป็นทีของการชนะ
print(f"Average balance: {np.mean(finals)}")
print(f"Average Profit (percentage) {((np.mean(finals)/balance)-1)*100} %")
print(f"Win average: {np.mean(wins)}" )
print(f"Win (percentage): {round(np.mean(wins)/num_play*100,2)}%" )

เราก็รู้แล้วว่ามันไม่คุ้มจับคุ้มที่ตรงไหนถ้าเกิดมีคนเสนอว่าเล่นเกมนี้กันเถอะแล้วคุณจะเอาให้คุ้มค่าพอที่จะเสี่ยงเล่นเดิมพันกับเขา ทางสถิติคุณอาจจะต้องเพิ่มรางวัล ถ้าเขาเสนอตัวเป็นเจ้ามือและข้อเสนอรางวัลให้เราเป็นผู้ชนะ 1 ครั้งจ่าย 6 เข้าเราควรจะลองไหมคำตอบอยู่ในนี้แล้วคุณก็แค่ ไปตั้งค่า win_prize ให้เป็น bet*6 ดูแล้วก็ simulation ซัก 1000, 10000 รอบดูว่าเรามีโอกาสที่จะชนะมากน้อยแค่ไหนจะเป็นสิ่งที่ช่วยเราในการตัดสินใจในการลงทุนได้
ลองซิมูเลชั่นรางวัลเป็น 6 เท่าของเงินเดิมพันดูครับ


ถ้าแบบนี้ ทางสถิติก็จะบอกว่า คุณควรรับเดิมพันถ้าคุณเป็นผู้เล่นครับแม้มันจะเป็นการพนันแต่ถ้าคุณพนันอยากมีหลักการมันคือการลงทุน!!!
สุดท้ายนี้ โปรแกรมนี้คุณสามารถเอาไป simulation อย่างอื่นก็ได้นะครับ เช่น ล๊อตเตอรี่ เป็นต้น คุณก็ต้องไปกำหนดรางวัลให้เขา ในกรณีที่มีหลายรางวัลก็ต้อง modify โค้ดให้มีการ return รางวัลอื่นๆด้วยครับ เชื่อว่าไม่ได้ยากหรอกครับลองเล่นดูได้

อันนี้ไม่สมจริงนะครับ เพราะความล๊อตเตอรี่มีหลายรางวัล แต่ถ้าสมมุติมีแค่รางวัลที่ 1 รูปด้านบนไม่ได้มี 1 ครั้งที่ผมซิมูเลชั่น ผมทำไป 1000 ครั้ง สมมุติว่าเรา 1000 คน ซื้อกัน 100 งวด ผลที่ได้คือเหมือนกัน เกลี้ยงกระเป๋า(ฮา)

ผมซิมมูเลชั่นเล่นๆ ให้คนแสนคน ซื้อล๊อตเตอรี่ 2 ปี 48 งวดติด ก็มีถูกกันประมาณ 4 คนครับ โอกาสยากเย็นแสนเข็ญขนาดนี้ทำไมเราถึงคิดว่ามันจะเป็นเราไปทุกงวดได้น้า (ฮา)
การพนันแต่ถ้าคุณพนันอยากมีหลักการมันคือการลงทุน! ถ้าไม่มันก็คือการพนันเหมือนเดิม!!
ปล. โค้ดตัวนี้มีวีดีโอสอน ในคอร์ส Free Python programming ของเรานะครับ เข้าไปลองดูได้ ไม่มีค่าใช้จ่ายครับ