การเรียนรู้การเปลี่ยนแปลงของตลาด: การแปลงการวิเคราะห์ต้นทุนธุรกรรมด้วยประวัติ Tick ที่แม่นยำเป็นพิเศษ – PCAP และ Amazon Athena สำหรับ Apache Spark | อเมซอนเว็บเซอร์วิส

การเรียนรู้การเปลี่ยนแปลงของตลาด: การแปลงการวิเคราะห์ต้นทุนธุรกรรมด้วยประวัติ Tick ที่แม่นยำเป็นพิเศษ – PCAP และ Amazon Athena สำหรับ Apache Spark | อเมซอนเว็บเซอร์วิส

โหนดต้นทาง: 3091357

โพสต์นี้เขียนร่วมกับ Pramod Nayak, LakshmiKanth Mannem และ Vivek Aggarwal จาก Low Latency Group ของ LSEG

การวิเคราะห์ต้นทุนธุรกรรม (TCA) ใช้กันอย่างแพร่หลายโดยเทรดเดอร์ ผู้จัดการพอร์ตโฟลิโอ และโบรกเกอร์สำหรับการวิเคราะห์ก่อนการซื้อขายและหลังการซื้อขาย และช่วยให้พวกเขาวัดและเพิ่มประสิทธิภาพต้นทุนการทำธุรกรรมและประสิทธิผลของกลยุทธ์การซื้อขายของพวกเขา ในโพสต์นี้ เราจะวิเคราะห์ตัวเลือก bid-ask สเปรดจาก ประวัติเห็บ LSEG – PCAP ชุดข้อมูลที่ใช้ Amazon Athena สำหรับ Apache Spark. เราแสดงวิธีการเข้าถึงข้อมูล กำหนดฟังก์ชันแบบกำหนดเองเพื่อใช้กับข้อมูล สืบค้นและกรองชุดข้อมูล และแสดงภาพผลลัพธ์ของการวิเคราะห์ ทั้งหมดนี้โดยไม่ต้องกังวลกับการตั้งค่าโครงสร้างพื้นฐานหรือกำหนดค่า Spark แม้แต่ชุดข้อมูลขนาดใหญ่ก็ตาม

พื้นหลัง

Options Price Reporting Authority (OPRA) ทำหน้าที่เป็นผู้ประมวลผลข้อมูลหลักทรัพย์ที่สำคัญ รวบรวม รวบรวม และเผยแพร่รายงานการขายล่าสุด ราคา และข้อมูลที่เกี่ยวข้องสำหรับ US Options ด้วยการแลกเปลี่ยนออปชั่นของสหรัฐฯ 18 แห่งและสัญญาที่เข้าเกณฑ์มากกว่า 1.5 ล้านสัญญา OPRA มีบทบาทสำคัญในการให้ข้อมูลตลาดที่ครอบคลุม

ในวันที่ 5 กุมภาพันธ์ 2024 บริษัท Securities Industry Automation Corporation (SIAC) ได้รับการตั้งค่าให้อัปเกรดฟีด OPRA จาก 48 ช่องเป็น 96 ช่องมัลติคาสต์ การปรับปรุงนี้มีจุดมุ่งหมายเพื่อเพิ่มประสิทธิภาพการกระจายสัญลักษณ์และการใช้กำลังการผลิตเพื่อตอบสนองต่อกิจกรรมการซื้อขายที่เพิ่มขึ้นและความผันผวนในตลาดออปชั่นของสหรัฐฯ SIAC แนะนำให้บริษัทต่างๆ เตรียมความพร้อมสำหรับอัตราข้อมูลสูงสุดที่ 37.3 GBits ต่อวินาที

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

OPRA โดดเด่นในฐานะฟีดที่มีปริมาณมากที่สุดรายการหนึ่ง โดยมียอดข้อความสูงสุด 150.4 พันล้านข้อความในวันเดียวในไตรมาสที่ 3 ปี 2023 และความต้องการความจุที่เหลือที่ 400 พันล้านข้อความภายในวันเดียว การบันทึกทุกข้อความเป็นสิ่งสำคัญสำหรับการวิเคราะห์ต้นทุนธุรกรรม การตรวจสอบสภาพคล่องของตลาด การประเมินกลยุทธ์การซื้อขาย และการวิจัยตลาด

เกี่ยวกับข้อมูล

