วิธีคำนวณ ROA ในเว็บ SET

14. August 2010

เพิ่งอ่านหนังสือเล่มแรกจบใน Kindle ไปได้ไม่นาน (The Little Book that beats the market) หนังสือมันสอนวิธีกรองหุ้นง่ายๆโดยใช้ reuturn on capital + earning yield แต่วิธีที่หนังสือมันใช้คำนวณสองค่านี่มันต้องใช้ค่าดิบๆบางอย่างจากงบการเงิน ซึ่งหามายากพอควร ( .. แปลว่า automate ไม่ได้ ..) ผมเลยลองมาดูๆค่าที่ใช้แทนได้ใกล้เคียงที่สุดแทนและมีบนเว็บ SET คือ ROA (return on assets - ผลกำไรต่อสินทรัพย์) และ ROE (return on equity - ผลกำไรต่อส่วนผู้ถือหุ้น)

 

ค่าสองตัวนี้ควรจะหาได้ง่ายๆ Wikipedia กล่าวว่า

ROA_FORM

แต่ทำไปทำมาปรากฎว่าคำนวณแล้วไม่เห็นจะตรงกับที่เขียนไว้ในเว็บเลยว่ะ ….’’ นั่งงงอยู่นาน

FS

จากรูป ถ้าจะหา ROA ปี 2009 (ปี 2010 ยังได้ข้อมูลไม่ครบ เด๋วจะงง) จะได้ 10190.22 / 115698.28 = 8.8076 %  … ไม่เห็นจะตรงกับ 13.33 % เลยอ้ะ

ถามอากู๋คนเดิมได้ความจากกระทู้ในพันทิบว่า SET มันใช้วิธีคำนวณคนละวิธี ใช้เป็น ROAA (return on average assets) แทน

ROAA = EBIT of nth year  / (0.5 * (NET assets n-1th year + NET assets nth year))

ตัวย่อแปลกๆในข้อความนี้อีกตัวคือ EBIT (Earnings before interest and taxes) ซึ่งเป็นกำไรแบบที่ยังไม่ได้คิดดอกเบี้ยเงินกู้กับภาษี ถ้าดูจากตารางข้างบนจะเห็น กำไร/ขาดทุน = 10,190.22 ล้านบาท แต่ถ้าไปเปิดงบกำไรขาดทุนละเอียดดูแล้วจะได้ EBIT = 14,878.46 ล้านบาท

INCOME

สุดท้ายเอาไปคำนวณ 14878.46 / ((115698.28 + 107510.00) / 2) ~ 13.3 % ตรงแล้ว

วันนี้แมงเม่าหนุ่มจึงอ่านงบการเงินเป็นมากขึ้นพอสมควรหลังจาก trade มานานเกือบปีแล้ว จดไว้นิดนึงเผื่อมีคนงงเหมือนกัน

หลักๆ หนังสือเล่มที่อ่านมันสอนให้ดูค่าพวกนี้เพื่อบอกว่าหุ้นตัวไหนน่าซื้อแบบ relative เค้าบอกว่าการทำนายอนาคตหรือราคาที่เหมาะสมนี่มันไม่ใช่เรื่องที่ใครๆก็จะทำได้ง่ายๆ แล้วหุ้นที่ undervalued แบบที่ Ben Graham เจ้าพ่อ VI ชอบซื้อปัจจุบันมันก็ไม่ได้เจอได้ง่ายขนาดนั้นอีกแล้ว ดังนั้นเรามาดูข้อมูลปีล่าสุดกันดีกว่า … ใครสนใจลองหาไปอ่านกันดู

General , , , ,

หนังไม่สมจริง

4. August 2010

ตอนเด็กๆ (ก็ไม่น่าจะเด็กมากประมาณ ม.3 ล่ะมั้ง) เวลาป๊าม๊าที่เป็นหมอนั่งดูละครชุดเรื่อง E.R. กันก็จะนั่งดูเหมือนจะบันเทิงแต่ก็จะจับผิดตลอดเวลาอย่างโน้นอย่างนี้ ไม่สมจริง ทำแบบนี้ไม่ได้ …. ตัวเองตอนนี้มาพอนั่งดูนั่งที่เกี่ยวกับคอมพิวเตอร์หลายๆเรื่องก็ไม่เห็นจะมีเรื่องไหนมันทำสมจริงๆมากๆเลยว่ะ (มีนะแต่น้อย) ส่วนใหญ่ GUI ของคอมพิวเตอร์ในหนังมันก็จะเว่อร์ๆอยู่แล้วเพื่อให้คนดูสนุก วันก่อนก็ได้คุยกับพี่ที่ทำงานอีกคนเค้าก็ติๆ Angel & Demon หน่อยว่าทำอะไรไม่อิงข้อมูลวิทยาศาสตร์ แล้วก็ชมเรื่อง Iron Man ให้ฟังว่าเรื่องนี้ทำอะไรปรึกษานักวิทยาศาสตร์ตลอด ไม่ได้ให้ข้อมูลผิดๆเหมือน Angel & Demon

พักหลังๆผมชอบไปอ่าน review หนัง หลายครั้งบทวิจารณ์หนังพวกนี้มันบอกว่าหนังเรื่องนึงไม่ดีด้วยเหตุผล “ไม่สมจริง” ยกตัวอย่างเช่นเรื่อง The Hurt Locker คนวิจารณ์เคยทำงานเกี่ยวกับทหารมาก่อน เค้าบอกว่าเค้าดูแล้วรู้สึกสะดุดมากตอนที่ตัวเอกตัดสินใจจัดกลุ่ม 3 คนไปกู้ระเบิด เค้าบอกว่าสถานการณ์จริงไม่มีทางมีเรื่องแบบนี้เกิดขึ้นเป็นอันขาด ทำให้เค้าเสียอารมณ์ = =’

มานั่งคิดๆดู สมมติว่าคนเขียนบทเค้าสามารถทำให้คนดู 95% ทั่วโลกบันเทิงไปกับหนังโดยไม่สะดุดเลยได้จนจบเรื่อง และไม่ต้องสนใจคน “วงใน” อีก 5% เลย ว่าจะคิดยังไง มันก็ดูคุ้มค่าที่จะทำนะ ไม่รู้จะเอาเงินไปจ้างที่ปรึกษาด้านวิทยาศาสตร์ การแพทย์ คณิตศาสตร์ โบราณคดี blah blah ไปทำให้คนอีก 5% พอใจไปทำไม

ผมมาจบที่ข้อสรุปว่า “ความไม่สมจริง” ไม่ใช่เหตุผลที่ทำให้หนังมันไม่ดีที่สามารถใช้เอามาบอกคนอื่นได้ (ยกเว้นชัวร์ว่าเป็น 5% ด้วยกัน) … หรือว่ายังไง ?

ถ้าจะให้ผมพูดในฐานะที่เป็นคนใน “5%” ของบางเรื่อง อย่างถ้าใครเคยดูเรื่อง Antitrust ไม่รู้จะมีคนสงสัยเหมือนผมรึเปล่าว่า บริษัทยักษ์ใหญ่จะแย่งตัวหนุ่มน้อยอัจฉริยะผู้เขียนโปรแกรมภาษา “Java” ได้ (ซึ่งมีคนเขียนเป็นอยู่ล้นตลาด) ไปทำงานทำไม =_=” อย่าลืมกดดูให้ถึงหน้าจอที่แสดงโค้ด Java สำหรับทำ Satellite Uplink .. หนังเรื่องนี้พยายาม feature ผลิตภัณฑ์ของ Sun ทั้งเรื่องเลย  …. ไม่อยาก spoil เพิ่มแต่ลองไปดูแล้วกันว่าคนพวกนี้พยายามกันขนาดไหนเพื่อจะ “ขโมย” โค้ด “Java” ของคนอื่น

แต่ก็ต้องยกให้ว่าเรื่องนี้ในด้าน GUI มันค่อนข้างจะสมจริงมาก จะมองมุมไหนคอมพิวเตอร์ก็น่าเกลียดเหมือนจริง +__+’

ถ้าหนังเรื่องไหนสามารถกำจัดความไม่สมจริงที่ถูกสั่งสมขึ้นมาโดยเรื่องอื่นๆได้นี่ ก็จะได้เป็น Hero ไปเลย :’) ยกตัวอย่าง Trinity ใช้ nmap ใน The Matrix (เคยลองๆใช้โปรแกรมนี้ตอนไปแข่ง Network Security Contest ด้วยนะ!) อันนี้ได้ใจคน 5% ไปชัวร์ๆ

หรือคุณว่ายังไง ??

Java, General , , ,

จับโจรขโมยรูป

27. June 2010

