لائیو آپشنز کا تجزیہ مسلسل بدل رہا ہے۔ مضمر اتار چڑھاؤ، چکنائی کے بڑھنے، اور سطح کی ظاہری شکل میں تبدیلیاں چند منٹوں کے بعد بھی مختلف نظر آ سکتی ہیں۔
تاہم، بہت سی ٹیمیں اب بھی ان نمبروں کے ساتھ ایسا سلوک کرتی ہیں جیسے وہ سب ایک ساتھ دیکھے گئے ہوں۔ یہ ڈیک کا اسکرین شاٹ ہے۔ یہ ایک ڈسپوزایبل لیپ ٹاپ سیل ہے۔ میٹنگ سے پہلے UI کو جلدی سے چیک کریں۔
یہ اس وقت تک کام کرتا ہے جب تک کہ آپ کو بنیادی سوالات کے جوابات دینے کی ضرورت نہ ہو جو آپ کے اصل ورک فلو میں ظاہر ہوتے ہیں۔
TSLA کی سطح 10:32 پر کیسی نظر آتی تھی؟ ترچھی کب سے کھڑی بدلنے لگی۔ تبدیلی پنکھوں کے ہلنے سے آئی یا اے ٹی ایم چلنے سے؟
اگر آپ ڈیٹا کے آنے پر اسے محفوظ نہیں کرتے ہیں، تو آپ اس ڈیٹا کو دوبارہ نہیں چلا سکتے، اس کا موازنہ یا آڈٹ نہیں کر سکتے۔ آپ اس وقت جو کچھ بھی دیکھنے کو ہوا اس میں پھنس گئے ہیں۔
اس مشق میں، ہم کچھ چھوٹی لیکن عملی بنائیں گے۔ یعنی، ایک اندرونی ڈیٹا بیس جو SpiderRock MLink کے TSLA کے LiveImpliedQuote تجزیہ کو مسلسل حاصل کرتا ہے، ہر اسنیپ شاٹ کو قابل استفسار تاریخ کے طور پر اسٹور کرتا ہے، اور "تازہ ترین منظر” ٹیبل کو برقرار رکھتا ہے تاکہ موجودہ سطح کے حالات پوری تاریخ کو اسکین کیے بغیر حاصل کیے جا سکیں۔
مقصد تجارتی نظام بنانا نہیں ہے۔ یہ قابل اعتماد داخلی ڈیٹا سیٹ بنانے کے بارے میں ہے جس کی آپ نگرانی اور استفسار کر سکتے ہیں۔
نوٹ: SpiderRock MLink کا LiveImpliedQuote تجزیہ ایک ادا شدہ پروڈکٹ ہے، جس میں اس کی تخلیق میں استعمال ہونے والے بنیادی مارکیٹ ڈیٹا کے لیے ایکسچینج فیس شامل ہے۔
انڈیکس
شرطیں
اس واک تھرو میں کوڈ چلانے سے پہلے آپ کو کچھ چیزیں تیار کرنے کی ضرورت ہے۔
API کی طرف، آپ کو LiveImpliedQuote فیڈ تک رسائی کے ساتھ SpiderRock MLink اکاؤنٹ کی ضرورت ہوگی۔ مثال ایک REST انٹرفیس کا استعمال کرتی ہے لہذا کسی WebSocket سیٹ اپ کی ضرورت نہیں ہے، لیکن ایک درست API کلید درکار ہے۔ اگر آپ کے پاس پہلے سے کوئی اکاؤنٹ نہیں ہے، تو آپ SpiderRock سے براہ راست رابطہ کر کے اس تک رسائی حاصل کر سکتے ہیں۔
ازگر کی طرف، ماحول کم سے کم ہے۔ فنکشن کے دستخطوں میں سے ایک میں استعمال ہونے والے ٹیوپل قسم کے اشارے کی ترکیب کے لیے Python 3.10 یا اس سے زیادہ کی ضرورت ہوتی ہے۔ بیرونی پیکیجز درخواست، پانڈا، نمپی، اور میٹپلوٹلیب ہیں۔ باقی سب کچھ (sqlite3, time, datetime) معیاری لائبریری کا حصہ ہے۔ آپ استعمال کرتے ہوئے بیرونی انحصار انسٹال کر سکتے ہیں:
pip install requests pandas numpy matplotlib
مقامی تحریری راستے کے علاوہ کسی ڈیٹا بیس سیٹ اپ کی ضرورت نہیں ہے۔ SQLite پہلی بار جب آپ اسے چلاتے ہیں تو خود بخود فائلیں بناتا ہے، لہذا آپ کو اسے الگ سے انسٹال یا کنفیگر کرنے کی ضرورت نہیں ہے۔
آخر میں، مشق TSLA کو ہدف کی علامت کے طور پر استعمال کرتی ہے کیونکہ ایک مائع اور فعال اختیارات کا سلسلہ موجود ہے۔ اسے مختلف بنیاد سے تبدیل کرنے کے لیے، کنفیگریشن بلاک میں صرف علامت متغیر کو تبدیل کریں۔
ہم کون سا ڈیٹا استعمال کرتے ہیں۔
یہ تعمیر SpiderRock MLink کی طرف سے ایک OptAnalytics پیغام کی قسم سے تقویت یافتہ ہے۔ ریئل ٹائم مضمر اقتباس.
ہر پیغام اختیارات کے معاہدے کی نمائندگی کرتا ہے اور ان تجزیات کے ساتھ آتا ہے جس کی آپ کو عملی طور پر نگرانی کرنے کی ضرورت ہوتی ہے۔
-
آپشن شناخت کنندہ (علامت، میعاد ختم ہونے، ہڑتال، کال یا ڈال)
-
سطح IV (sVol) اور متعلقہ سطحی فیلڈز
-
یونانی (ڈیلٹا، گاما، تھیٹا، ویگا)
-
سیاق و سباق کے شعبے جیسے بنیادی قیمت (uPrc)، میعاد ختم ہونے کا وقت (سال)، شرح (ریٹ)
-
لائیو فیڈ کو ڈیٹا بیس میں تبدیل کرتے وقت اہم ٹائم اسٹیمپ اور کیلکولیشن سورس مارکر
ہم مضمون میں sVol کو اہم اتار چڑھاؤ والے فیلڈ کے طور پر مانیں گے اور اسے سرفیس IV کہیں گے۔ مسکراہٹوں کو دوبارہ لکھتے وقت یا محفوظ کردہ ریکارڈز سے تعصب پراکسی کا حساب لگاتے وقت یہ ورک فلو کی مستقل مزاجی کو برقرار رکھتا ہے۔
ڈیمو TSLA کا استعمال کرتا ہے کیونکہ اس میں ایک بھرپور اور فعال آپشن چین ہے، جو مختصر کیپچر ونڈوز کے ساتھ بھی ڈیٹا بیس اور سوالات کو مزید دلچسپ بناتا ہے۔ یہی پائپ لائن دیگر قدیموں کے لیے بھی کام کرتی ہے۔ صرف ایک چیز جو بدلتی ہے وہ علامت فلٹر ہے۔
ترتیبات: پیکجز درآمد کریں۔
ڈیٹا بیس یا APIs کو چھونے سے پہلے ایک چھوٹا، دوبارہ قابل دہرایا جانے والا ماحول ترتیب دیں۔ اس حصے کو جان بوجھ کر کم سے کم رکھا گیا ہے۔ یہ صرف وہی درآمد کرتا ہے جو اسے تین چیزیں کرنے کی ضرورت ہوتی ہے: REST کال کرنا، SQLite میں ڈیٹا اسٹور کرنا، اور بنیادی تجزیہ اور پلاٹ انجام دینا۔
import requests
import sqlite3
import pandas as pd
import numpy as np
import time
from datetime import datetime, timezone
import matplotlib.pyplot as plt
plt.style.use('ggplot')
-
requestsMLink REST اینڈ پوائنٹ کو کال کرنے کے لیے استعمال کیا جاتا ہے۔ -
sqlite3ایک ہلکا پھلکا ڈیٹا بیس فراہم کرتا ہے جسے بغیر کسی اضافی سیٹ اپ کے مقامی طور پر لکھا جا سکتا ہے۔ -
pandasاورnumpyڈیٹا کو واپس آنے کے بعد اسے صرف شکل دینے اور فلٹر کرنے کے لیے استعمال کیا جاتا ہے۔ -
timeاورdatetimeپولنگ لوپ چلا کر اور ہر اسنیپ شاٹ کو ٹائم سٹیمپ لگا کر اپنے ڈیٹا بیس کو ریئل ٹائم سیریز بننے میں مدد کریں۔
ڈیٹا بیس ڈیزائن
اگر آپ کا مقصد حقیقی وقت کے تجزیات کو قابل استفسار بنانا ہے، تو آپ کے ڈیٹا بیس کے ڈیزائن کو دو تقاضوں کی حمایت کرنی چاہیے:
سب سے پہلے، آپ کو ایک آڈٹ ٹریل کی ضرورت ہے. تمام سنیپ شاٹس کو محفوظ کیا جانا چاہیے تاکہ ہم اس کی تشکیل نو کر سکیں کہ ایک مخصوص وقت پر سطح کیسی نظر آتی تھی۔
دوسرا، آپ کو فوری جواب دینے کے لیے ایک طریقہ درکار ہے "اب یہ کیسا لگتا ہے؟” آپ کی محفوظ کردہ ہر چیز کو تلاش کیے بغیر۔
تو ہم دو میزیں استعمال کرتے ہیں۔
-
implied_quote_history: صرف شامل کریں۔ ہر سروے ایک مکمل سنیپ شاٹ داخل کرتا ہے۔ -
implied_quote_latest: ایک قطار فی اختیار معاہدہ۔ ہر پول اس ٹیبل کو اپ ڈیٹ کرتا ہے لہذا یہ ہمیشہ تازہ ترین سنیپ شاٹ کی عکاسی کرتا ہے۔
دونوں جدولوں کے مرکز میں مستحکم آپشن شناخت کنندہ ہیں۔ فیڈ میں نیسٹڈ آپشن کیز ہیں، اس لیے ہم انہیں ایک ہی کلید پر نارملائز کرتے ہیں۔ option_key ایک سٹرنگ جس میں علامت، میعاد ختم ہونے، اسٹرائیک پرائس، کال یا پوٹ، اور فیلڈز شامل ہیں۔ یہ تازہ ترین جدول کی بنیادی کلید اور استفسار کی بنیادی شمولیت کی کلید ہوگی۔
#config
api_key = "YOUR SPIDERROCK API KEY"
mlink_url = "https://mlink-live.nms.saturn.spiderrockconnect.com/rest/json"
msg_type = "LiveImpliedQuote"
symbol = "TSLA"
poll_interval_s = 10
poll_duration_s = 120
limit = 2000
#create db connection
db_path = "/mnt/data/optanalytics_iv_greeks.db"
def get_conn(path: str = db_path):
conn = sqlite3.connect(path)
conn.execute("PRAGMA journal_mode=WAL;")
conn.execute("PRAGMA synchronous=NORMAL;")
return conn
#create db schema
def setup_db(path: str = db_path):
conn = get_conn(path)
cur = conn.cursor()
cur.execute("""
create table if not exists implied_quote_history (
id integer primary key autoincrement,
asof_ts text not null,
option_key text not null,
symbol text not null,
expiry text not null,
strike real not null,
cp text not null,
calc_source text,
u_prc real,
years real,
rate real,
s_vol real,
atm_vol real,
s_mark real,
o_bid real,
o_ask real,
o_bid_iv real,
o_ask_iv real,
delta real,
gamma real,
theta real,
vega real,
src_ts text
);
""")
cur.execute("""
create index if not exists idx_hist_symbol_expiry_asof
on implied_quote_history(symbol, expiry, asof_ts);
""")
cur.execute("""
create index if not exists idx_hist_option_asof
on implied_quote_history(option_key, asof_ts);
""")
cur.execute("""
create table if not exists implied_quote_latest (
option_key text primary key,
last_asof_ts text not null,
symbol text not null,
expiry text not null,
strike real not null,
cp text not null,
calc_source text,
u_prc real,
years real,
rate real,
s_vol real,
atm_vol real,
s_mark real,
o_bid real,
o_ask real,
o_bid_iv real,
o_ask_iv real,
delta real,
gamma real,
theta real,
vega real,
src_ts text
);
""")
cur.execute("""
create index if not exists idx_latest_symbol_expiry
on implied_quote_latest(symbol, expiry);
""")
conn.commit()
conn.close()
setup_db()
یہ ایک SQLite ڈیٹا بیس فائل اور دونوں میزیں بنائے گا۔ ہسٹری ٹیبل صرف ضمیمہ کے لیے ہے اور ان دو سوالات کے لیے ترتیب دیا گیا ہے جنہیں آپ بعد میں چلائیں گے: میعاد ختم ہونے اور وقت کے حساب سے سنیپ شاٹس حاصل کریں، اور مخصوص اختیارات کے لیے ٹائم لائن حاصل کریں۔ option_key. تازہ ترین جدول کی کلیدیں یہ ہیں: option_keyیہ آپ کو ایک مستقل "موجودہ منظر” کو اپ ڈیٹ کرنے اور برقرار رکھنے کی اجازت دیتا ہے۔
ہم جس گرمی کو ذخیرہ کرتے ہیں وہ جان بوجھ کر خود راست ہے۔ یہ سطح IV (s_vol)، سطحی نشان (s_mark)، یونانی حروف، اور کئی سیاق و سباق کے شعبوں کو برقرار رکھتا ہے۔ ہم ایک ٹائم اسٹیمپ بھی اسٹور کرتے ہیں تاکہ ہم بعد میں اندازہ لگا سکیں کہ ویلیو کب بنائی گئی تھی۔
LiveImpiedQuote حاصل کریں۔
اب آئیے اپنی پہلی لائیو پل کرتے ہیں۔ یہاں مقصد کامل فلٹر بنانا نہیں ہے۔ مقصد یہ ہے کہ TSLA اختیارات کے تجزیے کے معنی خیز حصوں کو بازیافت کرنے کے قابل ہو اور اس بات کو یقینی بنائے کہ ردعمل کا ڈھانچہ ہماری توقع کے مطابق ہو۔
ایک LiveImpliedQuote کی درخواست کریں اور علامت کے لحاظ سے فلٹر کرنے کے لیے جہاں شق کا استعمال کریں۔ جواب ایک فہرست ہے جہاں زیادہ تر قطاریں حقیقی LiveImpliedQuote پیغامات ہیں اور آخر میں ایک قطار QueryResult کا خلاصہ ہے۔
def fetch_live_implied_quote(symbol: str, limit: int = 2000):
where = f"okey.tk:eq:{symbol}"
params = {
"apiKey": api_key,
"cmd": "getmsgs",
"msgType": msg_type,
"where": where,
"limit": limit
}
r = requests.get(mlink_url, params=params)
r.raise_for_status()
return r.json()
raw = fetch_live_implied_quote(symbol, limit=limit)
print("raw messages:", len(raw))
print("first type:", raw[0].get("header", {}).get("mTyp") if raw else None)
یہ آرام ہے۔ getmsgs کال اپنی API کلید، پیغام کی قسم، اور سادہ علامت کا فلٹر پاس کریں۔ کہ limit یہ ضروری ہے۔ یہ ایک سروے سے واپس آنے والے پیغامات کی تعداد کو محدود کرتا ہے، لہذا فعال بنیادوں کے لیے، واپس کیے گئے انتباہات اور میعاد ختم ہونے کا سیٹ سروے سے سروے تک مختلف ہو سکتا ہے۔ یہ اس ٹیوٹوریل کے لیے ٹھیک ہے۔ کیونکہ مقصد ڈیٹا بیس کے نمونوں اور نگرانی کے سوالات کی اقسام کو ظاہر کرنا ہے جن کی وہ حمایت کرتے ہیں۔
یہ آؤٹ پٹ ہے جو آپ کو دیکھنا چاہئے:

قطاروں کے جواب کو معمول بنائیں
موجودہ خام نیسٹڈ میسج آبجیکٹ کی فہرست ہے۔ یہ فارمیٹ ٹرانسمیشن کے لیے موزوں ہے، لیکن یہ ایسا فارمیٹ نہیں ہے جسے براہ راست اسٹور یا استفسار کیا جا سکے۔ اب ہم ہر LiveImpliedQuote پیغام کو مستقل اسکیما کے ساتھ ایک فلیٹ قطار میں تبدیل کرتے ہیں۔
def make_option_key(okey: dict) -> str:
return "|".join([
str(okey.get("tk")),
str(okey.get("dt")),
str(okey.get("xx")),
str(okey.get("cp")),
str(okey.get("at")),
str(okey.get("ts")),
])
def normalize_liq(raw: list, asof_ts: str, keep_calc_source: str = "Loop") -> pd.DataFrame:
rows = []
for row in raw:
if row.get("header", {}).get("mTyp") != "LiveImpliedQuote":
continue
m = row.get("message", {})
if keep_calc_source and m.get("calcSource") != keep_calc_source:
continue
pkey = m.get("pkey", {})
okey = pkey.get("okey", {})
if not okey:
continue
s_vol = m.get("sVol")
if s_vol is None or s_vol == 0:
continue
o_bid = m.get("oBid", 0) or 0
o_ask = m.get("oAsk", 0) or 0
quote_ok = int(not (o_bid == 0 and o_ask == 0))
rows.append({
"asof_ts": asof_ts,
"option_key": make_option_key(okey),
"symbol": okey.get("tk"),
"expiry": okey.get("dt"),
"strike": okey.get("xx"),
"cp": okey.get("cp"),
"calc_source": m.get("calcSource"),
"u_prc": m.get("uPrc"),
"years": m.get("years"),
"rate": m.get("rate"),
"s_vol": s_vol,
"atm_vol": m.get("atmVol"),
"s_mark": m.get("sMark"),
"o_bid": o_bid,
"o_ask": o_ask,
"o_bid_iv": m.get("oBidIv"),
"o_ask_iv": m.get("oAskIv"),
"quote_ok": quote_ok,
"delta": m.get("de"),
"gamma": m.get("ga"),
"theta": m.get("th"),
"vega": m.get("ve"),
"src_ts": m.get("timestamp"),
})
df = pd.DataFrame(rows)
if df.empty:
return df
df = (
df.sort_values("src_ts")
.drop_duplicates(subset=["option_key"], keep="last")
.reset_index(drop=True)
)
return df
asof_ts = datetime.now(timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z")
snapshot_df = normalize_liq(raw, asof_ts)
print("snapshot rows:", len(snapshot_df))
print("quote_ok distribution:", snapshot_df["quote_ok"].value_counts().to_dict() if not snapshot_df.empty else {})
snapshot_df.head()
معمول کے اس قدم میں تین عملی فیصلے شامل ہیں:
-
سب سے پہلے، ایک مستحکم عمارت بنائیں.
option_keyآپشن شناخت کنندہ میں تازہ ترین جدول کے لیے آپ کے پاس ایک مستقل بنیادی کلید ہوگی۔ -
دوسرا، ہم صرف
calcSource="Loop". ایک LiveImpliedQuote میں ٹک اور لوپ دونوں ریکارڈ شامل ہو سکتے ہیں۔ لوپ ریکارڈز اسنیپ شاٹ طرز کے تجزیہ میں زیادہ مستقل ہوتے ہیں کیونکہ بنیادی حوالہ قیمت پوری سطح پر مستحکم ہوتی ہے۔ -
تیسرا، جارحانہ فلٹرنگ سے بچیں۔ اس ڈیٹاسیٹ میں، ٹاپ آف دی بک بِڈ اور اسک فیلڈز 0 ہو سکتے ہیں چاہے اینالیٹکس فیلڈز آباد ہوں۔ لہذا اس قطار کو حذف کرنے کے بجائے
quote_okاسے جھنڈا لگائیں اور ریکارڈ رکھیں۔ یہ آپ کی پائپ لائن کو قابل استعمال بنائے گا جبکہ بعد میں یہ واضح کرے گا کہ کون سی قطاروں میں لائیو کوٹس ہیں۔
آؤٹ پٹ ہے:

اس مقام پر، ایک قطار ایک آپشن کنٹریکٹ سنیپ شاٹ کی نمائندگی کرتی ہے۔ حقیقت میں quote_ok مجموعی طور پر، 0 کا مطلب یہ ہے کہ اس ٹکڑے کے لیے بولیاں اور سوال نہیں کیے جائیں گے، چاہے سرفیس IV، چکنائی، اور دیگر تجزیہ کے شعبے ہوں۔ یہ اب بھی مانیٹرنگ ڈیٹا بیس بنانے کے لیے مفید ہے۔ کیونکہ یہاں کلیدی خیال ایک قابل عمل مارکیٹ کی تشکیل نو کرنا نہیں ہے، بلکہ وقت کے ساتھ تجزیہ کے ارتقاء کو ٹریک کرنا ہے۔
ڈیٹا بیس پر لکھیں
اب جب کہ ہمارے پاس کلین اسنیپ شاٹ ڈیٹا فریم ہے، کام اسے دو جگہوں پر برقرار رکھنا ہے۔
ہسٹری ٹیبل: سب کچھ شامل کریں۔ یہ ایک آڈٹ ریکارڈ ہے۔ تازہ ترین جدول: اوپر کی طرف سے option_key. یہ ایک فوری "موجودہ منظر” ہے۔
یہ علیحدگی وہی ہے جو ڈیٹا بیس کو مفید بناتی ہے۔ تاریخ آپ کو ماضی کے اسنیپ شاٹس کو دوبارہ تشکیل دینے کی اجازت دیتی ہے۔ تازہ ترین خصوصیات آپ کو ٹائم سیریز کو اسکین کیے بغیر "سطح اب کیسی دکھتی ہے” کا جواب دینے کی اجازت دیتی ہیں۔
def safe_add_column(table: str, col: str, col_type: str, path: str = db_path):
conn = get_conn(path)
cur = conn.cursor()
existing = [r[1] for r in cur.execute(f"PRAGMA table_info({table});").fetchall()]
if col not in existing:
cur.execute(f"ALTER TABLE {table} ADD COLUMN {col} {col_type};")
conn.commit()
conn.close()
safe_add_column("implied_quote_history", "quote_ok", "INTEGER")
safe_add_column("implied_quote_latest", "quote_ok", "INTEGER")
def write_snapshot_to_db(df: pd.DataFrame, path: str = db_path) -> tuple[int, int]:
if df.empty:
return 0, 0
conn = get_conn(path)
cur = conn.cursor()
cols = [
"asof_ts",
"option_key","symbol","expiry","strike","cp",
"calc_source","u_prc","years","rate",
"s_vol","atm_vol","s_mark",
"o_bid","o_ask","o_bid_iv","o_ask_iv",
"delta","gamma","theta","vega",
"quote_ok","src_ts"
]
for c in cols:
if c not in df.columns:
df[c] = None
insert_df = df[cols].copy()
cur.executemany(
"""
insert into implied_quote_history (
asof_ts,
option_key, symbol, expiry, strike, cp,
calc_source, u_prc, years, rate,
s_vol, atm_vol, s_mark,
o_bid, o_ask, o_bid_iv, o_ask_iv,
delta, gamma, theta, vega,
quote_ok, src_ts
) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""",
insert_df.itertuples(index=False, name=None)
)
history_inserted = cur.rowcount
cur.executemany(
"""
insert into implied_quote_latest (
option_key,
last_asof_ts, symbol, expiry, strike, cp,
calc_source, u_prc, years, rate,
s_vol, atm_vol, s_mark,
o_bid, o_ask, o_bid_iv, o_ask_iv,
delta, gamma, theta, vega,
quote_ok, src_ts
) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
on conflict(option_key) do update set
last_asof_ts=excluded.last_asof_ts,
symbol=excluded.symbol,
expiry=excluded.expiry,
strike=excluded.strike,
cp=excluded.cp,
calc_source=excluded.calc_source,
u_prc=excluded.u_prc,
years=excluded.years,
rate=excluded.rate,
s_vol=excluded.s_vol,
atm_vol=excluded.atm_vol,
s_mark=excluded.s_mark,
o_bid=excluded.o_bid,
o_ask=excluded.o_ask,
o_bid_iv=excluded.o_bid_iv,
o_ask_iv=excluded.o_ask_iv,
delta=excluded.delta,
gamma=excluded.gamma,
theta=excluded.theta,
vega=excluded.vega,
quote_ok=excluded.quote_ok,
src_ts=excluded.src_ts
""",
insert_df[[
"option_key","asof_ts","symbol","expiry","strike","cp",
"calc_source","u_prc","years","rate",
"s_vol","atm_vol","s_mark",
"o_bid","o_ask","o_bid_iv","o_ask_iv",
"delta","gamma","theta","vega",
"quote_ok","src_ts"
]].itertuples(index=False, name=None)
)
latest_upserted = cur.rowcount
conn.commit()
conn.close()
return history_inserted, latest_upserted
hist_n, latest_n = write_snapshot_to_db(snapshot_df)
print("history inserted:", hist_n)
print("latest upserted:", latest_n)
ہم بیچ لکھتے ہیں اس کا استعمال کرتے ہوئے: executemany یہ ہزاروں آپشن قطاروں کے ساتھ بھی اندراج کو تیز کرتا ہے۔ ریکارڈ داخل کرنا آسان ہے۔ جدید تحریریں SQLite upsert کلید کا استعمال کرتی ہیں۔ option_keyاس کا مطلب ہے کہ اگر کوئی معاہدہ پہلے سے ہی تازہ ترین جدول میں موجود ہے، تو اس کے فیلڈز کو تازہ ترین اسنیپ شاٹ کے ساتھ اوور رائٹ کر دیا جائے گا۔
آپ کو درج ذیل کو چیک کرنا چاہئے:

پہلی تحریر کے بعد، دونوں جدولوں میں قطاروں کی ایک ہی تعداد ہوگی۔ یہ متوقع ہے، کیونکہ تاریخ میں اب تک صرف ایک سنیپ شاٹ ہے۔ جیسے ہی آپ متعدد سنیپ شاٹس کو پولنگ کرنا شروع کرتے ہیں، ہسٹری ٹیبل ہر چکر کے ساتھ بڑھتا جاتا ہے، جب کہ تازہ ترین ٹیبل تقریباً یکساں رہتا ہے اور مسلسل اپ ڈیٹ ہوتا رہتا ہے۔
ایک مختصر پولنگ کیپچر چل رہا ہے۔
اس مقام پر، پائپ لائن ایک ہی سنیپ شاٹ کے لیے آخر سے آخر تک کام کرتی ہے۔ لیکن ڈیٹا بیس کا پورا نقطہ حقیقی وقت کے تجزیات کو ٹائم سیریز میں ترجمہ کرنا ہے۔ لہذا ہم ایک مختصر کیپچر ونڈو چلاتے ہیں اور یکے بعد دیگرے کئی سنیپ شاٹس محفوظ کرتے ہیں۔
یہ پروڈکشن شیڈولر نہیں ہے۔ یہ ایک سادہ لوپ ہے جو چند منٹوں تک چلتا ہے، ہر چند سیکنڈ میں پول کرتا ہے، اسنیپ شاٹ کو ٹائم اسٹیمپ کرتا ہے، اور اسے دونوں میزوں پر لکھتا ہے۔
def poll_and_write(symbol: str, duration_s: int = poll_duration_s, interval_s: int = poll_interval_s):
start = time.time()
polls = 0
total_hist = 0
while time.time() - start < duration_s:
asof_ts = datetime.now(timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z")
raw = fetch_live_implied_quote(symbol, limit=limit)
df = normalize_liq(raw, asof_ts)
hist_n, latest_n = write_snapshot_to_db(df)
polls += 1
total_hist += hist_n
print(f"[{polls}] {asof_ts} snapshot_rows={len(df)} history+={hist_n} latest_upsert={latest_n}")
time.sleep(interval_s)
print(f"done. polls={polls}, total_history_added={total_hist}")
poll_and_write(symbol, duration_s=120, interval_s=10)
ہر لوپ تکرار ایک سنیپ شاٹ کی نمائندگی کرتا ہے۔ ایک UTC ٹائم اسٹیمپ (asof_ts) بنائیں، LiveImpliedQuote سے تازہ ترین بیچ حاصل کریں، اسے قطاروں میں معمول بنائیں، اور اسے ڈیٹا بیس میں لکھیں۔ ہسٹری ٹیبل تمام سنیپ شاٹس کو جمع کرتا ہے۔ تازہ ترین جدول کو اس کے ساتھ اوور رائٹ کریں: option_key، لہذا یہ ہمیشہ تازہ ترین منظر کی نمائندگی کرتا ہے۔
ایک عملی تفصیل قابل ذکر ہے۔ چونکہ API کالز محدود ہیں، اس لیے اس بات کی کوئی گارنٹی نہیں ہے کہ آپ کو سروے سے سروے تک انتباہات اور میعاد ختم ہونے کا ایک ہی سیٹ موصول ہوگا۔ اسی لیے snapshot_rows یہ تکرار سے تکرار تک مختلف ہوسکتا ہے۔
پیداوار میں، ٹکڑوں کو عام طور پر ایک مخصوص میعاد ختم ہونے کی تاریخ اور اسٹرائیک بینڈ کو طے کرکے، یا IV کو ایک مقررہ کرنسی پوائنٹ پر انٹرپولیٹ کرکے مستحکم کیا جاتا ہے۔ اس ٹیوٹوریل میں، ہم مجموعہ کو آسان رکھتے ہیں اور ڈیٹا بیس کے نمونوں اور نگرانی کے سوالات پر توجہ مرکوز کرتے ہیں جن کی وہ حمایت کرتے ہیں۔
آپ کو ٹیلی میٹری بذریعہ پول اس طرح نظر آئے گا:
[1] 2026-04-14T18:09:29Z snapshot_rows=1454 history+=1454 latest_upsert=1454
...
done. polls=9, total_history_added=12806
یہ اس بات کی تصدیق کرتا ہے کہ ڈیٹا بیس ایک ٹائم سیریز بنا رہا ہے۔ 9 سے زیادہ سروے، ہم نے اپنے ریکارڈ میں 12,806 آپشن قطاریں محفوظ کیں۔ تازہ ترین جدول ہر بار اپ ڈیٹ کیا جاتا ہے، لیکن یہ تاریخ کی طرح بڑا نہیں ہوتا ہے کیونکہ اسے ہر معاہدے کی کلید کے ذریعے اوور رائٹ کیا جاتا ہے۔
اگلے حصے میں، ہم لکھنا بند کر دیں گے اور استفسار شروع کر دیں گے۔
تجزیہ: ڈیٹا بیس سے مائیکرو ری کنسٹرکشن
جب ڈیٹا آتا ہے۔ implied_quote_historyورک فلو الٹ ہے۔ ہم "API جوابات" کے لحاظ سے سوچنا چھوڑ دیتے ہیں اور "سوالات" کے لحاظ سے سوچنا شروع کر دیتے ہیں۔ یہ سیکشن دو کام کرتا ہے: پہلے، ایک میعاد ختم ہونے کا انتخاب کریں جس میں نمائندہ ہونے کے لیے کافی قطاریں ہوں۔ اس کے بعد ہم کئی ٹائم اسٹیمپ پر اس میعاد ختم ہونے کے لیے کال سائیڈ اتار چڑھاؤ والی مسکراہٹ کو دوبارہ تشکیل دیتے ہیں۔
اچھی کوریج کے ساتھ میعاد ختم ہونے کی تاریخ کا انتخاب کریں۔
مسکراہٹ پلاٹ گمراہ کن ہو سکتے ہیں اگر آپ ایک میعاد ختم ہونے کی تاریخ کا انتخاب کرتے ہیں جو صرف کیپچر کردہ سنیپ شاٹس میں وقفے وقفے سے ظاہر ہوتا ہے۔ لہذا، ہم تاریخ کے جدول میں سب سے زیادہ قطاروں والی میعاد ختم ہونے کی تاریخوں کو دیکھ کر شروعات کرتے ہیں۔
conn = get_conn()
expiry_counts = pd.read_sql_query(
"""
select expiry, count(*) as n
from implied_quote_history
where symbol = ?
group by expiry
order by n desc
limit 10
""",
conn,
params=(symbol,)
)
conn.close()
expiry_counts
یہ استفسار صرف ہسٹری ٹیبل کو اسکین کرتا ہے، TSLA کے ذریعے فلٹر کرتا ہے، اور کیپچر کی مدت میں فی میعاد ختم ہونے پر موجود آپشن قطاروں کی تعداد کو شمار کرتا ہے۔ سب سے اوپر 10 رکھیں اور دوبارہ ترتیب دینے کے لیے پہلے کو ختم ہونے کی تاریخ کے طور پر منتخب کریں۔

میعاد ختم ہونے کی تاریخ 2026-11-20 اس کی تعداد سب سے زیادہ ہے۔
یہاں گنتی کا مطلب یہ نہیں ہے کہ یہ میعاد ختم ہونے کی کسی بھی تجارتی معنوں میں "بہترین" ہے۔ اس کا مطلب ہے کہ یہ پکڑے گئے ڈیٹا میں سب سے زیادہ مستقل طور پر ظاہر ہوتا ہے۔ یہ صاف مسکراہٹ کے موازنہ کے لیے ایک عملی انتخاب بناتا ہے۔
سنیپ شاٹس میں اپنی مسکراہٹ کو دوبارہ ترتیب دیں۔
اب ہم ذخیرہ شدہ تاریخ سے ایک میعاد ختم ہونے کے لیے استفسار کرتے ہیں، صرف کالز کو برقرار رکھتے ہیں، اور متعدد سنیپ شاٹ ٹائم اسٹیمپ پر حملوں کے لیے سطح IV(s_vol)۔
chosen_expiry = "2026-11-20"
conn = get_conn()
smile = pd.read_sql_query(
"""
select asof_ts, strike, cp, s_vol, u_prc
from implied_quote_history
where symbol = ? and expiry = ?
""",
conn,
params=(symbol, chosen_expiry)
)
conn.close()
smile_calls = smile[smile["cp"] == "Call"].copy()
ts_list = sorted(smile_calls["asof_ts"].unique())
pick = [ts_list[0], ts_list[len(ts_list)//2], ts_list[-1]]
plt.figure(figsize=(9,5))
for ts in pick:
g = smile_calls[smile_calls["asof_ts"] == ts].sort_values("strike")
plt.plot(g["strike"], g["s_vol"], label=ts)
plt.title(f"{symbol} Vol Smile (Calls) | Expiry {chosen_expiry} | 3 snapshots")
plt.xlabel("Strike")
plt.ylabel("Implied Vol (s_vol)")
plt.grid(True)
plt.legend()
plt.show()
ہم تاریخ سے منتخب شدہ میعاد ختم ہونے کے لیے تمام قطاریں حاصل کرتے ہیں اور پھر کال کے ذریعے فلٹر کرتے ہیں تاکہ ہم پوٹ اور کال کی شکلوں کو مکس نہ کریں۔ پلاٹ کو پڑھنے میں آسان رکھنے کے لیے، ہم صرف تین اسنیپ شاٹس تیار کرتے ہیں۔ پہلا، درمیانی، آخری۔

شارٹ کیپچر ونڈوز میں، مسکراہٹیں اکثر اوور لیپ ہوتی ہیں۔ اس کا مطلب یہ نہیں کہ نظام کام نہیں کرتا۔ اس کا عام طور پر مطلب ہے کہ ان دو منٹوں کے دوران سطح زیادہ حرکت نہیں کرتی تھی۔ اہم حصہ یہ ہے کہ آپ صرف اپنے محفوظ کردہ ریکارڈز کا استعمال کرکے ان کی تشکیل نو اور موازنہ کرسکتے ہیں۔
جگہ کے ارد گرد زوم ان کریں
مکمل رینج کے پلاٹ ظاہری شکل کے لیے کارآمد ہیں، لیکن وہ ان علاقوں کے قریب چھوٹی تبدیلیوں کو چھپا سکتے ہیں جن کا لوگ واقعی خیال رکھتے ہیں۔ لہذا ہم بنیادی قیمت کے ارد گرد بینڈ کو بڑھاتے ہیں۔
s0 = float(smile_calls["u_prc"].dropna().median())
low, high = s0 * 0.6, s0 * 1.4
for ts in pick:
g = smile_calls[smile_calls["asof_ts"] == ts].sort_values("strike")
g = g[(g["strike"] >= low) & (g["strike"] <= high)]
plt.plot(g["strike"], g["s_vol"], label=ts)
plt.title(f"{symbol} Vol Smile (Calls) | Expiry {chosen_expiry} | zoomed")
plt.xlabel("Strike")
plt.ylabel("Implied Vol (s_vol)")
plt.grid(True)
plt.legend(fontsize=8)
plt.show()
ہم اپنے ذخیرہ شدہ ڈیٹا پر طاقتور اسپاٹ پراکسی استعمال کرتے ہیں۔ u_prc اسے قدر دیں اور پھر ہڑتال کو اس کے آس پاس کی حد میں رکھیں۔ مقصد درستگی نہیں ہے۔ یہ چارٹ کو پڑھنے میں آسانی پیدا کرنے اور اس بات کی نشاندہی کرنے کے لیے ہے کہ آیا ATM کے قریب کا علاقہ بہہ رہا ہے۔

یہاں تک کہ چھوٹی چھوٹی تبدیلیاں بھی قابل دید ہیں۔ یہی وجہ ہے کہ ریکارڈ اسٹوریج اہم ہے۔ اگر آپ تنہائی میں صرف ایک سنیپ شاٹ دیکھیں تو ان تبدیلیوں کو یاد کرنا یا نظر انداز کرنا آسان ہے۔
تجزیہ: ATM IV اور Skew over Time
مکمل مسکراہٹ والے پلاٹ مفید ہیں، لیکن یہ ہمیشہ کسی سطح کی نگرانی کا تیز ترین طریقہ نہیں ہوتے ہیں۔ عملی طور پر، ٹیمیں عام طور پر چند سمری نمبروں کو ٹریک کرتی ہیں کیونکہ وہ تبدیلیوں کو تیزی سے دیکھنے کے لیے ختم ہوتی ہیں اور پھر صرف اس صورت میں ڈرل ڈاؤن کرتی ہیں جب کوئی مسئلہ ہو۔
یہ ہر ایک ذخیرہ شدہ سنیپ شاٹ کو ایک میعاد ختم ہونے کے لیے دو میٹرکس تک کم کر دیتا ہے۔
-
ATM IV: نقطہ کے قریب ترین حملے کے مقام کی سطح IV۔
-
Skew Proxy: قریب ترین دستیاب ہٹ کا استعمال کرتا ہے، جو کہ 0.9x پوائنٹ پر سرفیس IV ہے مائنس سطح IV 1.1x پوائنٹ پر۔
chosen_expiry = "2026-11-20"
conn = get_conn()
df = pd.read_sql_query(
"""
select asof_ts, strike, s_vol, u_prc
from implied_quote_history
where symbol = ? and expiry = ? and cp = 'Call'
""",
conn,
params=(symbol, chosen_expiry)
)
conn.close()
df["strike"] = df["strike"].astype(float)
df["s_vol"] = df["s_vol"].astype(float)
def closest_iv(grp: pd.DataFrame, target_strike: float):
g = grp.iloc[(grp["strike"] - target_strike).abs().argsort()[:1]]
return float(g["s_vol"].iloc[0]), float(g["strike"].iloc[0])
rows = []
for ts, grp in df.groupby("asof_ts"):
spot = float(grp["u_prc"].dropna().median())
atm_target = spot
down_target = spot * 0.9
up_target = spot * 1.1
atm_iv, atm_k = closest_iv(grp, atm_target)
down_iv, down_k = closest_iv(grp, down_target)
up_iv, up_k = closest_iv(grp, up_target)
rows.append({
"asof_ts": ts,
"spot": spot,
"atm_strike": atm_k,
"atm_iv": atm_iv,
"k90": down_k,
"iv_90": down_iv,
"k110": up_k,
"iv_110": up_iv,
"skew_90_110": down_iv - up_iv
})
metrics = pd.DataFrame(rows).sort_values("asof_ts").reset_index(drop=True)
metrics
ایک میعاد ختم ہونے کے لیے ہسٹری ٹیبل سے استفسار کریں اور صرف کالز رکھیں، پھر انہیں سنیپ شاٹ ٹائم اسٹیمپ کے ذریعے گروپ کریں۔ ہم ہر اسنیپ شاٹ کے لیے میڈین استعمال کرتے ہیں۔ u_prc اسپاٹ پراکسی کے طور پر، ہم قریب ترین دستیاب حملے کا انتخاب کرتے ہیں۔ یہ ATM IV فراہم کرتا ہے۔ ہم 0.9x اسپاٹ اور 1.1x اسپاٹ کے لیے ایک ہی نقطہ نظر کو دہراتے ہیں اور تعصب پراکسی کو فرق کے طور پر شمار کرتے ہیں۔
ٹیبل استعمال شدہ اصل اسٹرائیک کو بھی اسٹور کرتا ہے (atm_strike, k90, k110)۔ چونکہ آپشن سٹرائیک کی قیمتیں الگ الگ ہیں، اس لیے قریبی سٹرائیک سنیپ شاٹس کے درمیان تبدیل ہو سکتی ہے۔ منتخب کردہ سٹرائیکس کو مرئی رکھنا آپ کو میٹرکس کی وضاحت کرنے کی اجازت دیتا ہے جب وہ حرکت کرتے ہیں۔
آؤٹ پٹ ایک ٹیبل ہے جس میں ایک قطار فی سنیپ شاٹ ٹائم اسٹیمپ اور حساب شدہ میٹرکس ہے۔

اب جب کہ ہمارے پاس کلین ٹائم سیریز ٹیبل ہے، ہم دونوں میٹرکس کو دیکھ سکتے ہیں۔ سب سے پہلے، ATM IV۔ پھر ایک متعصب پراکسی۔
plt.plot(metrics["asof_ts"], metrics["atm_iv"])
plt.title(f"{symbol} ATM IV over time | Expiry {chosen_expiry}")
plt.xticks(rotation=30, ha="right")
plt.ylabel("ATM IV (s_vol)")
plt.grid(True)
plt.show()
plt.plot(metrics["asof_ts"], metrics["skew_90_110"])
plt.title(f"{symbol} Skew proxy (IV@0.9S - IV@1.1S) | Expiry {chosen_expiry}")
plt.xticks(rotation=30, ha="right")
plt.ylabel("Skew proxy")
plt.grid(True)
plt.show()
یہ ہے پہلا چارٹ، ATM IV، وقت کے ساتھ۔

ATM IV مختصر وقت میں آہستہ آہستہ حرکت کرتا ہے جب تک کہ قیمت میں کوئی تیز اصلاحی واقعہ پیش نہ آئے۔ یہ اس دوڑ میں کافی مستحکم رہتا ہے، جو مختصر کیپچرز کے لیے ایک حقیقت پسندانہ نتیجہ ہے۔ یہاں قدر یہ ہے کہ یہ اس خیال کو تبدیل کرتا ہے کہ ڈیٹا بیس ایک مبہم تاثر سے "کافی مستحکم" ہے جس کا بعد میں مقدار اور موازنہ کیا جا سکتا ہے۔
یہ دوسرا چارٹ ہے، وقت کے ساتھ پراکسی سکیو۔

جھکاؤ پراکسی زیادہ حساس ہوتے ہیں کیونکہ وہ ونگ پوائنٹس پر مبنی ہوتے ہیں۔ اگر یہ بدل جاتا ہے، تو اس کا عام طور پر مطلب یہ ہوتا ہے کہ اس پختگی کے منفی پہلو کی قیمت الٹا سے مختلف ہوتی ہے۔ ایک لطیف فرق یہ ہے کہ قریب ترین دستیاب ہٹ سنیپ شاٹس کے درمیان تبدیل ہو سکتی ہے۔ جب سطح ڈرامائی طور پر حرکت نہ کر رہی ہو تب بھی یہ قدم قدم پر حرکت پیدا کر سکتا ہے۔ اسی لیے ہم اپنے میٹرکس ٹیبل میں k90 اور k110 رکھتے ہیں۔ تحریف کی سازش کو قابل وضاحت رکھتا ہے۔
الرٹ اسٹائل تھریشولڈ
ایک بار جب آپ کے پاس فی اسنیپ شاٹ میٹرکس کا ٹیبل ہو جائے تو، مانیٹرنگ پرت شامل کرنا آسان ہے۔ خیال وہ نہیں ہے جو ڈیل پیدا کرتا ہے۔ خیال اس وقت جھنڈا لگانا ہے جب سطح کسی کے قریب سے دیکھنے کے لیے کافی حرکت کرتی ہے۔
ہم یہاں دو چیک کرتے ہیں:
alerts = metrics.copy()
alerts["atm_iv_change"] = alerts["atm_iv"].diff()
alerts["skew_change"] = alerts["skew_90_110"].diff()
atm_thresh = 0.002
skew_thresh = 0.003
alerts["atm_alert"] = alerts["atm_iv_change"].abs() >= atm_thresh
alerts["skew_alert"] = alerts["skew_change"].abs() >= skew_thresh
alerts[[
"asof_ts",
"atm_iv", "atm_iv_change", "atm_alert",
"skew_90_110", "skew_change", "skew_alert",
"atm_strike", "k90", "k110"
]]
میٹرکس ٹیبل فی سنیپ شاٹ لے کر پہلے فرق کا حساب لگائیں۔ اس کے بعد یہ ان تبدیلیوں کا دہلیز سے موازنہ کرتا ہے اور بولین پرچم کو محفوظ کرتا ہے۔ آؤٹ پٹ ٹیبل حساب میں استعمال ہونے والے میٹرکس اور الرٹس دونوں کو برقرار رکھتا ہے، جس سے آپ بلیک باکس کے بجائے تمام انتباہات کا حساب لگا سکتے ہیں۔

اس دوڑ میں، ATM IV کی انتباہات تمام غلط ہیں، لیکن تعصب کی وارننگ ایک بار شروع ہو جاتی ہے۔
تعصب کی وارننگ اس لیے ہوتی ہے کیونکہ تعصب پراکسی دو سنیپ شاٹس کے درمیان حد سے زیادہ چھلانگ لگاتی ہے۔ یہ قابل وضاحت ہے۔ اگر آپ ٹیبل پر نظر ڈالتے ہیں، تو آپ دیکھ سکتے ہیں کہ پراکسیز کے لیے استعمال ہونے والی ہٹس اسی مدت کے دوران تبدیل ہوئی ہیں (k90 340 سے 315 تک چلا گیا)۔ چونکہ ہڑتال متواتر ہوتی ہے، اس لیے قریب ترین ہڑتال کے اشارے کو مرحلہ وار کیا جا سکتا ہے یہاں تک کہ جب سطح نمایاں طور پر حرکت نہ کر رہی ہو۔
اسے پڑھنے میں آسانی پیدا کرنے کے لیے، ہم سیریز اور نشان انتباہی پوائنٹس دونوں کو پلاٹ کرتے ہیں۔
plt.plot(alerts["asof_ts"], alerts["atm_iv"])
for i, r in alerts[alerts["atm_alert"]].iterrows():
plt.scatter(r["asof_ts"], r["atm_iv"], s=30, edgecolors="r", alpha=0.6, linewidth=2)
plt.title(f"{symbol} ATM IV with alerts | Expiry {chosen_expiry}")
plt.xticks(rotation=30, ha="right")
plt.grid(True)
plt.show()
plt.plot(alerts["asof_ts"], alerts["skew_90_110"])
for i, r in alerts[alerts["skew_alert"]].iterrows():
plt.scatter(r["asof_ts"], r["skew_90_110"], s=30, edgecolors="r", alpha=0.6, linewidth=2)
plt.title(f"{symbol} Skew proxy with alerts | Expiry {chosen_expiry}")
plt.xticks(rotation=30, ha="right")
plt.grid(True)
plt.show()
دونوں پلاٹ ایک ہی طرز کا استعمال کرتے ہیں۔ ہم میٹرک کو ایک لکیر کے طور پر کھینچتے ہیں اور پھر ٹائم اسٹیمپ پر ایک مارکر کو چڑھاتے ہیں جس پر متعلقہ انتباہی جھنڈا درست ہے۔ یہ اس وقت ظاہر ہوتا ہے جب کوئی چیز حد سے تجاوز کرتی ہے۔
یہ چارٹ ایک انتباہ کے ساتھ ایک متعصب پراکسی پیش کرتا ہے۔

یہ چارٹ ایک انتباہی علامت دکھاتا ہے جو آپ کے ٹیبل میں نظر آنے والی چیزوں سے ملتا ہے۔
ATM IV پلاٹ ظاہر نہیں کیا گیا ہے کیونکہ کوئی وارننگ پوائنٹس نہیں ہیں۔
ختم
اس مشق میں، ہم نے TSLA کے لیے SpiderRock MLink سے LiveImpliedQuote فیڈ کا استعمال کیا اور اسے ایک چھوٹے اندرونی ڈیٹا بیس میں تبدیل کر دیا جس سے ہم استفسار کر سکتے ہیں۔ ہم نے تمام سنیپ شاٹس کو صرف اپینڈ ہسٹری ٹیبل میں اسٹور کیا، تازہ ترین منظر کو ایک مستحکم آپشن شناخت کنندہ کے ذریعے کلید میں رکھا، اور پھر ذخیرہ شدہ ڈیٹا کو سمائلی کی تشکیل نو کے لیے استعمال کیا، ATM سطح IV اور ایک سادہ ڈسٹورشن پراکسی کو ٹریک کیا، اور پہلے سے طے شدہ الرٹ قواعد شامل کیے گئے۔
یہ B2B ورک فلو کے لیے بہترین فٹ ہے کیونکہ یہ ریئل ٹائم اینالیٹکس کو ڈیٹا سیٹس میں بدل دیتا ہے جن کا آڈٹ، دوبارہ چلایا اور نگرانی کی جا سکتی ہے۔ یہی پیٹرن لاگو ہوتا ہے چاہے آپ ایک اندرونی ڈیش بورڈ بنا رہے ہوں، اپنے ڈیسک کی سطح کی معمول کی جانچ کر رہے ہوں، یا اسکرین شاٹس اور ایک بار کے لیپ ٹاپ لانچوں پر انحصار کیے بغیر واقعہ کے بعد کا فوری جائزہ لے رہے ہوں۔
اگر آپ پیمانہ بنانا چاہتے ہیں تو، سب سے زیادہ عملی اگلا مرحلہ یہ ہے کہ SQLite سے Postgres کی طرف لمبے عرصے تک کیپچر ونڈوز، ایک سے زیادہ علامتوں کو ٹریک کرنے اور ڈیٹا والیوم میں اضافہ کرنے کے بعد۔ جب میٹرک استحکام اہم ہو جاتا ہے، تو ہو سکتا ہے کہ آپ ان ٹکڑوں کو معیاری بنانا چاہیں جنہیں آپ سروے کے ذریعے ٹریک کرتے ہیں یا حتیٰ کہ IV کو ایک مقررہ مالیاتی نقطہ پر انٹرپولیٹ کرنا چاہیں گے تاکہ قریب ترین واقعہ کی تبدیلی کے ساتھ اپنی پیمائش کو کم کرنے سے بچا جا سکے۔
یہ ہمیں مضمون کے آخری حصے تک لے جاتا ہے۔ مجھے امید ہے کہ آپ نے کچھ نیا اور مفید سیکھا ہوگا۔