ประวัติเห็บ LSEG – PCAP เป็นพื้นที่เก็บข้อมูลบนคลาวด์ที่มีขนาดเกิน 30 PB ซึ่งเป็นที่เก็บข้อมูลตลาดระดับโลกคุณภาพสูงเป็นพิเศษ ข้อมูลนี้จะถูกบันทึกอย่างพิถีพิถันโดยตรงภายในศูนย์ข้อมูลการแลกเปลี่ยน โดยใช้กระบวนการบันทึกข้อมูลซ้ำซ้อนซึ่งมีการวางตำแหน่งเชิงกลยุทธ์ในศูนย์ข้อมูลแลกเปลี่ยนหลักและสำรองที่สำคัญทั่วโลก เทคโนโลยีการจับภาพของ LSEG ช่วยให้มั่นใจในการเก็บข้อมูลโดยไม่สูญเสียข้อมูล และใช้แหล่งเวลา GPS เพื่อความแม่นยำในการประทับเวลาระดับนาโนวินาที นอกจากนี้ ยังมีการใช้เทคนิคการเก็งกำไรข้อมูลที่ซับซ้อนเพื่อเติมเต็มช่องว่างของข้อมูลอย่างราบรื่น ภายหลังการจับภาพ ข้อมูลจะผ่านการประมวลผลและการอนุญาโตตุลาการอย่างพิถีพิถัน จากนั้นจึงทำให้เป็นมาตรฐานในรูปแบบไม้ปาร์เก้โดยใช้ Ultra Direct แบบเรียลไทม์ของ LSEG (RTUD) ตัวจัดการฟีด

กระบวนการทำให้เป็นมาตรฐานซึ่งเป็นส่วนสำคัญในการเตรียมข้อมูลสำหรับการวิเคราะห์ จะสร้างไฟล์ Parquet ที่ถูกบีบอัดได้มากถึง 6 TB ต่อวัน ข้อมูลจำนวนมหาศาลเป็นผลมาจากลักษณะที่ครอบคลุมของ OPRA ซึ่งครอบคลุมการแลกเปลี่ยนหลายครั้ง และมีสัญญาออปชั่นมากมายที่มีลักษณะเฉพาะที่หลากหลาย ความผันผวนของตลาดที่เพิ่มขึ้นและกิจกรรมการสร้างตลาดในการแลกเปลี่ยนออปชันยังส่งผลต่อปริมาณข้อมูลที่เผยแพร่บน OPRA อีกด้วย

คุณลักษณะของ Tick History – PCAP ช่วยให้บริษัทสามารถทำการวิเคราะห์ต่างๆ ได้ รวมถึงสิ่งต่อไปนี้:

  • การวิเคราะห์ก่อนการซื้อขาย – ประเมินผลกระทบทางการค้าที่อาจเกิดขึ้นและสำรวจกลยุทธ์การดำเนินการที่แตกต่างกันตามข้อมูลในอดีต
  • การประเมินหลังการซื้อขาย – วัดต้นทุนการดำเนินการตามจริงเทียบกับเกณฑ์มาตรฐานเพื่อประเมินประสิทธิภาพของกลยุทธ์การดำเนินการ
  • ปลดข้อจำกัด การปฏิบัติ – ปรับแต่งกลยุทธ์การดำเนินการตามรูปแบบตลาดในอดีตเพื่อลดผลกระทบของตลาดและลดต้นทุนการซื้อขายโดยรวม
  • การบริหารความเสี่ยง – ระบุรูปแบบการเลื่อนไหล ระบุค่าผิดปกติ และจัดการความเสี่ยงที่เกี่ยวข้องกับกิจกรรมการซื้อขายในเชิงรุก
  • การระบุแหล่งที่มาของประสิทธิภาพ – แยกผลกระทบของการตัดสินใจซื้อขายออกจากการตัดสินใจลงทุนเมื่อวิเคราะห์ประสิทธิภาพของพอร์ตโฟลิโอ

ชุดข้อมูล LSEG Tick History – PCAP มีอยู่ใน การแลกเปลี่ยนข้อมูล AWS และสามารถเข้าถึงได้ที่ AWS Marketplace. ด้วย AWS Data Exchange สำหรับ Amazon S3คุณสามารถเข้าถึงข้อมูล PCAP ได้โดยตรงจาก LSEG บริการจัดเก็บข้อมูลอย่างง่ายของ Amazon (Amazon S3) ช่วยลดความจำเป็นสำหรับบริษัทต่างๆ ในการจัดเก็บสำเนาข้อมูลของตนเอง แนวทางนี้เพิ่มความคล่องตัวในการจัดการข้อมูลและการจัดเก็บข้อมูล ช่วยให้ลูกค้าเข้าถึง PCAP คุณภาพสูงหรือข้อมูลมาตรฐานได้ทันทีโดยใช้งานง่าย บูรณาการ และ ประหยัดพื้นที่จัดเก็บข้อมูลได้อย่างมาก.

เอเธน่าสำหรับ Apache Spark

