Friday, 21 July 2017

Php รหัส ชี้แจง เคลื่อนไหว ค่าเฉลี่ย


ฉันต้องการคำนวณค่า EMA (Exponential Moving Average) ใน PHP Ive พยายามกับรหัสต่อไปนี้ แต่ให้ฉัน 500 ข้อผิดพลาด PHP: ฟังก์ชันการคำนวณ EMA trader-ema พยายามด้วย Googling เป็นเวลานาน แต่ไม่ได้รับความช่วยเหลือเกี่ยวกับเรื่องนี้ใน PHP ดังนั้น Ive ไม่มีเงื่อนงำสิ่งที่ต้องทำเพื่อคำนวณค่า EMA แก้ไข -1: ส่วนขยายที่ติดตั้ง Ive ติดตั้งส่วนขยายที่จำเป็นทั้งหมดตอนนี้ฉันได้รับเอาท์พุท แต่ก็ไม่ได้ดูเหมือนให้ผลผลิตที่เหมาะสม ฉันคิดว่าฟังก์ชัน PHP สำหรับการคำนวณ EMA ทำงานไม่ถูกต้อง ความช่วยเหลือในเรื่องนี้น่าจะได้รับความนิยมอย่างมากลองพยายามดึงข้อมูล EMA ล่าสุดของชุดข้อมูลขนาดใหญ่ (15000 ค่า) เป็นอัลกอริทึมที่ต้องใช้ทรัพยากรมากเนื่องจากแต่ละค่าขึ้นอยู่กับขั้นตอนก่อนหน้านี้ นี่คือรหัสของฉัน: สิ่งที่ฉันได้ทำ: Isolate k เพื่อไม่คำนวณ 10000 times เก็บเฉพาะ EMA ที่คำนวณล่าสุดและไม่เก็บข้อมูลทั้งหมดไว้ในอาร์เรย์สำหรับ () แทน foreach () อาร์เรย์ข้อมูลไม่มีคีย์ อาร์เรย์พื้นฐานนี้อนุญาตให้ฉันลดเวลาดำเนินการจาก 2000ms เป็น 500ms สำหรับค่า 15000 สิ่งที่ไม่ได้ผล: ใช้ SplFixedArray () การโกงนี้เพียง 10ms การใช้งาน 1,000,000 ค่าใช้ส่วนขยายของ PHPTrader นี้ส่งกลับอาร์เรย์ที่มี EMAs ทั้งหมดแทนที่จะเป็นเพียงล่าสุดและการเขียนช้าลงและเรียกใช้อัลกอริทึมเดียวกันใน C และใช้งานได้มากกว่า 2,000,000 ค่าใช้เวลาเพียง 13ms ดังนั้นเห็นได้ชัดว่าการใช้ภาษาระดับล่างที่คอมไพล์แล้วดูเหมือนจะช่วยให้ P ที่ไหน ฉันควรจะไปจากที่นี่รหัสในที่สุดจะทำงานบนอูบุนตูดังนั้นภาษาที่ฉันควรเลือกจะ PHP จะสามารถโทรและส่งผ่านเช่นอาร์กิวเมนต์มากสคริปต์ถามกรกฎาคม 11 14 ที่ 19:21 ชัดเจนใช้กับนามสกุลให้คุณ การเพิ่มขึ้นอย่างมีนัยสำคัญ นอกจากนี้แคลคูลัสสามารถปรับปรุงได้ด้วยตัวเองและคุณสามารถเพิ่มภาษาใดก็ได้ตามที่คุณเลือก เป็นเรื่องง่ายที่จะเห็นว่า lastEMA สามารถคำนวณได้ดังนี้: สามารถเขียนใหม่ได้ดังนี้เพื่อที่จะออกจากลูปให้มากที่สุดเท่าที่จะเป็นไปได้: เพื่ออธิบายการสกัดของ k คิดว่าในสูตรก่อนหน้านี้มีลักษณะเหมือนกับว่าทั้งหมด ข้อมูลดิบต้นฉบับจะถูกคูณด้วย k ดังนั้นในทางปฏิบัติคุณจึงสามารถคูณผลลัพธ์สุดท้ายได้ โปรดทราบว่าการเขียนใหม่ด้วยวิธีนี้ทำให้คุณมีการดำเนินการภายในห่วง 2 แบบแทนที่จะเป็น 3 (เพื่อให้แม่นยำภายในลูปนอกจากนี้ยังมีการเพิ่ม i และการเปรียบเทียบกับการกำหนดค่าให้เป็นขนาดและ lastEMA) ด้วยวิธีนี้คุณจึงคาดว่าจะได้รับเพิ่มเติม speedup ในช่วงระหว่าง 16 และ 33 นอกจากนี้ยังมีการปรับปรุงอื่น ๆ ที่สามารถพิจารณาได้อย่างน้อยในบางสถานการณ์พิจารณาเฉพาะค่าล่าสุดค่าแรกจะคูณหลายครั้งโดย k1m 1 - k ดังนั้นการมีส่วนร่วมของพวกเขาอาจน้อยหรือแม้แต่ไป ภายใต้ความแม่นยำจุดลอยตัว (หรือข้อผิดพลาดที่ยอมรับได้) แนวคิดนี้มีประโยชน์อย่างยิ่งหากคุณสามารถสันนิษฐานได้ว่าข้อมูลที่เก่ากว่านั้นมีลำดับความสำคัญเท่าเดิมเนื่องจากเป็นรุ่นที่ใหม่กว่าเพราะถ้าคุณพิจารณาเฉพาะค่าสุดท้ายของข้อผิดพลาดที่คุณทำคือ err EMAofdiscardeddata (1-k) n ดังนั้นถ้าลำดับของขนาดเป็นแบบเดียวกันเราสามารถบอกได้ว่าข้อผิดพลาดที่สัมพันธ์กันนั้นเกิดขึ้นคือ relerr err lastEMA EMAofdiscardeddata (1-k) n lastEMA ซึ่งเกือบจะเท่ากับ (1-k) n ภายใต้สมมติฐานว่า lastEMA เกือบเท่ากับ EMAofdiscardeddata: สมมติว่าคุณสามารถยอมรับข้อผิดพลาด relerr relative คุณสามารถพิจารณาเฉพาะค่า n สุดท้ายที่ (1-k) n lt relerr หมายความว่าคุณสามารถคำนวณล่วงหน้า (ก่อนลูป) บันทึก n (relerr) (1-k) และคำนวณทั้งหมดเฉพาะเมื่อพิจารณาจากค่า n ล่าสุดเท่านั้น หากชุดข้อมูลมีขนาดใหญ่มากนี้สามารถให้การเร่งความเร็วที่สมเหตุสมผล พิจารณาว่าสำหรับตัวเลขทศนิยม 64 บิตคุณมีความแม่นยำสัมพัทธ์ (เกี่ยวข้องกับ Mantra) ซึ่งเป็น 2-53 (ประมาณ 1.1e-16 และเฉพาะ 2-24 5.96e-8 สำหรับเลขทศนิยม 32 บิต) ดังนั้นคุณจึงไม่สามารถรับ ดีกว่าข้อผิดพลาดญาตินี้โดยทั่วไปคุณไม่ควรมีข้อได้เปรียบในการคำนวณค่า log (1-k) มากกว่า n log (1.1e-16) เพื่อให้เป็นตัวอย่างถ้าช่วง 2000 แล้ว log n (1.1e-16) (1-22001) 36746 ฉันคิดว่าน่าสนใจที่รู้ว่าการคำนวณพิเศษจะหายไปภายในรอบที่ไร้ประโยชน์จะดีกว่าที่จะไม่ทำ ตอนนี้ตัวอย่างหนึ่งสำหรับกรณีที่คุณสามารถยอมรับความผิดพลาดของญาติที่มีขนาดใหญ่กว่าความแม่นยำของจุดลอยตัว relpp 1ppm 1e-6 0.00001 6 หลักทศนิยมที่คุณมี log n (1.1e-16) (1-22001) 13815 ฉันคิดว่าค่อนข้าง (สมมุติว่าช่วง 2000 มีความหมายหรือสูงสำหรับแอพพลิเคชันของคุณ แต่ฉันไม่สามารถรู้ได้) เพียงไม่กี่ตัวเลขอื่น ๆ เพราะผมไม่ทราบว่าตัวเลขทั่วไปของคุณคือ relerr 1e-3 range 2000 n 6907 relerr 1e-3 range 200 n 691 relerr 1e-3 range 20 n 69 relerr 1e-6 range 2000 n 13815 relerr 1e - 6 ช่วง 200 n 1381 relerr ช่วง 1e-6 20 n 138 ถ้าสมมติฐาน lastEMA เกือบเท่ากับ EMAofdiscardeddata ไม่สามารถใช้งานได้ง่ายขึ้น แต่เนื่องจาก cam ประโยชน์จะมีนัยสำคัญอาจมีความหมายต่อไป: เราจำเป็นต้องพิจารณาใหม่ (1-k) (บันทึก log (relerr) (lastEMA EMAofdiscardeddata)) เข้าสู่ระบบ (1-k) จุดศูนย์กลางคือการคำนวณ lastEMA (1-k) สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการเข้าสู่ระบบ (EMAofdiscardeddata) EMAofdiscardeddata (โดยไม่มีการคำนวณที่เกิดขึ้นจริงก่อนหน้านี้หรือ EMAofdiscardeddata แน่นอน) กรณีหนึ่งคือเมื่อเรารู้จัก a priori ว่าตัวอย่างเช่น EMAofdiscardeddata lastEMA lt M (เช่น M 1000 หรือ M 1e6) ในกรณีนี้ n lt (log (relerrM)) log (1 - k) ถ้าคุณไม่สามารถให้หมายเลข M ได้คุณต้องหารหัสที่ดี ea to over-estimate EMAofdiscardeddata lastEMA วิธีที่เร็วที่สุดหนึ่งวิธีอาจใช้ M max (data) min (data) Parallelization การคำนวณสามารถเขียนใหม่ได้ในรูปแบบที่เป็นคำย่อที่เรียบง่ายนอกจากนี้ถ้าภาษาสนับสนุนการใช้งานสนับสนุน parallelization ชุดข้อมูลสามารถแบ่งออกเป็น 4 (หรือ 8 หรือ n. โดยทั่วไปจำนวนแกน CPU มี) และสามารถคำนวณผลรวมของข้อตกลงในแต่ละอันในแบบขนานสรุปผลแต่ละตัวที่สิ้นสุด ฉันไม่ได้ไปในรายละเอียดกับเรื่องนี้เนื่องจากคำตอบนี้มีอยู่แล้วยาวมากและฉันคิดว่าแนวคิดนี้ได้แสดงไว้แล้ว ขอขอบคุณสำหรับการใช้ข้อมูลนี้ในข้อมูลตลาดหุ้นดังนั้นข้อเท็จจริงที่ว่าข้อมูลที่เก่ากว่านั้นมีขนาดเท่ากันเนื่องจากข้อมูลใหม่ขึ้นอยู่กับกรอบเวลาที่ใช้ สมมติว่าช่วงของ 200 จะมีการเปลี่ยนแปลงของราคาในกรอบเวลารายวัน (200 วัน) มากกว่ากรอบเวลา 5 นาที (16 ชั่วโมง) ฉันจะทดสอบกับสถานการณ์ที่แตกต่างกันเกี่ยวกับข้อมูลจริงและข้อมูลจำลอง ข้อมูลใหม่ที่มีช่วง 200 ขึ้นไปฉันใช้ชุดข้อมูลองค์ประกอบ 1000 รายการ แต่ฉันยังทำการทดสอบบางอย่างในช่วงไม่กี่ปีที่ผ่านมาดังนั้นฉันยังต้องโหลดชุดข้อมูลทั้งหมด คุณช่วยทั้งสองสถานการณ์ขอขอบคุณคุณ ndash Lykegenes 16 ก. ค. 14 เวลา 15:11 การสร้างส่วนขยายของคุณเองจะช่วยเพิ่มประสิทธิภาพได้อย่างแน่นอน นี่เป็นบทแนะนำที่ดีจากเว็บไซต์ Zend ตัวเลขประสิทธิภาพบางส่วน: ฮาร์ดแวร์: Ubuntu 14.04, PHP 5.5.9, CPU Intel® CPU1.3GHz, CPU 1 คอร์, RAM 128MB (VPS) ก่อน (เฉพาะ PHP, 16,000 ค่า) 500ms C Extension, 16,000 ค่า การขยาย C 0.3ms (มูลค่า 100,000) ส่วนขยาย C ยาว 3.7 ม. (500,000 ค่า) 28.0ms แต่หน่วยความจำ Im จำกัด ที่จุดนี้โดยใช้ 70MB ฉันจะแก้ไขปัญหานั้นและอัพเดตตัวเลขตามลำดับtraderemaฟังก์ชัน traderema () ไม่ทำงานอย่างถูกต้อง มันคำนวณเพียงเฉลี่ยของรายการงวดล่าสุด ทำตามรหัสต่อไปนี้สำหรับ traderema: function EMACalculator (array, array) EMApreviousday array0 printr (array) multiplier1 (2limit1) EMAarray () อาร์เรย์ EMA1 ปิดอาร์เรย์ 1 ในขณะที่ (จำกัด ) echoEMA คือ EMAn EMAp (EMApreviousday) multiplier1 EMApreviousday EMApreviousday EMA limit - - กลับ EMA ที่ขีด จำกัด ยอมรับระยะเวลาของ ema และอาร์เรย์ ยอมรับอาร์เรย์ของข้อมูลสำหรับการคำนวณ ema แต่น่าเสียดายที่รหัสที่แสดงจะมีข้อบกพร่องที่สำคัญสองข้อเนื่องจากวิธีการเก็บค่าเฉลี่ยเป็นจำนวนเต็ม หากต้องการดูตัวเลือกนี้ให้เลือก alpha เป็น 1024 เราเริ่มต้นด้วย adcvalue 0 จากนั้น dspemai32 จะคืนค่า 0 ตามที่คาดไว้ จากนั้นเพิ่มค่า adcvalue เป็น 1 tmp0 ใน dspemai32 จะเป็น: tmp0 (int64t) 1 (1024) (int64t) 0 (65536 - 1024) 1024 0 64512 1024 ดังนั้นค่าที่ส่งคืนคือ: (int32t) ((tmp0 32768) 65536) ( 1024 32768) 65536 33792 65536 0 ดังนั้น dspemai32 จะเก็บไว้ในคืน 0 ในขณะที่ควร (หลังจากเวลากรองยาวพอ) ในการส่งกลับสิ้นสุด 1 รหัสได้อย่างมีประสิทธิภาพดำเนินการตัวกรองที่มีเขตตายไม่เปลี่ยนจนกว่าอินพุทจะแตกต่างจาก เฉลี่ยโดย 32768alpha หรือมากกว่าหรือแตกต่างกันไปโดย - (32768alpha) หรือน้อยกว่า จากตัวอย่างข้างต้นให้เพิ่ม adcvalue เป็น 31 (ซึ่งน้อยกว่า 32768alpha) tmp0 ใน dspemai32 จะเป็น: tmp0 (int64t) 31 (1024) (int64t) 0 (65536 - 1024) 31744 0 64512 31744 ดังนั้นค่าที่ส่งคืนคือ: (int32t) ((tmp0 32768) 65536) (31744 32768) 65536 64512 65536 0 ดังนั้น dspemai32 จะเก็บไว้เมื่อกลับ 0 เมื่อเพิ่ม adcvalue ถึง 32 แทน tmp0 ใน dspemai32 จะเป็น: tmp0 (int64t) 32 (1024) (int64t) 0 (65536 - 1024) 32768 0 64512 32768 ดังนั้นค่าที่ส่งคืนคือ: ( int32t) ((tmp0 32768) 65536) (32768 32768) 65536 65536 65536 1 อย่างน้อยค่าเฉลี่ยกำลังเคลื่อนที่ไปที่ค่าอินพุทเป็น 1 นั่นเป็นสิ่งที่ดี แต่แล้ว: tmp0 (int64t) 32 (1024) (int64t) 1 (65536 - 1024) 32768 1 64512 97280 ดังนั้นค่าที่ส่งคืนคือ: (int32t) ((tmp0 97280) 65536) (97280 32768) 65536 130048 65536 1 ดังนั้น dspemai32 จะกลับมา 1 ไม่เคยถึงค่า input ของ 32 ไม่ดี ข้อผิดพลาดที่สองคือการหารจำนวนเต็ม (tmp0 32768) 65536 ใน C C การหารจำนวนเต็มจะไปถึง 0 ดังนั้นในสถานการณ์นั้นเขตตายจะมีขนาดใหญ่กว่า ดีกว่า (และง่ายกว่ามาก) คืออัลกอริทึมที่แสดงโดย david. prentice ใน avrfreakscomment824765comment-824765: ยาวรวม 0 int ค่าเฉลี่ย 0 int N 0 จำนวนที่ใช้งานของกลุ่มตัวอย่าง รวม ADCW เพิ่มการทำงานทั้งหมดถ้า (N gt MAXSAMPLES) จำนวนตัวอย่างทั้งหมด - เฉลี่ยลบจำนวนเต็ม N หนึ่งจำนวนเต็มรวมทั้งหมด

No comments:

Post a Comment