เมื่อเร็วๆนี้เห็นคนแอด facebook มา … รูป profile ดึงดูดเกินมาตรฐานเพื่อนไปมาก >_< … แต่ไม่รู้ว่าเป็นใคร …..’’

FacebookTheft

ปกติเวลามีคนไม่รู้จักแอดมา ถ้าไม่ได้ใช้รูป profile เป็นรูปคนผมจะดองไว้พักใหญ่ๆ (เผื่อตอนหลังเปลี่ยนรูปแล้วจำหน้าได้) แต่ถ้าเป็นหน้าคนแล้วไม่รู้จัก รอซักพักนึงไม่นานผมก็จะ Ignore ไป ครั้งนี้ก็เช่นเดียวกัน ผมดองไว้พักใหญ่ๆ จากเดิมที่ mutual friends ไม่มีเลย จนเริ่มเพิ่มจาก 3 …. 5 …. 8 …. 11 (จากการสังเกตพบว่าเกือบทั้งหมดเป็นผู้ชาย)

Mutual

Mutual friends ส่วนใหญ่เป็นคนที่จบ ม.ปลาย โรงเรียนเดียวกัน …. หรือว่าคนนี้มันจะคนดังโรงเรียนเราวะ …. อ่ะๆ ไหนๆก็ไหนๆ ขอเข้าไปเก็บข้อมูลเพิ่มหน่อยแล้วกัน ว่ะฮะๆๆ .. accept

ปรากฎว่า

  1. เข้าวอลล์อันดับแรก …. มันเป็นใครวะ ?!? ข้างในวอลล์ไม่มีอะไรเลย เขียนเพิ่มไม่ได้ แล้วก็มีเขียนบอกไว้ว่า ถ้าอยากติดต่อให้ message ไปหา ….. เฮ้ย!
  2. แน่นอน ดูรูป! มีอัลบั้มรูปเพิ่มอีกอันนึงเป็นรูปเหมือนถ่ายที่งานอะไรซักอย่าง แล้วเหมือนกำลังซ้อมอะไรอยู่ คนข้างหลังรูปมีอยู่คนนึง หน้าไม่ค่อยเหมือนคนไทย –_-‘ เริ่มเอะใจ แถมยังคอมเม็นต์รูปไม่ได้อีก ปกติถ้ารูปดีขนาดนี้จะมีพวกเข้ามาเม้นต์ว่า “น่ารักจังครับ ผม%sนะ อยากรู้จัก”

เริ่มสงสัยว่าตกลงนี่มันรูปอะไรกันแน่ การเสิร์ชหารูปดาราจากชื่อนั้นเป็นเรื่องปกติที่ใครๆก็ทำกันอยู่แล้ว แต่ไอ่การมีรูปดาราแล้วจะสาวกลับไปหารูปนี่ … วิธีปกติคือต้องถามคนที่รู้เยอะๆ หรือไม่ก็ถามตามเว็บบอร์ด แถมดาราสาวเกาหลีสมัยนี้หน้าตาเหมือนกันอย่างกะปั๊มออกมาจากโรงงาน HTC … จะหาเจอได้ไงหว่า

ยังโชคดีที่โลกเรามีสิ่งที่เรียกว่า Reverse Image Search!

Reverse

การใช้งานง่ายมาก แค่อัพโหลดรูปที่จะหาขึ้นไป ระบบจะหาให้ว่ามีรูปคล้ายๆกันอยู่ที่ไหนบ้าง จากการทดลอง ถ้ามี text มาโปะหน้ารูปนิดหน่อย / รูปโดน crop / รูปเอียง / เบี้ยว / distort นิดหน่อย มันก็หาเจอนะ!

ผลลัพธ์ …. tadaaaaa~!

Result

ปรากฎว่ารูปนี้เป็นของดาราจากประเทศขวัญใจเยาวชนไทยคนนึง ชื่อ Sandara Park (박산다라) ครับ

(หมั่นไส้ล่ะสิ เวลาเห็นคนเขียนชื่อแล้ววงเล็บชื่อเกาหลี - -‘ ก็เห็นเด็กๆเค้าชอบทำกันอยากทำบ้าง ไม่งั้นจะมี Unicode ไปทำไม)

dd2

สรุปสั้นๆของนิทานเรื่องนี้

  • Bandwagon effect มันมีผลมากกับการ add friend
  • มองโลกในแง่ร้าย คนที่กระทำการในลักษณะนี้จะสื่อสารกับเหยื่อที่หลงเข้ามาแบบ private เท่านั้น ไอ่การสื่อสารผ่านวอลล์ คอมเม็นต์ จะโดนปิดหมด ไม่ให้เหยื่อได้ข้อมูลเพิ่มจากเหยื่อคนอื่น พอการสื่อสารเป็นแบบ private แล้ว การล่อลวงก็จะทำได้ง่ายขึ้น
  • มองโลกในแง่ดี อาจจะมีเพื่อนโรงเรียนเก่าล่ะมั้ง ที่แค่ชอบดาราคนนี้ล่ะมั้ง เลยต้องเอารูปทั้ง profile ทั้งอัลบั้มอื่นเป็นคนนี้หมดเลยล่ะมั้ง ขี้อายก็เลยไม่อยากให้คนเขียนวอลล์แล้วให้เมสเสจไปคุยล่ะมั้ง ….
  • ผมจะไปลบ friend ที่เพิ่งแอดทิ้ง
  • ผมเข้าไปเสพย์รูป Sandara Park (박산다라) ต่อได้ถ้าต้องการ :P

General , , ,

รีวิว The Art of the Start

17. June 2010

TheArtOfTheStart

เพิ่งอ่านจบครับ ได้ยินชื่อหนังสือเล่มนี้ครั้งแรกนานมาแล้ว แต่ได้ยินจากที่ไหนจำไม่ได้แฮะ น่าจะเป็นหนังสือแนะนำของพวก developer เจ้าของบลอกดังๆซักคน จนเมื่อเร็วๆนี้เองไปเจอ video บรรยายโดย Guy Kawasaki หรือคนเขียนหนังสือเล่มนี้นั่นแหละ ดูแล้วชอบมากๆๆๆ ก็เลยตัดสินใจไปถอยมาทันทีจากคิโนะฯพารากอน

เนื้อหาประมาณ 200 หน้า ถือว่าไม่ยาว อ่านเพลินมากๆ ตอนอ่านก็คิดตามไปโดยเทียบกับประสบการณ์ที่เคยเจอมาในชีวิตด้วย แต่ยอมรับว่ามันก็มีบางเรื่องที่อ่านไม่ค่อยเข้าใจเท่าไหร่ อาจจะเป็นเพราะยังไม่มีประสบการณ์พอ - -‘a

หนังสือเล่มนี้ให้ข้อคิด และตบหน้าความเชื่อของผมหลายๆอย่างครับ ยกตัวอย่างให้ฟังเป็นบางเรื่อง ถ้าอ่านจากหนังสือจะพบว่ามันเป็น structure มากกว่านี้มาก

  • เรื่อง 10/20/30 – ทำ slides 10 หน้าเท่านั้น และบรรยาย 20 นาที และใช้ฟอนต์ 30 pts (หรือขนาดเท่ากับอายุมากสุดของคนที่มาฟังหารสอง)
  • สร้าง mantra ไม่ใช่ mission statement
  • ทำสิ่งที่มีความหมาย ไม่ใช่ทำเพราะอยากได้เงิน แต่การทำสิ่งที่มีความหมายก็ต้องการเงิน ต้องการ business model ที่ทำให้อยู่ได้ ไม่งั้นก็อดตาย
  • กว่าจะทำ market research จนพิสูจน์ได้ว่าตลาดมันมีอยู่จริง คู่แข่งมันก็เต็มไปหมดแล้ว จะรอ proven market ก็รอกินฝุ่นได้เลย (อันนี้มีแอบกัด Gartner)
  • งานสำคัญอย่าง branding หรือเขียน business plan สำคัญเกินกว่าจะจ้าง consultant ข้างนอกทำ หรือจะจ้างก็เอาไว้ตรวจสอบก็พอ
  • หลายคนอยากทำ product หรือ service ของตัวเองแต่ทำไม่ได้เพราะเรื่องเงิน ต้องรับงานพวก consulting คือการทำตาม requirement ลูกค้าไปก่อนโดยพยายามเอา product ที่ทำไปเป็นส่วนประกอบ พอเงินพอ + ลูกค้าเยอะพอ ลุกค้าก็จะวิ่งเข้ามาหา product/service ของเราแทน (ไม่ต้องเข้าหาลูกค้าเหมือน consulting)
  • จ้างคนที่เสพย์ติด และเชื่อในความหมายที่เราจะสร้างไปด้วยกัน
  • เลือกเพื่อนร่วมงานที่หลากหลาย หาคนเห็นต่าง หาคนมีเน็ตเวิร์คเยอะ หาคนชอบ implement หาคนไอเดียบรรเจิด หา …. (มีลิสต์ในหนังสือ)
  • เทคนิคการพูด + การนำเสนอ … อันนี้รู้สึกเป็นประโยชน์กับตัวเองมากเพราะยังพูดไม่ค่อยเก่ง
  • การหาลูกค้าที่ชื่นชอบ product/service ของเราเพื่อขอความช่วยเหลือให้เป็นแนวร่วมในการเจาะตลาดเพิ่ม – สร้าง evangelist -- evangelist ไม่ต้องการผลตอบแทนในรูปแบบเงิน แต่ถ้าได้เสื้อหรือแก้วน้ำ หรืออะไรที่ทำให้รู้สึกว่าเป็นลูกค้าคนพิเศษจะดีใจมาก
  • สร้าง exit ที่ง่ายให้กับลูกค้า -- การสมัครสมาชิกที่ยกเลิกสมาชิกได้ง่ายๆ จะทำให้ลูกค้ารู้สึกดีกว่า
  • ไม่มีบริษัทที่สร้างมาให้ยิ่งใหญ่เหมือน Microsoft, Apple, Google (ตอนนี้) ตั้งแต่แรก ให้เริ่มจากตลาดที่ยักษ์ใหญ่จะเจาะไม่ถึง แต่ไม่คิดจะเจาะก่อน แล้วค่อยๆขยายไป .. แม้แต่ MS, Apple, Google ก็ทำแบบนี้เช่นกัน
  • การล้มเหลวไม่ใช่เรื่องใหญ่ ตราบใดก็ตามที่ยังลองใหม่ได้
  • …. อีกมากมายนับไม่ถ้วน