สำหรับความพยายามในการวิเคราะห์ เอเธน่าสำหรับ Apache Spark มอบประสบการณ์โน้ตบุ๊กที่เรียบง่ายซึ่งสามารถเข้าถึงได้ผ่านคอนโซล Athena หรือ Athena API ซึ่งช่วยให้คุณสร้างแอปพลิเคชัน Apache Spark แบบโต้ตอบได้ ด้วยรันไทม์ Spark ที่ปรับให้เหมาะสม Athena จะช่วยวิเคราะห์ข้อมูลระดับเพตะไบต์โดยการปรับขนาดจำนวนเอ็นจิ้น Spark ที่น้อยกว่าหนึ่งวินาทีแบบไดนามิก ยิ่งไปกว่านั้น ไลบรารี Python ทั่วไป เช่น pandas และ NumPy ได้รับการผสานรวมอย่างลงตัว ซึ่งช่วยให้สามารถสร้างตรรกะแอปพลิเคชันที่ซับซ้อนได้ ความยืดหยุ่นขยายไปถึงการนำเข้าไลบรารีแบบกำหนดเองเพื่อใช้ในโน้ตบุ๊ก Athena สำหรับ Spark รองรับรูปแบบข้อมูลเปิดส่วนใหญ่ และผสานรวมเข้ากับรูปแบบได้อย่างราบรื่น AWS กาว แคตตาล็อกข้อมูล

ชุด

สำหรับการวิเคราะห์นี้ เราใช้ชุดข้อมูล LSEG Tick History – PCAP OPRA ตั้งแต่วันที่ 17 พฤษภาคม 2023 ชุดข้อมูลนี้ประกอบด้วยส่วนประกอบต่อไปนี้:

  • ราคาเสนอซื้อและข้อเสนอที่ดีที่สุด (BBO) – รายงานราคาเสนอสูงสุดและคำขอต่ำสุดเพื่อความปลอดภัยในการแลกเปลี่ยนที่กำหนด
  • การเสนอราคาและข้อเสนอที่ดีที่สุดระดับชาติ (NBBO) – รายงานราคาเสนอสูงสุดและคำขอต่ำสุดเพื่อความปลอดภัยในการแลกเปลี่ยนทั้งหมด
  • การซื้อขาย – บันทึกการซื้อขายที่เสร็จสมบูรณ์ในการแลกเปลี่ยนทั้งหมด

ชุดข้อมูลเกี่ยวข้องกับปริมาณข้อมูลต่อไปนี้:

  • การซื้อขาย – 160 MB กระจายอยู่ในไฟล์ Parquet ที่ถูกบีบอัดประมาณ 60 ไฟล์
  • บีบีโอ – 2.4 TB กระจายอยู่ในไฟล์ Parquet ที่ถูกบีบอัดประมาณ 300 ไฟล์
  • สพท – 2.8 TB กระจายอยู่ในไฟล์ Parquet ที่ถูกบีบอัดประมาณ 200 ไฟล์

ภาพรวมการวิเคราะห์

การวิเคราะห์ข้อมูลประวัติ OPRA Tick สำหรับการวิเคราะห์ต้นทุนธุรกรรม (TCA) เกี่ยวข้องกับการพิจารณาราคาตลาดและการซื้อขายตามเหตุการณ์การค้าที่เฉพาะเจาะจงอย่างละเอียด เราใช้ตัวชี้วัดต่อไปนี้เป็นส่วนหนึ่งของการศึกษานี้:

  • สเปรดที่เสนอราคา (QS) – คำนวณเป็นความแตกต่างระหว่าง BBO Ask และ BBO Bid
  • สเปรดที่มีประสิทธิภาพ (ES) – คำนวณเป็นส่วนต่างระหว่างราคาซื้อขายกับจุดกึ่งกลางของ BBO (BBO bid + (BBO Ask – BBO bid)/2)
  • สเปรดที่มีประสิทธิภาพ/เสนอราคา (EQF) – คิดตาม (ES/QS) * 100

เราคำนวณสเปรดเหล่านี้ก่อนการซื้อขายและเพิ่มเติมที่สี่ช่วงเวลาหลังการซื้อขาย (หลังจาก 1 วินาที 10 วินาที และ 60 วินาทีหลังการซื้อขาย)

กำหนดค่า Athena สำหรับ Apache Spark

หากต้องการกำหนดค่า Athena สำหรับ Apache Spark ให้ทำตามขั้นตอนต่อไปนี้:

  1. บนคอนโซล Athena ใต้ สมัครที่นี่ให้เลือก วิเคราะห์ข้อมูลของคุณโดยใช้ PySpark และ Spark SQL.
  2. หากนี่เป็นครั้งแรกที่คุณใช้ Athena Spark ให้เลือก สร้างเวิร์กกรุ๊ป.
  3. สำหรับ ชื่อเวิร์กกรุ๊ปธ กรอกชื่อคณะทำงาน เช่น tca-analysis.
  4. ตัว Vortex Indicator ได้ถูกนำเสนอลงในนิตยสาร เครื่องมือวิเคราะห์ เลือก Apache Spark.
  5. ตัว Vortex Indicator ได้ถูกนำเสนอลงในนิตยสาร การกำหนดค่าเพิ่มเติม ส่วนคุณสามารถเลือกได้ ใช้ค่าเริ่มต้น หรือให้กำหนดเอง AWS Identity และการจัดการการเข้าถึง บทบาท (IAM) และตำแหน่ง Amazon S3 สำหรับผลการคำนวณ
  6. Choose สร้างเวิร์กกรุ๊ป.
  7. หลังจากที่คุณสร้างเวิร์กกรุ๊ปแล้ว ให้ไปที่ โน๊ตบุ๊ค และเลือก สร้างสมุดบันทึก.
  8. ป้อนชื่อสมุดบันทึกของคุณ เช่น tca-analysis-with-tick-history.
  9. Choose สร้างบัญชีตัวแทน เพื่อสร้างสมุดบันทึกของคุณ

เปิดสมุดบันทึกของคุณ

หากคุณได้สร้างกลุ่มงาน Spark แล้ว ให้เลือก เปิดตัวแก้ไขสมุดบันทึก ภายใต้ สมัครที่นี่.


หลังจากที่สมุดบันทึกของคุณถูกสร้างขึ้น คุณจะถูกนำไปยังตัวแก้ไขสมุดบันทึกแบบโต้ตอบ


ตอนนี้เราสามารถเพิ่มและรันโค้ดต่อไปนี้ลงในสมุดบันทึกของเราได้

สร้างบทวิเคราะห์

ทำตามขั้นตอนต่อไปนี้เพื่อสร้างการวิเคราะห์:

  • นำเข้าไลบรารีทั่วไป:
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go

  • สร้างกรอบข้อมูลของเราสำหรับ BBO, NBBO และการซื้อขาย:
bbo_quote = spark.read.parquet(f"s3://<bucket>/mt=bbo_quote/f=opra/dt=2023-05-17/*")
bbo_quote.createOrReplaceTempView("bbo_quote")
nbbo_quote = spark.read.parquet(f"s3://<bucket>/mt=nbbo_quote/f=opra/dt=2023-05-17/*")
nbbo_quote.createOrReplaceTempView("nbbo_quote")
trades = spark.read.parquet(f"s3://<bucket>/mt=trade/f=opra/dt=2023-05-17/29_1.parquet")
trades.createOrReplaceTempView("trades")

  • ตอนนี้เราสามารถระบุการค้าเพื่อใช้สำหรับการวิเคราะห์ต้นทุนธุรกรรมได้:
filtered_trades = spark.sql("select Product, Price,Quantity, ReceiptTimestamp, MarketParticipant from trades")

เราได้รับผลลัพธ์ต่อไปนี้:

+---------------------+---------------------+---------------------+-------------------+-----------------+ 
|Product |Price |Quantity |ReceiptTimestamp |MarketParticipant| 
+---------------------+---------------------+---------------------+-------------------+-----------------+ 
|QQQ 230518C00329000|1.1700000000000000000|10.0000000000000000000|1684338565538021907,NYSEArca|
|QQQ 230518C00329000|1.1700000000000000000|20.0000000000000000000|1684338576071397557,NASDAQOMXPHLX|
|QQQ 230518C00329000|1.1600000000000000000|1.0000000000000000000|1684338579104713924,ISE|
|QQQ 230518C00329000|1.1400000000000000000|1.0000000000000000000|1684338580263307057,NASDAQOMXBX_Options|
|QQQ 230518C00329000|1.1200000000000000000|1.0000000000000000000|1684338581025332599,ISE|
+---------------------+---------------------+---------------------+-------------------+-----------------+

เราใช้ข้อมูลการค้าที่เน้นไว้สำหรับผลิตภัณฑ์การค้า (tp) ราคาซื้อขาย (tpr) และเวลาซื้อขาย (tt)

  • ที่นี่เราสร้างฟังก์ชันตัวช่วยจำนวนหนึ่งสำหรับการวิเคราะห์ของเรา
def calculate_es_qs_eqf(df, trade_price):
    df['BidPrice'] = df['BidPrice'].astype('double')
    df['AskPrice'] = df['AskPrice'].astype('double')
    df["ES"] = ((df["AskPrice"]-df["BidPrice"])/2) - trade_price
    df["QS"] = df["AskPrice"]-df["BidPrice"]
    df["EQF"] = (df["ES"]/df["QS"])*100
    return df

def get_trade_before_n_seconds(trade_time, df, seconds=0, groupby_col = None):
    nseconds=seconds*1000000000
    nseconds += trade_time
    ret_df = df[df['ReceiptTimestamp'] < nseconds].groupby(groupby_col).last()
    ret_df['BidPrice'] = ret_df['BidPrice'].astype('double')
    ret_df['AskPrice'] = ret_df['AskPrice'].astype('double')
    ret_df = ret_df.reset_index()
    return ret_df