ส่วนตัวแล้วคิดว่า จุดที่สำคัญอยู่ที่พออ่านสถาณการณ์แล้วต้องเอามาคิดเปรียบเทียบกับเรื่องที่เราเจอในชีวิตให้เยอะๆ แล้วจะรู้สึกว่าได้อะไรมาก เล่มนี้ขึ้นหิ้งแนะนำอย่างไม่น่าสงสัยครับ :)

General

Correlation ในราคาหุ้น

13. June 2010

ช่วงนี้สนใจเรื่องแนวๆ quantitative มากเป็นพิเศษ อ่านไปเรื่อยๆก็สนุกดี แต่บางทีก็อดรู้สึกไม่ได้ว่านี่เอาเวลามาทำอะไรอยู่ฟะเนี่ย -*- ยิ่งทำๆไปแล้วยังไม่เห็นผลลัพธ์ที่จับต้องได้นี่ มันจะเริ่มหงุดหงิดๆ 555+

Correlation นี่มันเป็นความสัมพันธ์เชิงสถิติระหว่างข้อมูล (ในที่นี่ก็หมายถึงพวกราคานั่นแหละ) ซึ่งบางทีการที่ข้อมูลสองชุดมัน correlate กัน ก็ อาจจะ แปลว่ามีความสัมพันธ์อะไรบางอย่างอยู่เบื้องหลังก็ได้

สำหรับพวกข้อมูลที่เป็นตัวเลข (เช่นราคาหุ้น) การที่มัน correlate กันนั้นก็หมายถึงราคามันจะเปลี่ยนแปลงไปพร้อมๆกัน เช่น ตัวนึงขึ้นมาก อีกตัวก็ต้องขึ้นมากด้วย ตัวนึงนิ่ง อีกตัวนิ่ง หรือจะเป็นแบบตัวนึงขึ้นมากอีกตัวนึงลงมากก็ได้

ใน Excel มีฟังก์ชันสะดวกๆให้ใช้ชื่อ CORREL ส่วนใน Python เข้าใจว่าใน SciPy ก็มีเหมือนกัน แต่บางครั้งคนเราควร Reinvent the Wheel บ้าง เพื่อความบันเทิง :P

Pearson

วิธีการตีความผลลัพธ์คือ

  • ถ้าได้ค่าใกล้ 1 มาก แปลว่ามันขึ้นลงพร้อมๆกันมากๆ (correlate)
  • ถ้าได้ค่าใกล้ 0 แปลว่ามันแทบจะไม่ correlate กันเลย
  • ถ้าได้ค่าใกล้ 1 มาก แปลว่ามันจะขึ้นลงกลับกันมากๆ (correlate)