def get_trade_after_n_seconds(trade_time, df, seconds=0, groupby_col = None):
    nseconds=seconds*1000000000
    nseconds += trade_time
    ret_df = df[df['ReceiptTimestamp'] > nseconds].groupby(groupby_col).first()
    ret_df['BidPrice'] = ret_df['BidPrice'].astype('double')
    ret_df['AskPrice'] = ret_df['AskPrice'].astype('double')
    ret_df = ret_df.reset_index()
    return ret_df

def get_nbbo_trade_before_n_seconds(trade_time, df, seconds=0):
    nseconds=seconds*1000000000
    nseconds += trade_time
    ret_df = df[df['ReceiptTimestamp'] < nseconds].iloc[-1:]
    ret_df['BidPrice'] = ret_df['BidPrice'].astype('double')
    ret_df['AskPrice'] = ret_df['AskPrice'].astype('double')
    return ret_df

def get_nbbo_trade_after_n_seconds(trade_time, df, seconds=0):
    nseconds=seconds*1000000000
    nseconds += trade_time
    ret_df = df[df['ReceiptTimestamp'] > nseconds].iloc[:1]
    ret_df['BidPrice'] = ret_df['BidPrice'].astype('double')
    ret_df['AskPrice'] = ret_df['AskPrice'].astype('double')
    return ret_df

  • ในฟังก์ชันต่อไปนี้ เราสร้างชุดข้อมูลที่มีราคาทั้งหมดก่อนและหลังการซื้อขาย Athena Spark จะกำหนดจำนวน DPU ที่จะเรียกใช้เพื่อประมวลผลชุดข้อมูลของเราโดยอัตโนมัติ
def get_tca_analysis_via_df_single_query(trade_product, trade_price, trade_time):
    # BBO quotes
    bbos = spark.sql(f"SELECT Product, ReceiptTimestamp, AskPrice, BidPrice, MarketParticipant FROM bbo_quote where Product = '{trade_product}';")
    bbos = bbos.toPandas()

    bbo_just_before = get_trade_before_n_seconds(trade_time, bbos, seconds=0, groupby_col='MarketParticipant')
    bbo_just_after = get_trade_after_n_seconds(trade_time, bbos, seconds=0, groupby_col='MarketParticipant')
    bbo_1s_after = get_trade_after_n_seconds(trade_time, bbos, seconds=1, groupby_col='MarketParticipant')
    bbo_10s_after = get_trade_after_n_seconds(trade_time, bbos, seconds=10, groupby_col='MarketParticipant')
    bbo_60s_after = get_trade_after_n_seconds(trade_time, bbos, seconds=60, groupby_col='MarketParticipant')
    
    all_bbos = pd.concat([bbo_just_before, bbo_just_after, bbo_1s_after, bbo_10s_after, bbo_60s_after], ignore_index=True, sort=False)
    bbos_calculated = calculate_es_qs_eqf(all_bbos, trade_price)

    #NBBO quotes
    nbbos = spark.sql(f"SELECT Product, ReceiptTimestamp, AskPrice, BidPrice, BestBidParticipant, BestAskParticipant FROM nbbo_quote where Product = '{trade_product}';")
    nbbos = nbbos.toPandas()

    nbbo_just_before = get_nbbo_trade_before_n_seconds(trade_time,nbbos, seconds=0)
    nbbo_just_after = get_nbbo_trade_after_n_seconds(trade_time, nbbos, seconds=0)
    nbbo_1s_after = get_nbbo_trade_after_n_seconds(trade_time, nbbos, seconds=1)
    nbbo_10s_after = get_nbbo_trade_after_n_seconds(trade_time, nbbos, seconds=10)
    nbbo_60s_after = get_nbbo_trade_after_n_seconds(trade_time, nbbos, seconds=60)

    all_nbbos = pd.concat([nbbo_just_before, nbbo_just_after, nbbo_1s_after, nbbo_10s_after, nbbo_60s_after], ignore_index=True, sort=False)
    nbbos_calculated = calculate_es_qs_eqf(all_nbbos, trade_price)

    calc = pd.concat([bbos_calculated, nbbos_calculated], ignore_index=True, sort=False)
    
    return calc

  • ตอนนี้เรามาเรียกใช้ฟังก์ชันการวิเคราะห์ TCA พร้อมข้อมูลจากการซื้อขายที่เราเลือก:
tp = "QQQ 230518C00329000"
tpr = 1.16
tt = 1684338579104713924
c = get_tca_analysis_via_df_single_query(tp, tpr, tt)

เห็นภาพผลการวิเคราะห์