def corr(series1, series2):
"""Calculate Pearson's product-moment coefficient

More info: http://en.wikipedia.org/wiki/Correlation_and_dependence#Pearson.27s_product-moment_coefficient

"
""
if len(series1) != len(series2):
raise Exception((series1, series2), 'Lengths of series are not equal')

n = len(series1)
sum_x = sum(series1)
sum_y = sum(series2)
sum_sqx = sum(a*a for a in series1)
sum_sqy = sum(a*a for a in series2)
sum_xy = sum(map(lambda s: s[0] * s[1], zip(series1, series2)))

import math
res = (n*sum_xy - sum_x*sum_y)/(math.sqrt(n*sum_sqx - sum_x*sum_x)*math.sqrt(n*sum_sqy - sum_y*sum_y))

return res

ตัวอย่างที่ค่อนข้าง obvious:

  • [1,2,3] กับ [3,4,5] ได้ 1.0
  • [1,2,3] กับ [-3,-4,-5] ได้ -1.0

ลองเอามาทดสอบกับราคาหุ้นดู ช่วงนี้ผมมีฐานข้อมูลราคาเป็นของตัวเองแล้ว (จากการไป pull ข้อมูลมาจากเว็บสาธารณะ) เก็บใส่ mongdb ไว้ ใช้คู่กับ Python สะดวกโยธินมาก (เอาเวลาตอนไหนไปทำวะเนี่ย)

ทดสอบกับ data 500 วันล่าสุด

  • CPF กับ CPALL = 0.96  -- ขึ้นลงตามกันโคดๆๆ .. แน่ล่ะ
  • CPF กับ TUF = 0.94 -- อาหารเหมือนกันมั้ง
  • BBL กับ KBANK = 0.94 -- กลุ่มธนาคารเหมือนกัน
  • PS กับ QH = 0.89 -- อันนี้อยู่ใน sector อสังหาเหมือนกัน
  • DTAC กับ ADVANC = 0.74 -- ไม่เยอะอย่างที่คิด
  • CPN กับ CPF = 0.37 -- ห้างเซ็นทรัล กับ อาหาร
  • CPF กับ CAWOW = –0.68 – ไก่ ลง ฟิตเนส ขึ้น ??
  • TRC กับ PS = -0.11 -- ไม่ค่อยเกี่ยวกันเท่าไหร่ …
  • ..

พวก quant ตัวเทพเค้าบอกว่า จริงๆ correlation ไม่ค่อยมีประโยชน์กับการ trade เท่าไหร่ ที่มีประโยชน์คือ cointegration เป็นคุณสมบติอีกแบบที่บอกว่า series สองอันมันจะแตกต่างกันได้บ้างเป็นบางเวลา แต่สุดท้ายแล้วต้องกับมาขึ้นลงคู่กันอีกรอบ คุณสมบัตินี้ทำให้เอาไปใช้ทำ pair trading ได้

สรุปว่าถ้าลองทำกับทุกคู่ในตลาด (ประมาณ 500 ตัว) น่าจะพอเห็นอะไรบ้าง … ไว้เวลาเอื้ออำนวยอีกรอบละกัน :)

ช่วงนี้ความสนใจเยอะจัด สับสนมาก เลือกทำไม่ถูก - -‘ อย่างนึงที่ทำก็คือไล่อ่านบลอกของไอดอลคนใหม่อยู่ (Max Dama) ใครสนใจเรื่องพวก automated trading ต้องลองเข้าไปดู มีอะไรให้เก็บเกี่ยวเยอะแน่นอน

General , ,

กูเกิ้ลโค้ดแยม : รอบคัดเลือก 2010

9. May 2010

ครั้งนี้ตัดคำว่าเฉลยออกแล้ว ลดความมั่นใจลงหน่อยนึง - -‘a 

แต่ตั้งแต่ทำมา 3 ปี ปีนี้เป็นปีแรกที่ได้คะแนนเต็มรอบแรก T_T ดีใจ

ข้อแรก Snapper Chain

ถ้าเปลี่ยน ON เป็นเลข 1 แล้ว OFF เป็นเลขศูนย์ แล้วให้ปลั๊กไฟหลัก (Power) อยู่ซ้ายสุด

ถ้ามี Snapper สองอัน มันจะวิ่งตามลำดับนี้

00
10
01
11 <--- Light on!
00
10 …

ถ้าเป็น 3 อัน ก็พอจะเดาได้ว่ามันก็เป็นแบบนี้

000
100
010
110
001
101
011
111 <--- Light on!

สรุปว่ามันก็เหมือนกับนับเลขฐานสองกลับหลัง ดังนั้นถ้ามี snapper n อัน กรณีที่จะทำให้หลอดไฟติดได้ก็คงต้องเป็นการ snap เป็นจำนวน (c * 2^n) – 1 เท่านั้น (โดย c เป็นจำนวนเต็ม … บวก)

if __name__ == '__main__':
fin = 'A-large.in'
fon = 'A-large.out'

fi = open(fin, 'r')
fo = open(fon, 'w')

c = int(fi.readline())
for i in xrange(c):
n, k = [int(x) for x in fi.readline().split(' ')]
ans = (k % 2 ** n) == 2 ** n - 1
fo.write("Case #%d: %s\n" % (i + 1, 'ON' if ans else 'OFF'))

print "Done!"
fi.close()
fo.close()

ข้อสอง Fair Warning

ข้อนี้เข้าใจว่าเป็นเรื่องแนวๆ number theory

มีคนอ่านโจทย์แล้วงงเยอะมาก โจทย์มันถามว่า ต้องใช้เวลานานอย่างน้อยเท่าไหร่ ถึงจะทำให้ ตัวหารร่วมมากสุด (ห.ร.ม. – Greatest Common Divisor (GCD)) มีค่ามากที่สุด

ในโจทย์ตัวอย่างเป็น 26000 11000 6000 ดังนั้นถ้าเวลาผ่านไป 4000 sec (ซึ่งเป็นคำตอบที่ถูกต้อง) จะทำให้กลายเป็น 30000 15000 10000 และทำให้เลขชุดนี้มี GCD เป็น 5000 ซึ่งไม่ว่าจะเป็นเวลาก่อน 4000 sec หรือหลัง 4000 sec ไปอีกนานเท่าไหร่ก็ตาม GCD ที่หาได้ก็จะมีค่าไม่เกิน 5000 แน่นอน เช่นถ้าผ่านไปแค่ 2000 sec จะได้เลขชุดนี้เป็น 28000 13000 8000 ซึ่งมี GCD = 1000 (น้อยกว่า 5000)

ขอแทนเวลาที่ผ่านไปเรื่อยๆ ด้วยแถบยืดๆ x (ซึ่งยืดได้เท่าไหร่ก็ไม่รู้ แต่ต้องยืดเท่าๆกันสำหรับแต่ละ event)

<===== x ===...==><==  6000 ==>
<===== x ===...==><== 11000 ======>
<===== x ===...==><== 26000 ================>

หรือถ้าเรา define ให้ y = x + 6000 จะกลายเป็นรูปนี้ (เลือก 6000 เพราะเป็น MIN)

<===== y ===...=======>
<===== y ===...=======><== 5000 ======>
<===== y ===...=======><== 20000 ===========>

ทีนี้เราก็จะหา GCD ของ y, y+ 5000, และ y + 20000 .. ยกคุณสมบัติ GCD ที่จะใช้มาทวนก่อน

  • gcd(a, b) = gcd(b, a) …. สลับที่
  • gcd(a, gcd(b, c)) = gcd(gcd(a, b), c) …. เปลี่ยนกลุ่ม
  • gcd(a, b) = gcd(b, a - b) … กรณี a > b

จากรูปด้านบน ถ้าเราหา GCD ระหว่าง y กับบรรทัดอื่นๆ ทีละคู่ จะได้อะไรประมาณนี้ออกมา

<===== y ===...=======>
<== 5000 ======>
<== 20000 ===========>

กลายเป็น gcd(5000, 20000, y) ทำโน่นนี่ไปมาจะได้ GCD = gcd(gcd(5000, 20000), y)

เนื่องจากว่าเราให้ y เป็นอะไรก็ได้อยู่แล้ว ดังนั้น MAX GCD = gcd(5000, 20000) = 5000 แน่นอน!

ต่อมา เราต้องการทราบ x น้อยที่สุด (เวลาน้อยที่สุดที่จะทำให้ได้ MAX GCD) ซึ่ง y = x + 6000

พบว่าในเคสนี้ x น้อยสุดเป็น 4000 ซึ่งทำให้ y เป็น (+) ได้ และหาร MAX GCD = 5000 ลงตัว

ขอสารภาพว่า … ข้อนี้ตอนทำไม่ได้คิด math แบบข้างบนหรอก (อ้าววว) นั่งวาดรูปๆๆๆ เดาๆๆ แล้วลองมั่วๆกับ sample ดู ถูกเคสเล็กก็ลองเคสใหญ่เลย ไอ่ที่ทำ math เพราะพยายามหาข้อสนับสนุนวิธีที่ทำไป(แล้ว) = =’

ขอขอบคุณ Python ทำให้ไม่ต้องไปวุ่นวายเรื่อง BigInteger แล้วก็ยังแถม fractions.gcd มาให้อีก!

(แอบภูมิใจบรรทัด reduce TvT)

import fractions

if __name__ == '__main__':
fin = 'B-large.in'
fon = 'B-large.out'

fi = open(fin, 'r')
fo = open(fon, 'w')

c = int(fi.readline())
for i in xrange(c):
ts = [int(x) for x in fi.readline().split(' ')][1:]
m = min(ts)
tns = [x - m for x in ts]
unit = reduce(lambda x,y: fractions.gcd(x,y), tns)
r = m % unit
ans = unit - r if r else 0
fo.write("Case #%d: %d\n" % (i + 1, ans))

print "Done!"
fi.close()
fo.close()

ข้อสาม Theme Park

ข้อนี้ใช้วิธี pre-computed (หรือจะเรียกว่า cache ?) อะไรที่มันทำได้ไว้ก่อน ทำให้ตอนคำนวณจริงๆไม่ต้องทำอะไรซ้ำๆ แต่ถ้าทำแค่นี้มันจะยังไม่เร็วพอ (โดยเฉพาะถ้าเป็นโปรแกรม Python รันดิบๆ T_T’)

แนวคิดคือ ในการเล่นรอบใดๆที่มี group ที่อยู่หัวคิวเป็น group เดียวกัน (เช่นรอบ 3 กับรอบ 5 มี g1 เป็นหัวคิวเหมือนกัน) จะเก็บเงินได้เท่ากันเสมอ และหัว group ในรอบถัดไปก็จะเป็น group เดียวกันเสมอ …

ดังนั้นไอ่การคำนวณจำนวนคนนั่งในแต่ละรอบนี่ ทำครั้งเดียวก็พอ (สำหรับรอบที่ขึ้นต้นด้วยแต่ละ group) และก็ควรบันทึกไว้ด้วย ว่าหลังจาก group นี้เล่นในรอบนี้แล้ว รอบถัดไปจะเป็น group ไหน จากตัวอย่าง

grou: [1, 4, 2, 1]
hist: [5, 6, 4, 6]
next: [2, 3, 1, 2]

อันนี้บอกว่า ถ้าเริ่มที่ g0 เก็บเงินได้ 5 ในรอบนั้น, g1 เก็บได้ 6, ….

และถ้าเริ่มที่ g0 รอบถัดไปจะเริ่มที่ g2, เริ่ม g1 ถัดไปเริ่มที่ g3, เริ่ม g2 ถัดไปเริ่มที่ g1, …

โจทย์กำหนดมา r รอบ ก็แค่บวก hist แล้ววนตาม next ต่อไป r ครั้งก็น่าจะได้คำตอบแล้ว แต่อาจจะไม่ทัน …

ถ้าสังเกต next ดีๆ จะเห็นว่ามันวนซ้ำๆ

  • g0 –> g2 –> g3 –> g1 –> g2 –> g3 –> g1 –> g2 –> g3 –> g1 –> g2 –> ….
  • g0 –> (g2 –> g3 –> g1 –>)*  ….

จะเห็นว่ามี loop g2 –> g3 –> g1 วนซ้ำไปมา เราสามารถคิดเงินรวมได้เป็น hist[2] + hist[3] + hist[1] และการวนนี้ใช้เวลา 3 รอบ

ถ้าเรารู้ว่าในการเล่นเครื่องเล่น r รอบมันมีการวนแบบนี้เกิดขึ้นกี่ครั้ง ก็เอาจำนวนรอบมาคูณค่าเล่นรวมได้เลย จะลดการคำนวณไปได้มากเลยทีเดียว เพราะบางเคสมันเล่นตั้ง 10^8 รอบ

ข้อนี้โค้ดผมยาวและซับซ้อนผิด concept มาก - -‘ ปัญหาหลักเกิดจากการเลือกใช้ data structure ไม่ถูกต้อง ผมดันไปใช้เป็น linked structure แบบที่เห็นด้านบน ทำให้ทั้งการหา loop อะไรมันทำยากไปหมด ทั้งๆที่มันทำเป็น list ธรรมดาก็ได้แล้ว

จากเท่าที่แอบไปดูโค้ดเพื่อนบ้านมา ผมชอบคำตอบข้อนี้ของ nattster เขียนอ่านเข้าใจง่ายดี กระชับ สั้น (Python) เป็นตัวอย่างในการเรียนรู้ที่ดี (ส่วนโค้ดยาวๆของผมอยู่ที่นี่ )

ว่าด้วย Big Integer

ข้อสองดักคอคนเขียน C++ สุดๆ เพราะ input/output มันเกิน range ของ int, long ไปเยอะมากๆๆ (10^50)

หลังจากไปไล่อ่านโค้ดเพื่อนบ้านมาว่าแต่ละคนแก้ปัญหายังไง เพื่อนบ้านเขียนกันหลายภาษามาก Python, Ruby, C#, C++, Java, Scala, .. ได้ข้อสรุปว่า

  • Python - ไม่ต้องทำอะไร เด๋วมันเพิ่มขนาดให้เอง
  • C/C++ – ปกติใครๆในอินเทอร์เน็ตก็จะแนะนำให้ใช้ GNU MP (GMP - http://gmplib.org/) แต่เชื่อว่าหลายคนเห็นว่าเป็น GNU ก็คงไม่อยากยุ่งด้วยแล้ว ด้วยความชันของการเรียนรู้เพื่อใช้งาน (ผมคนนึงล่ะ) แล้วก็มีคนใช้ http://mattmccutchen.net/bigint/ ผมว่า lib มันดูใช้ง่ายน่าใช้มากเลยอ่ะ บางคนก็เคยเขียน big num ไว้ใช้เอง (จริงๆ)
  • Java BigInteger!
  • C# - เข้าใจว่า pre 4.0 ยังต้องหา lib ข้างนอกมาใช้เอง ส่วนถ้า 4.0+ (Visual Studio 2010) มี System.Numerics.BigInteger ให้ใช้ (พร้อมเมธอด GreatestCommonDivisor) เฉพาะเรื่องนี้ตามหลัง Java ไม่รู้กี่ปี 555+

ส่วนตัวรู้สึกสอบรอบนี้ โจทย์เน้นหนักไปทางคนที่ถนัดคิดแบบ verbally ซะเป็นส่วนใหญ่ (คือคนที่คิดเป็นข้อความ คำพูด พวกตรีโกณมิติ พีชคณิต ทฏษฏีจำนวน) คนที่ถนัดคิดแบบ visually จะเสียเปรียบ

Code Jam 2010 participants from Thailand http://www.go-hero.net/jam/10/regions/Thailand

ใครมีอะไรมาแชร์ คอมเม็นต์มาโลดด~

General , , ,

ว่าด้วย M79

2. May 2010

Grenade_launcher_M79_1

ช่วงนี้ตูมตามกันใหญ่ เลยลองไปหาอ่านข้อมูลเพิ่มเติมเกี่ยวกับ M79 มาครับ เผื่อว่าจะมีประโยชน์ในการป้องกันตนเอง พอจะสรุปเป็นประเด็นได้ดังนี้

- M79 มันเป็นชื่อ ปืนยิงระเบิด ไม่ใช่ชื่อของระเบิดจริงๆ จริงๆแล้วมันยิงระเบิดได้หลายแบบมากสังแบบสังหารระยะใกล้ หรือยิงระเบิดระยะไกลแบบที่เจอในไทย

- ระเบิดที่เจอในไทยมีชื่อเรียกเฉพาะจริงๆว่า M406

- ตอนเริ่มยิง หัวระเบิด M406 จะวิ่งออกจากปากกระบอก M79 ด้วยความเร็วประมาณ 75 เมตร / วินาที หรือเท่ารถยนต์ความเร็ว 270 กม. / ชม. … โอ้ววว ที่ยกมาตรงนี้เพราะคิดว่าระหว่างหัวระเบิดวิ่งมันน่าจะมองเห็นทันด้วยตาเปล่าและมี action เช่นการหมอบลงพื้น ได้ทัน

- ตอนระเบิด หัวระเบิด M406 จะให้สะเก็ดระเบิดออกมาประมาณ 300 ชิ้นถ้วนออกมารอบทิศทาง (ถ้าใครไม่คุ้นกับคำว่าสะเก็ดระเบิด ให้คิดว่ามันเป็นกระสุนดีๆนี่เอง) ด้วยความเร็ว 1,524 เมตร / วินาที (อันนี้คงไม่ต้องเทียบกับรถยนต์ เพราะคงรู้นะว่ามันเร็วมาก - -‘’)

- เสียงเดินทางที่ความเร็ว 340 เมตร / วินาที ที่อากาศ 20 °C และความหนาแน่นอากาศระดับน้ำทะเล

- นั่นแปลว่า สะเก็ดระเบิดเดินทางเร็วกว่าเสียง และจังหวะที่เราได้ยินเสียงระเบิด คาดว่าสะเก็ดระเบิดคงฝังในตัวเรียบร้อยแล้ว o__o’ ฮะ!!?! ดังนั้นตอนที่ได้ยินเสียงระเบิด มันไม่มีโอกาสเลยที่จะทำ action เช่นการหมอบ … ยกเว้นจะทำเพื่อหลบระเบิดลูกถัดไป …

- ตัวลูกระเบิดมีระบบรักษาความปลอดภัย … ให้ผู้ยิง (เอ๊ะ!) ด้วยการการรันตีว่าจะไม่ระเบิดภายในระยะ 30 เมตรหลังจากที่มันโดนยิง ดังนั้นถ้าอยู่ใกล้คนยิง 30 เมตรก็จะปลอดภัย …. แต่ถ้าเห็นหน้าคนยิง ก็อาจจะโดนเก็บอยู่ดี =_=’’ โอ้ยย

- ยิงได้ไกลที่ประมาณ 350 – 400 เมตร  แต่ถ้าระเบิดตกใกล้ตัวในรัศมี 5 เมตร (เกือบเท่าตึก 2 ชั้น) การันตีว่าตาย  - -‘’

- ตอนเรียน นศท. (รด. นั่นแหละ) ทหารแตงโมรึเปล่าก็ไม่รู้ สอนว่าให้ “หมอบ” หลบระเบิด เพราะวิถีสะเก็ดระเบิดจะพุ่งออกมาเป็นตัว V แบบรูปด้านล่าง ดังนั้นการหมอบจะมีโอกาสหลบได้เยอะสุด อีกอย่างนึง (อันนี้ไม่แน่ใจ) ให้คว่ำหน้าเอาตาแนบกับมือเป็นการเก็บอวัยวะสำคัญ

Trajectory

- แต่ประเด็นคือระเบิดแบบที่ทหารบอก มัน assume ว่าระเบิดจากที่พื้น  แล้วถ้าระเบิดบนหลังคา BTS หรือต้นไม้ข้างๆ หรือกำแพงตึกล่ะ ??

Trajectory2

- ผมมานั่งคิดๆดูแล้ว คิดว่าสถานการณ์ส่วนใหญ่การหมอบ work สุดนะ เพราะโอกาสมันคงน้อยมากที่จะยิงแล้วไประเบิดบนเพดาน (ซึ่งเป็นกรณีแย่สุดของการหมอบ  - -‘ ) นอกนั้นก็โอเค

- ดังนั้น ผมคิดว่ากรณีทั่วๆไป ถ้าเราสามารถทำนายได้ว่าต่อไปจะมีเหตุระเบิดเกิดขึ้น หรือเห็นคนกำลังชู M79 กำลังจะยิงเลย ให้หมอบไว้น่าจะดีสุด (หวังว่าจะไม่มีใครทะลึ่งวิ่งเข้าไปหลบในระยะ 30 เมตรจากคนยิง +_+)

หวังว่าคงมีประโยชน์ ไม่ว่าฝ่ายไหนจะยิง ตัวเราต้องปลอดภัยไว้ก่อน

General, Life , ,

ทำไมคนเราถึงเกลียดภาษาอื่นๆ

21. February 2010

แน่นอน ภาษา Programming นะครับ ไม่ใช่ จีน ญี่ปุ่น อังกฤษ :P

ไปเจอคำถามนี้และคำตอบที่น่าสนใจมาก ว่าการเกลียดภาษาอื่นๆมักจะแบ่งเป็น 3 แบบ

เกลียด เพราะได้ยินข่าวลือแย่ๆมา เช่น

  • “Ruby ช้า เขียนแล้วโค้ดสวยก็จริงแต่ทำงานช้าโคดๆ”
  • “เขียน VB, C#, .NET แล้วโง่ เอะอะอะไรก็ลากแปะ”
  • “Java ช้า”
  • “C++ มีแต่ไดโนเสาร์เขียน”

พวกนี้ส่วนใหญ่พอได้ยินข่าวลือพวกนี้มาจาก forums หรือเว็บข่าว ก็มักจะฝังใจแล้วบอกต่อๆกัน แต่ก็ไม่เคยลองเอง และก็ไม่รู้ว่ามันไม่ดีตามที่บอกรึเปล่า

เกลียด เพราะใช้แล้วไม่พอใจ

พวกนี้เคยใช้จริง แล้วไม่พอใจจริง ซึ่งอาจเกิดจากสาเหตุ เช่น

  • โดนหัวหน้า อาจารย์ เจ้านาย บังคับให้ทำ ซึ่งทำแล้วปรากฎว่าใช้แล้วได้ผลไม่ดี (อาจจะแบบว่าใช้อย่างอื่นแล้วเหมาะกว่า เช่น เคยเอา C++ ไปเขียน Web App) ก็เลยไม่ชอบ
  • ใช้แล้วมัน “ไม่ใช่ว่ะ”
  • ไม่ค่อยมีข้อมูลในการใช้เรียนรู้ หรือ learning curve ชันไป

เกลียด โดยหลักการ

ไม่ชอบลักษณะ / คุณสมบัติ บางอย่างของภาษา โดยอาจจะรู้สึกว่าภาษาหนึ่งดีกว่าอีกภาษา ตรงที่ … เช่น

  • “ไม่ชอบ Java เพราะต้องทำงานบน JVM  … มันไม่ถูกต้องนะ! เขียน C++ แล้วให้ compile เป็น native สิ!” -- คลั่ง C++
  • “ไม่ชอบ C++ เพราะต้องมารับผิดชอบการเขียนให้มัน cross platform เอง ต้องมาเช็ค #ifdef เบื้อกอะไรตั้งมากมาย แล้วต้องมาเรียนรู้ platform-specific system calls เอง เฮ้อ” -- ผมเขียน Java
  • “ไม่ชอบ Java เพราะ syntax มันช่างบุโรคั่งและยืดเยื้อ รวมถึงแคร์เรื่อง backward compatibility เหลือเกิน ไม่ Elegant เหมือนภาษาผมเอาซะเลย” -- ผมเขียน C#

ส่วนตัวผมมีประสบการณ์กับการไม่ชอบทั้ง 3 แบบ

แบบ 1 สมัยเด็กๆผมรู้สึกว่า VB 6 ดูดีมีอนาคตกว่า VC++ มากๆ เพราะแค่ new project ใหม่ก็ได้ Window เปล่าๆมาอันนึงแล้ว ส่วน VC++ ต้องเขียนโค้ดเองกว่า 80 บรรทัดกว่าจะได้หน้าต่างว่างๆมา ผมก็เลยไม่เข้าใจอย่างยิ่งว่าทำไมคนถึงยังชอบไปเขียน C++ กัน ประกอบกับเจอพวก C++ หัวแข็งมากมายใน forum ดังสมัยนั้น (thaidev.com) ซึ่งบางที task VC++ บางอย่างที่มาถามๆกันในเว็บบอร์ด ผม “Thinking in VB 6” พรืดเดียวก็ออกแล้ว ผมจึงไม่ชอบ C++ และเป็นผู้ ไม่สนับสนุน อย่างเป็นทางการ ตั้งแต่นั้น

ผมมาค้นพบอีกทีตอนหลังว่า มันใช้ในงานคนละประเภทกัน (จริงๆคนในบอร์ดเค้าก็พูดกันอยู่ปาวๆ แต่ด้วยความที่โลกของเราตอนนั้นมันแคบ ก็เลยไม่ค่อยเข้าใจ) แล้วไอ้ภาษาสุดวิเศษของผม เวลาจะทำอะไรระดับกลางๆ (ไม่ต้องถึงระดับลึกหรอกนะ) กับระบบ นี่นั่งเขียน Declare WinAPI กันอ้วกแตกเลยทีเดียว

แบบ 2 ผมเกลียด C บน Microcontroller มากๆครับ! เนื่องจากว่ามันเป็นภาษาที่ค่อนข้างพิกา… เอ้ย จำกัด ไม่สามารถใช้ประโยชน์ของ C ได้อย่างเต็มที่, call stack ก็มีขนาดจำกัด แล้วยังมี bahavior ที่คาดเดาไม่ได้อีกหลายอย่าง (ขนาดผมเขียน C แบบพื้นฐานมากๆแล้วนะ) ประกอบกับผมขาด resource (เวลา + ฮาร์ดแวร์ที่ใช้เบิร์นโปรแกรมลงบอร์ด) ทำให้สุดท้ายผลมันออกมาไม่ดี แล้วก็มีเรื่องไม่ดีมากตามมาอีกหลายอย่าง (เพื่อนสนิทรู้กัน - -‘’) ผมเลย “พาล” เกลียด C บน Micro แบบฝังใจไปเลยจนทุกวันนี้

เปรียบเทียบกับประสบการณ์เดียวกันบน Verilog (มันใช้งานละแบบกันน่ะ แค่เป็น hardware เหมือนกันเลยเอามาเทียบ) ผมประทับใจมากกก

แบบ 3 ถ้าจะมีคงเป็น PHP ซึ่งตอนนั้นผมขยับจาก ASP ไปเป็น ASP.NET พอดี สมัยนั้น ผมดูภาษามันแล้วรู้สึกว่าวิธีการ extends ภาษาด้วยการลง mod เพิ่มมันดูพิลึกๆ (มาก) แล้วก็ยังมีเรื่องต้อง compile คู่กับ MySQL lib ให้ตรงเวอร์ชันอีกไม่งั้นจะใช้ด้วยกันไม่ได้ ก็เลยไม่คิดจะศึกษาเพิ่มเติมนอกจากเขียนอะไรง่ายๆที่สมัยนั้นคนชอบเขียนกัน (Counter, Webboard, GuestBook) ซึ่งการไม่ศึกษา PHP ทำผมเสียโอกาสไปเยอะพอควร

เอาจริงๆผมไม่ค่อยเกลียดอะไรในระดับนี้เท่าไหร่นะ ด้วยเหตุผลที่ว่า ภาษาไหนที่มันไม่ดังผมก็จะไม่ค่อยสนใจ แล้วภาษาที่ดังขึ้นมาได้ก็แปลว่ามันผ่านกระบวนการ natural selection และมันโดนทดสอบด้วย “เวลา” มาระดับนึงแล้ว มันก็คงมีข้อดีของมันแหละ

ที่เห็นแล้วหงุดหงิดใจมากกว่าคือการเลือก tecnhology แล้วไม่ค่อยคำนึงความเป็นไปได้ + ความเหมาะสม ถ้าเป็นคนใกล้ตัวก็จะพยายามแนะนำและโน้มน้าว 555+ แต่ก็ยอมรับว่าบางทีเราก็ไม่ได้รู้ requirement เท่ากับเจ้าของงานเองก็อาจจะบอกอะไรไม่ได้มากเท่าเค้าเหมือนกัน

โดยสรุปคือ ไม่ว่าจะเป็นความเกลียดแบบไหน ล้วนแล้วแต่มีผลเสียทั้งสิ้น ถ้าเป็นไปได้ควรมองให้เห็นข้อดีข้อเสียของแต่ละอย่างมากกว่า (จบบลอกเหมือนนิทานอิสป)

General

ดึงราคาหุ้นใน SET

13. December 2009

ไปอ่านเอกสารพวก Chart Patterns มา ซึ่งมันคือ Pattern ของกราฟราคาหุ้นที่คนเขียนเอกสารพวกนี้เค้าสังเกตมาว่า เป็นสัญญาณอะไรบางอย่างที่ทำให้หุ้นจะเปลี่ยนราคา (ขึ้น หรือ ลง) ไปอย่างรวดเร็วทำให้สามารถใช้ trade ทำกำไร (หรือขาดทุนยับ) ได้ ส่วนใหญ่คนเขียนเอกสารเค้าก็จะออกตัวไว้ก่อนเลยว่า มันไม่ถูก 100% นะ แต่ก็ไม่เคยมีใครบอกว่ามันถูกกี่ % ดังนั้นก่อนอื่นต้องหาวิธีดึงราคามาเอาไว้ทำการทดลองก่อน

จริงๆแล้ว API ที่ บ.เหมาะกับงานนี้มากเลย แต่ถ้าเอา Data ตรงนั้นมาใช้กลัวว่าอาจจะได้เตะฝุ่นก่อนทำงานครบปี :[ เหอะๆ

class DayData:
    date = None
    open = None
    close = None
    max = None
    min = None
    volume = None
    value = None
    set_index = None

    def __init__(self):
        pass

    @staticmethod
    def to_datetime(str):
        from datetime import datetime
        ds = [int(x) for x in str.split('/')]
        ds[2] = ds[2] + 2000
        return datetime(ds[2], ds[1], ds[0])
                
    @staticmethod
    def to_decimal(str):
        from decimal import Decimal
        return Decimal(str.replace(',',''))

class SETFetch:
    @staticmethod
    def fetch(symbol):
        import urllib2
        from decimal import Decimal
        from BeautifulSoup import BeautifulSoup
        
        set_url_format = "http://www.settrade.com/C04_02_stock_historical_p1.jsp?txtSymbol=%s&from=%d";
        cur_pos = 1
        all_data = []

        while True:
            page = urllib2.urlopen(set_url_format % (symbol, cur_pos))
            soup = BeautifulSoup(page)
            read_data = soup.findAll('tr','tdbg_gray20') + soup.findAll('tr','tdbg_white20')
            if len(read_data) == 0:
                # no more data to read
                break
            cur_pos = cur_pos + len(read_data)
            all_data = all_data + read_data

        daily = []
        for day in all_data:
            flds = day.findAll('td')
            current = DayData()
            current.date =  DayData.to_datetime(flds[0].text)
            current.open = DayData.to_decimal(flds[1].text)
            current.max = DayData.to_decimal(flds[2].text)
            current.min = DayData.to_decimal(flds[3].text)
            current.close = DayData.to_decimal(flds[5].text)
            current.volume = DayData.to_decimal(flds[8].text) * 1000
            current.value = DayData.to_decimal(flds[9].text)
            current.set_index = DayData.to_decimal(flds[10].text)
            daily.append(current)    
        daily.sort(key=lambda x: x.date, reverse=True)
        return daily

if __name__ == '__main__':
    daily = SETFetch.fetch('PTT')
    for day in daily:
        print day.date
    #pdb.set_trace()
ตัวอย่างการใช้งาน
Python 2.6.3 (r263rc1:75186, Oct  2 2009, 20:40:30) [MSC v.1500 32 bit (Intel)]
on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from setfetch import SETFetch
>>> data = SETFetch.fetch('CPF')
>>> dir(data[0])
['__doc__', '__init__', '__module__', 'close', 'date', 'max', 'min', 'open', 's
t_index', 'to_datetime', 'to_decimal', 'value', 'volume']
>>> for sample in data[0:10]:
...     print sample.date, sample.close
...
2009-12-11 00:00:00 10.90
2009-12-09 00:00:00 10.70
2009-12-08 00:00:00 10.80
2009-12-04 00:00:00 11.00
2009-12-03 00:00:00 10.70
2009-12-02 00:00:00 10.60
2009-12-01 00:00:00 10.90
2009-11-30 00:00:00 10.70
2009-11-27 00:00:00 10.20
2009-11-26 00:00:00 10.40
>>>

เท่าที่รู้ SET จะไม่ยอมให้ใครมาเผยแพร่ Historical Prices พวกนี้ ยกเว้นคนที่จ่ายตังค์ให้ SET และถ้าจะเผยแพร่ก็ต้องเผยแพร่แบบเก็บเงินเท่านั้นด้วย! (แจกฟรีไม่ได้) แต่ทุกวันนี้ก็จะเห็นมีการแอบแจกกันบ่อยๆ :} เป็นเหตุผลว่าทำไมถึงดูราคาหุ้นไทยในเว็บดีๆอย่าง Google Finance ไม่ได้ (แต่ทำไม Bloomberg ดูได้ไม่รู้ ขี้โกงๆ)

ช่วงนี้นอกจากจะเขียนโค้ดช้าลงแล้ว เวลาว่างยาวๆติดๆกันก็ไม่ค่อยจะมี ความสนใจก็เยอะเหลือเกิน >_< เลยต้องพยายามทำให้เสร็จไปเป็นชิ้นเล็กๆ ครั้งหน้าค่อยมาต่อกันเรื่อง Bar Pattern ที่ไปดูมา ว่าพอมาทดสอบกับข้อมูล 6 เดือนที่ดึงมาแล้วมันจะเวิร์คแค่ไหน

General , , ,

2 เดือนในตลาด

7. November 2009

เผลอๆผ่านมาจะครบสองเดือนแล้วตั้งแต่เริ่มเข้าไปซื้อขายหุ้นใน SET ~

ผมสารภาพว่าก่อนหน้านี้ เวลาดูข่าวทีวี (เอ๊ะ .. ดูทีวีด้วยเหรอ) ช่วงที่เค้าบอกว่าวันนี้ดัชนีตกไปกี่จุดๆ จะเป็นช่วงเวลาที่น่าเบื่อสำหรับผมมากก (พูดเรื่องอะไรกันวะ) แต่หลังจากเริ่มทำงานที่บริษัทก็เลยรู้ว่า product ของ Thomson Reuters มันเกี่ยวกับ Financial Market ล้วนๆเลยนี่หว่า (ก่อนสัมภาษณ์เข้าทีไม่กี่วันยังคิดอยู่เลย ว่านี่จะเข้ามาเป็นลูกจ้างนักข่าว เขียนโปรแกรมตามสั่งให้รึเปล่าวะ 555+) ก็เลยเริ่มสนใจขึ้นมามาก ประกอบกับวัยเพิ่งเริ่มทำงาน ภาระอะไรก็ไม่มี ยังรับความเสี่ยงสูงๆได้อยู่ น่าจะใช้โอกาสนี้ให้คุ้มค่าหน่อย

เคยคุยกับพี่ที่ทีม เค้าบอกว่าเค้าเริ่มซื้อๆขายๆตั้งแต่ ปี 2 … จะไม่น่าแปลกใจเท่าไหร่ถ้าพี่เค้าไม่ได้อายุมากกว่าผมประมาณ 6 ปี = =’ ผมก็แอบรู้สึกว่าตัวเองเริ่มช้าไปนิดนึง จริงๆเรื่องนี้อาจจะแล้วแต่คน แต่ผมคิดว่าวันนึงเราคงหลีกเลี่ยงการรู้จัก “ตลาด” ไม่ได้ เริ่มรู้จักตลาดเร็วๆก็น่าจะดีกว่า ถ้าย้อนเวลากลับไปได้อยากเริ่มซะตั้งแต่เรียนมหาลัยนี่หละ เหมาะที่สุดแล้ว

โชคดีอีกอย่างคือที่บ้านก็ไม่ได้ไม่เห็นด้วยกับการเอาเงินไปโยนไว้ใน Market แต่อย่างใด และยังให้คำแนะนำที่ดีได้ ผมคุยกับเพื่อนหลายๆคน บางบ้านจะไม่สนับสนุนให้ “เล่นหุ้น” มาก ช่วงสองเดือนนี้ก็ได้คำแนะนำจากป๊าตลอด และก็จากพี่ๆที่ทีมบ้าง เจอเหตุการณ์สำคัญไปสองครั้ง

  1. อย่างแรก ซื้อหุ้นน้ำผลไม้ของ TIPCO แล้ว (มารู้ตอนหลังว่ามันบังเอิญมากก) ราคามันขึ้นสูงอย่างมีนัยสำคัญ ก็ขายทิ้ง ถือเป็น impression ที่สุดยอดมากสำหรับมือใหม่ ทำให้ view ผมตอนนั้นโคด optimistic เลย (ถ้าเงินมันหาง่ายขนาดนั้น คงมีคนนอนจิ้มๆคีย์บอร์ดอยู่บ้านมากมาย =_=’)
  2. อย่างที่สอง ตอนมีข่าวทุบตลาด แล้วดัชนีร่วงติดกัน 2-3 วัน ช่วงนั้นหุ้นที่ซื้อมาแทบทุกตัวราคาตกระนาว ก็ได้เรียนรู้กันไปหลายอย่าง ทำลายความ optimistic ลงไปอย่างสิ้นเชิง และทำให้รู้สึกว่าต้องระมัดระวังขึ้นมาก

 

Technical Analysis และ Value Investing

วิธีการทำเงินในตลาดมันเข้าใจง่ายมากครับ ก็คือซื้อมาแล้วก็ขายออกไปให้แพงกว่า! แต่ปัญหาคือ แล้วจะซื้อตอนไหนและขายตอนไหนน่ะสิ ???

มี “แนวคิด” สองอย่างที่ใครๆในตลาดก็รู้จัก คือเรื่องของ Technical Analysis และ Value Investing (VI)

อย่างแรกมีความหมายตามชื่อ คือ Technical Analysis นั้น จะสนใจข้อมูลที่อยู่ตรงหน้าเป็นหลัก คือ ราคา ปริมาณการซื้อขาย แล้วพยายามทำนายอนาคต มีเครื่องมือที่สำคัญคือ indicator ซึ่งจริงๆแล้วมันคือการเอาข้อมูลที่เห็นตรงหน้า (ราคา เปิด ปิด สูงสุด ต่ำสุด ซื้อขายล่าสุด ปริมาณ) ไปผ่านการคำนวณอะไรบางอย่าง แล้วเอามาแสดงอีกรอบ เท่านั้นเอง หลังจากเราเห็นข้อมูลพวกนี้ก็สามารถมองหา Signal (สัญญาณ) ได้ สัญญาณที่บอกว่าราคากำลังจะขึ้นเรียกว่า Bullish Signal (กระทิง) ในขณะที่สัญญาณที่บอกว่าราคาจะตกเรียกว่า Bearish Signal (หมี)

Indicator ก็แบ่งเป็นประเภทต่างๆ ที่เห็นพูดถึงกันบ่อยก็คือ MACD ที่เป็น indicator ประเภท trend following นั่นคือมันจะทำงานได้ดีเวลา “แนวโน้ม” ราคามัน “ขึ้น” หรือว่า “ลง” อย่างชัดเจน และจะทำงานได้แย่มากถ้าราคามันแกว่งไปมาแบบไม่มี trend หรือรูปแบบ Whipsaw ส่วนอีกตัวที่พูดถึงบ่อยเช่นกันคือ Relative Strength Index (RSI) เป็น Indicator ประเภท momentum คือบอกว่าตอนนี้มีการซื้อหรือขายมากเกินไปรึยัง (over-bought, over-sold) ถ้ามากเกินไปแล้วก็อาจจะถึงเวลาที่ราคาจะกลับตัว

อย่างที่สอง คือ Value Investing เป็นแนวคิดที่ริเริ่มสอนโดย Benjamin Graham ซึ่งปรากฎว่า ศิษย์เอกของอาจารย์คนนี้ “รวยแหลก” แทบทุกคน หนึ่งในนั้นรวมถึงนักลงทุนที่ขึ้นชื่อว่าประสบความสำเร็จที่สุดในโลก คือ Warren Buffett ด้วย เนื่องจากว่ามือใหม่อย่างผมเป็นพวกที่ incline ไปทาง TA มากกว่า เลยรู้แนวคิดของ VI แค่นิดหน่อย คือการเลือกหุ้นเพื่อลงทุนของ VI นั้นมักจะใช้ข้อมูลที่เป็น Reference Data คือเป็นประวัติการจ่ายปันผลของบริษัท ทรัพย์สินของบริษัทเป็นยังไงบ้าง ราคานี้เหมาะสมแล้วหรือเปล่า? คำพูดที่จะได้ยินบ่อยๆจาก VI คือ “ราคาต่ำกว่าที่ควรจะเป็นมาก ควรซื้อ” หรือ “ราคาสูงกว่าที่ควรจะเป็นมากแล้ว ควรขาย” ตัวอย่างหุ้นที่ “น่าซื้อ” สำหรับคนกลุ่มนี้ เช่น หุ้นที่ราคาหุ้นนั้น ต่ำกว่าทรัพย์สินที่บริษัทมีทั้งหมดเสียอีก แบบนี้ก็จะถือว่าราคามันต่ำกว่าความเป็นจริง และเชื่อว่าวันนึงราคาก็จะ (ขึ้นมา) reflect เรื่องนี้ในที่สุด พวกนี้ส่วนใหญ่จะถือยาว คือ buy-and-hold ซื้อไว้แล้วก็เฝ้าดูห่างๆก็พอ ไม่ต้องเฝ้าหน้าจอรอดูจุดกลับตัวเหมือนพวก TA

เรื่องแปลกๆที่ผมสังเกตเห็น คือ VI กับ TA จะแบ่งก๊กกันชัดเจน และมักจะมี argument ให้เห็นบ่อยๆว่าแบบไหนทำเงินได้ดีกว่า ข้ออ้างอย่างนึงที่มักจะเห็นบ่อยๆคือ VI ดีกว่าเพราะว่านักลงทุนที่รวยที่สุดเป็น VI พันธุ์แท้! .. อันนี้ก็เหมือนกับการอ้างว่า ถ้าอยากรวยไม่ต้องเรียนมหาวิทยาลัยก็ได้ เพราะ Bill Gates ก็ไม่ได้จบมหาวิทยาลัย

การแบ่งก๊กระหว่าง VI กับ TA ทำให้ผมคิดถึงตัวเอง รวมถึงพวก “C++ หัวแข็ง” “Microsoft หัวแข็ง” “Linux หัวแข็ง” หลายๆคน ผมว่าการมี “ศาสนา” พวกนี้ทำให้เราพลาดอะไรดีๆไปหลายอย่าง

คำแนะนำสำหรับคนอยากเริ่ม

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

หลังจากนั้นก็ต้องเปิดบัญชีซื้อกับโบรคเกอร์ เนื่องจากว่าเราเข้าไปซื้อๆขายๆในตลาดเองไม่ได้ ต้องมี middle-man หรือนายหน้าพวกนี้จัดการให้ โดยเค้าก็จะมีการคิดค่าดำเนินการนิดหน่อย (Commission) เช่น ถ้าซื้อหุ้นราคา 1 บาท จำนวน 1000 หุ้น แบบนี้เราจะต้องจ่ายค่าดำเนินการเพิ่ม 1.5 บาท เป็นต้น รวมเงินที่ต้องจ่ายเป็น 1001.5 บาท

มือใหม่รายย่อยอย่างเราๆก็น่าจะเปิดเป็นแบบ internet trading (อีกแบบคือใช้โทรศัพท์โทรไปหาเจ้าหน้าที่การตลาด หรือเรียกสั้นๆว่า “มาร์” มาจาก marketing) แล้วก็เปิดเป็นบัญชีแบบ Cash Balance คือต้องโอนเงินเข้าไปก่อนจึงจะซื้อหุ้นได้ (เหมือนโทรศัพท์มือถือ Pre-paid) ซึ่งน่าจะปลอดภัยมากกว่า ส่วนบัญชีอีกแบบจะให้ซื้อได้ก่อน แล้วค่อยเช็คบิลทีหลัง

ตอนนี้ก็มีโบรคอยู่หลายๆที่ วิธีเลือกง่ายๆสำหรับมือใหม่คือเลือกโบรคที่ “ไม่คิดค่า commission ขั้นต่ำ” ณ เวลาที่ผมเขียนนี่ค่า commission อยู่ที่ 0.15% หมายถึงถ้าซื้อขาย 100 บาท จะเป็นค่าคอม 0.15 บาท แต่ถ้าหากมีค่าคอมขั้นต่ำ 50 บาท (สมมติ) หลังคำนวณค่าคอมแล้วได้แค่ 0.15 บาทก็จะต้องจ่าย 50 บาทเต็มๆ

อีกอย่างที่ต้องดูคือโปรแกรมสำหรับดูราคาแบบ Real-time ของโบรคมันใช้ได้กับคอมพิวเตอร์ของเรารึเปล่า หลายๆที่ใช้ technology พวก ActiveX นั่นหมายถึงต้องใช้ Windows และ IE เท่านั้นจึงจะใช้ได้ บางที่เช่นที่ผมใช้อยู่ก็จะมีส่วนที่เป็น HTML ธรรมดาให้ใช้เหมือนกัน (สำหรับ Firefox และพวก PDA) ใช้ดูราคา ส่งคำสั่งซื้อขายได้ แต่มันจะไม่ real-time เท่านั้นเอง

ตอนที่ผมเลือกโบรคที่เจ้าที่สนใจอยู่สองที่ คือ KTZmico และ Kim Eng (ไม่ได้ค่าโฆษณานะ) สุดท้ายผมเลือก Kim Eng ด้วยเหตุผลหลายอย่าง หนึ่งในนั้นคือชื่อโดเมนมันพิมพ์ง่ายกว่ามาก! สนนค่าเปิดพอร์ตอยู่ที่ 30 บาทถ้วน ถ้าใครอยากเริ่มผมแนะนำให้เริ่มเตรียมเอกสารเปิดไว้เลย เพราะหลังเปิดแล้วจะช่วยให้ Active ขึ้นมาก

Hope this helps

General , ,