ตอนนี้เรามาสร้างกรอบข้อมูลที่เราใช้สำหรับการแสดงภาพของเรากันดีกว่า แต่ละเฟรมข้อมูลมีเครื่องหมายคำพูดสำหรับหนึ่งในห้าช่วงเวลาสำหรับฟีดข้อมูลแต่ละรายการ (BBO, NBBO):

bbo = c[c['MarketParticipant'].isin(['BBO'])]
bbo_bef = bbo[bbo['ReceiptTimestamp'] < tt]
bbo_aft_0 = bbo[bbo['ReceiptTimestamp'].between(tt,tt+1000000000)]
bbo_aft_1 = bbo[bbo['ReceiptTimestamp'].between(tt+1000000000,tt+10000000000)]
bbo_aft_10 = bbo[bbo['ReceiptTimestamp'].between(tt+10000000000,tt+60000000000)]
bbo_aft_60 = bbo[bbo['ReceiptTimestamp'] > (tt+60000000000)]

nbbo = c[~c['MarketParticipant'].isin(['BBO'])]
nbbo_bef = nbbo[nbbo['ReceiptTimestamp'] < tt]
nbbo_aft_0 = nbbo[nbbo['ReceiptTimestamp'].between(tt,tt+1000000000)]
nbbo_aft_1 = nbbo[nbbo['ReceiptTimestamp'].between(tt+1000000000,tt+10000000000)]
nbbo_aft_10 = nbbo[nbbo['ReceiptTimestamp'].between(tt+10000000000,tt+60000000000)]
nbbo_aft_60 = nbbo[nbbo['ReceiptTimestamp'] > (tt+60000000000)]

ในส่วนต่อไปนี้ เราจะให้โค้ดตัวอย่างเพื่อสร้างการแสดงภาพที่แตกต่างกัน

พล็อต QS และ NBBO ก่อนการซื้อขาย

ใช้โค้ดต่อไปนี้เพื่อพล็อตสเปรดที่เสนอราคาและ NBBO ก่อนการซื้อขาย:

fig = px.bar(title="Quoted Spread Before The Trade",
    x=bbo_bef.MarketParticipant,
    y=bbo_bef['QS'],
    labels={'x': 'Market', 'y':'Quoted Spread'})
fig.add_hline(y=nbbo_bef.iloc[0]['QS'],
    line_width=1, line_dash="dash", line_color="red",
    annotation_text="NBBO", annotation_font_color="red")
%plotly fig

วางแผน QS สำหรับแต่ละตลาดและ NBBO หลังการซื้อขาย

ใช้โค้ดต่อไปนี้เพื่อพล็อตค่าสเปรดที่เสนอสำหรับแต่ละตลาดและ NBBO ทันทีหลังการซื้อขาย:

fig = px.bar(title="Quoted Spread After The Trade",
    x=bbo_aft_0.MarketParticipant,
    y=bbo_aft_0['QS'],
    labels={'x': 'Market', 'y':'Quoted Spread'})
fig.add_hline(
    y=nbbo_aft_0.iloc[0]['QS'],
    line_width=1, line_dash="dash", line_color="red",
    annotation_text="NBBO", annotation_font_color="red")
%plotly fig

พล็อต QS สำหรับแต่ละช่วงเวลาและแต่ละตลาดสำหรับ BBO

ใช้โค้ดต่อไปนี้เพื่อพล็อตสเปรดที่เสนอราคาสำหรับแต่ละช่วงเวลาและแต่ละตลาดสำหรับ BBO:

fig = go.Figure(data=[
    go.Bar(name="before trade", x=bbo_bef.MarketParticipant.unique(), y=bbo_bef['QS']),
    go.Bar(name="0s after trade", x=bbo_aft_0.MarketParticipant.unique(), y=bbo_aft_0['QS']),
    go.Bar(name="1s after trade", x=bbo_aft_1.MarketParticipant.unique(), y=bbo_aft_1['QS']),
    go.Bar(name="10s after trade", x=bbo_aft_10.MarketParticipant.unique(), y=bbo_aft_10['QS']),
    go.Bar(name="60s after trade", x=bbo_aft_60.MarketParticipant.unique(), y=bbo_aft_60['QS'])])
fig.update_layout(barmode='group',title="BBO Quoted Spread Per Market/TimeFrame",
    xaxis={'title':'Market'},
    yaxis={'title':'Quoted Spread'})
%plotly fig

พล็อต ES สำหรับแต่ละช่วงเวลาและตลาดสำหรับ BBO

ใช้โค้ดต่อไปนี้เพื่อพล็อตค่าสเปรดที่มีประสิทธิภาพสำหรับแต่ละช่วงเวลาและตลาดสำหรับ BBO:

fig = go.Figure(data=[
    go.Bar(name="before trade", x=bbo_bef.MarketParticipant.unique(), y=bbo_bef['ES']),
    go.Bar(name="0s after trade", x=bbo_aft_0.MarketParticipant.unique(), y=bbo_aft_0['ES']),
    go.Bar(name="1s after trade", x=bbo_aft_1.MarketParticipant.unique(), y=bbo_aft_1['ES']),
    go.Bar(name="10s after trade", x=bbo_aft_10.MarketParticipant.unique(), y=bbo_aft_10['ES']),
    go.Bar(name="60s after trade", x=bbo_aft_60.MarketParticipant.unique(), y=bbo_aft_60['ES'])])
fig.update_layout(barmode='group',title="BBO Effective Spread Per Market/TimeFrame",
    xaxis={'title':'Market'}, 
    yaxis={'title':'Effective Spread'})
%plotly fig

พล็อต EQF สำหรับแต่ละช่วงเวลาและตลาดสำหรับ BBO

ใช้โค้ดต่อไปนี้เพื่อพล็อตสเปรดที่มีประสิทธิผล/เสนอราคาสำหรับแต่ละช่วงเวลาและตลาดสำหรับ BBO:

fig = go.Figure(data=[
    go.Bar(name="before trade", x=bbo_bef.MarketParticipant.unique(), y=bbo_bef['EQF']),
    go.Bar(name="0s after trade", x=bbo_aft_0.MarketParticipant.unique(), y=bbo_aft_0['EQF']),
    go.Bar(name="1s after trade", x=bbo_aft_1.MarketParticipant.unique(), y=bbo_aft_1['EQF']),
    go.Bar(name="10s after trade", x=bbo_aft_10.MarketParticipant.unique(), y=bbo_aft_10['EQF']),
    go.Bar(name="60s after trade", x=bbo_aft_60.MarketParticipant.unique(), y=bbo_aft_60['EQF'])])
fig.update_layout(barmode='group',title="BBO Effective/Quoted Spread Per Market/TimeFrame",
    xaxis={'title':'Market'}, 
    yaxis={'title':'Effective/Quoted Spread'})
%plotly fig

ประสิทธิภาพการคำนวณ Athena Spark

เมื่อคุณเรียกใช้บล็อกโค้ด Athena Spark จะกำหนดจำนวน DPU ที่ต้องใช้โดยอัตโนมัติในการคำนวณให้เสร็จสิ้น ในบล็อกโค้ดสุดท้ายที่เราเรียกว่า tca_analysis เรากำลังสั่งให้ Spark ประมวลผลข้อมูล จากนั้นเราจะแปลงดาต้าเฟรม Spark ที่ได้ให้เป็นดาต้าเฟรมของ Pandas นี่ถือเป็นส่วนการประมวลผลที่เข้มข้นที่สุดของการวิเคราะห์ และเมื่อ Athena Spark รันบล็อกนี้ ก็จะแสดงแถบความคืบหน้า เวลาที่ผ่านไป และจำนวน DPU ที่กำลังประมวลผลข้อมูลในปัจจุบัน ตัวอย่างเช่น ในการคำนวณต่อไปนี้ Athena Spark ใช้ 18 DPU

เมื่อคุณกำหนดค่าโน้ตบุ๊ก Athena Spark คุณจะมีตัวเลือกในการตั้งค่าจำนวน DPU สูงสุดที่โน้ตบุ๊กสามารถใช้ได้ ค่าเริ่มต้นคือ 20 DPU แต่เราทดสอบการคำนวณนี้ด้วย 10, 20 และ 40 DPU เพื่อแสดงให้เห็นว่า Athena Spark ปรับขนาดโดยอัตโนมัติเพื่อดำเนินการวิเคราะห์ของเราอย่างไร เราสังเกตว่า Athena Spark ปรับขนาดเป็นเส้นตรง โดยใช้เวลา 15 นาที 21 วินาทีเมื่อโน้ตบุ๊กได้รับการกำหนดค่าด้วย DPU สูงสุด 10 DPU, 8 นาทีและ 23 วินาทีเมื่อโน้ตบุ๊กได้รับการกำหนดค่าด้วย 20 DPU และ 4 นาที 44 วินาทีเมื่อโน้ตบุ๊กถูกกำหนดค่า กำหนดค่าด้วย 40 DPU เนื่องจาก Athena Spark เรียกเก็บเงินตามการใช้งาน DPU ที่รายละเอียดต่อวินาที ค่าใช้จ่ายในการคำนวณเหล่านี้จึงใกล้เคียงกัน แต่หากคุณตั้งค่า DPU สูงสุดที่สูงกว่า Athena Spark ก็สามารถส่งกลับผลลัพธ์ของการวิเคราะห์ได้เร็วกว่ามาก สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับราคา Athena Spark กรุณาคลิก  โปรดคลิกที่นี่เพื่ออ่านรายละเอียดเพิ่มเติม.

สรุป

ในโพสต์นี้ เราได้สาธิตวิธีที่คุณสามารถใช้ข้อมูล OPRA ความเที่ยงตรงสูงจาก Tick History-PCAP ของ LSEG เพื่อทำการวิเคราะห์ต้นทุนธุรกรรมโดยใช้ Athena Spark ความพร้อมใช้งานของข้อมูล OPRA ในเวลาที่เหมาะสม เสริมด้วยนวัตกรรมการเข้าถึงของ AWS Data Exchange สำหรับ Amazon S3 ช่วยลดเวลาในการวิเคราะห์เชิงกลยุทธ์สำหรับบริษัทที่ต้องการสร้างข้อมูลเชิงลึกที่นำไปปฏิบัติได้สำหรับการตัดสินใจซื้อขายที่สำคัญ OPRA สร้างข้อมูล Parquet ที่ทำให้เป็นมาตรฐานประมาณ 7 TB ในแต่ละวัน และการจัดการโครงสร้างพื้นฐานเพื่อให้การวิเคราะห์ตามข้อมูล OPRA ถือเป็นเรื่องท้าทาย

ความสามารถในการปรับขนาดของ Athena ในการจัดการการประมวลผลข้อมูลขนาดใหญ่สำหรับ Tick History – PCAP สำหรับข้อมูล OPRA ทำให้เป็นตัวเลือกที่น่าสนใจสำหรับองค์กรที่กำลังมองหาโซลูชันการวิเคราะห์ที่รวดเร็วและปรับขนาดได้ใน AWS โพสต์นี้แสดงปฏิสัมพันธ์ที่ราบรื่นระหว่างระบบนิเวศ AWS และข้อมูล Tick History-PCAP และวิธีที่สถาบันการเงินสามารถใช้ประโยชน์จากการทำงานร่วมกันนี้เพื่อขับเคลื่อนการตัดสินใจที่ขับเคลื่อนด้วยข้อมูลสำหรับกลยุทธ์การซื้อขายและการลงทุนที่สำคัญ


เกี่ยวกับผู้เขียน

ปราโมทย์ นายัค เป็นผู้อำนวยการฝ่ายการจัดการผลิตภัณฑ์ของกลุ่ม Low Latency ที่ LSEG ปราโมดมีประสบการณ์มากกว่า 10 ปีในอุตสาหกรรมเทคโนโลยีทางการเงิน โดยมุ่งเน้นที่การพัฒนาซอฟต์แวร์ การวิเคราะห์ และการจัดการข้อมูล Pramod เป็นอดีตวิศวกรซอฟต์แวร์และหลงใหลเกี่ยวกับข้อมูลตลาดและการซื้อขายเชิงปริมาณ

ลักษมีคานธ์ มันเนม เป็นผู้จัดการผลิตภัณฑ์ในกลุ่ม Low Latency Group ของ LSEG เขามุ่งเน้นไปที่ผลิตภัณฑ์ข้อมูลและแพลตฟอร์มสำหรับอุตสาหกรรมข้อมูลตลาดที่มีความหน่วงต่ำ LakshmiKanth ช่วยให้ลูกค้าสร้างโซลูชันที่เหมาะสมที่สุดสำหรับความต้องการข้อมูลตลาดของตน

วิเวก อัคการ์วาล เป็นวิศวกรข้อมูลอาวุโสในกลุ่ม Low Latency Group ของ LSEG วิเวกทำงานเกี่ยวกับการพัฒนาและบำรุงรักษาท่อข้อมูลสำหรับการประมวลผลและการส่งมอบฟีดข้อมูลตลาดที่บันทึกไว้และฟีดข้อมูลอ้างอิง

อัลเก็ต เมมูชาจ เป็นสถาปนิกหลักในทีมพัฒนาตลาดบริการทางการเงินที่ AWS Alket รับผิดชอบด้านกลยุทธ์ทางเทคนิค โดยทำงานร่วมกับคู่ค้าและลูกค้าเพื่อปรับใช้แม้แต่ปริมาณงานตลาดทุนที่มีความต้องการมากที่สุดกับ AWS Cloud

ประทับเวลา:

เพิ่มเติมจาก AWS ข้อมูลขนาดใหญ่

เร่งความเร็วการเริ่มใช้งานและการผสานรวมอย่างราบรื่นกับ ThoughtSpot โดยใช้การผสานรวมพันธมิตร Amazon Redshift | บริการเว็บอเมซอน

โหนดต้นทาง: 2756605
ประทับเวลา: มิถุนายน 21, 2023

Amazon EMR Serverless รองรับขนาดผู้ปฏิบัติงานที่ใหญ่ขึ้นเพื่อเรียกใช้ปริมาณงานที่ใช้การประมวลผลและใช้หน่วยความจำมากขึ้น

โหนดต้นทาง: 1960703
ประทับเวลา: กุมภาพันธ์ 15, 2023