اہم مواد پر جائیں

ایتھیریم پر اپنا خود کا AI ٹریڈنگ ایجنٹ بنائیں

AI
ٹریڈنگ
ایجنٹ
python
متوسط
Ori Pomerantz
13 فروری، 2026
28 منٹ کی پڑھائی

اس ٹیوٹوریل میں آپ سیکھیں گے کہ ایک سادہ AI ٹریڈنگ ایجنٹ کیسے بنایا جائے۔ یہ ایجنٹ ان مراحل کا استعمال کرتے ہوئے کام کرتا ہے:

  1. کسی ٹوکن کی موجودہ اور ماضی کی قیمتیں پڑھیں، ساتھ ہی دیگر ممکنہ طور پر متعلقہ معلومات بھی
  2. اس معلومات کے ساتھ ایک سوال تیار کریں، پس منظر کی معلومات کے ساتھ یہ بتانے کے لیے کہ یہ کس طرح متعلقہ ہو سکتا ہے
  3. سوال جمع کریں اور ایک متوقع قیمت واپس حاصل کریں
  4. سفارش کی بنیاد پر ٹریڈ کریں
  5. انتظار کریں اور دہرائیں

یہ ایجنٹ ظاہر کرتا ہے کہ معلومات کو کیسے پڑھا جائے، اسے ایک ایسے سوال میں ترجمہ کیا جائے جو قابل استعمال جواب دے، اور اس جواب کا استعمال کیا جائے۔ یہ سب ایک AI ایجنٹ کے لیے درکار اقدامات ہیں۔ اس ایجنٹ کو Python میں لاگو کیا گیا ہے کیونکہ یہ AI میں استعمال ہونے والی سب سے عام زبان ہے۔

یہ کیوں کریں؟

خودکار ٹریڈنگ ایجنٹس ڈیولپرز کو ٹریڈنگ کی حکمت عملی منتخب کرنے اور اس پر عمل کرنے کی اجازت دیتے ہیں۔ AI ایجنٹس زیادہ پیچیدہ اور متحرک ٹریڈنگ حکمت عملیوں کی اجازت دیتے ہیں، ممکنہ طور پر ایسی معلومات اور الگورتھم کا استعمال کرتے ہوئے جن کے استعمال پر ڈیولپر نے غور بھی نہیں کیا ہے۔

ٹولز

یہ ٹیوٹوریل کوٹس اور ٹریڈنگ کے لیے Python (opens in a new tab)، Web3 لائبریری (opens in a new tab)، اور Uniswap v3 (opens in a new tab) کا استعمال کرتا ہے۔

Python کیوں؟

AI کے لیے سب سے زیادہ استعمال ہونے والی زبان Python (opens in a new tab) ہے، اس لیے ہم اسے یہاں استعمال کرتے ہیں۔ اگر آپ Python نہیں جانتے تو فکر نہ کریں۔ زبان بہت واضح ہے، اور میں بالکل بتاؤں گا کہ یہ کیا کرتی ہے۔

Web3 لائبریری (opens in a new tab) سب سے عام Python ایتھیریم API ہے۔ اسے استعمال کرنا بہت آسان ہے۔

بلاک چین پر ٹریڈنگ

بہت سے ڈسٹری بیوٹڈ ایکسچینجز (DEX) ہیں جو آپ کو ایتھیریم پر ٹوکنز ٹریڈ کرنے کی اجازت دیتے ہیں۔ تاہم، آربٹریج کی وجہ سے ان کی شرح تبادلہ ایک جیسی ہوتی ہے۔

Uniswap (opens in a new tab) ایک وسیع پیمانے پر استعمال ہونے والا DEX ہے جسے ہم کوٹس (ٹوکن کی نسبتی قدریں دیکھنے کے لیے) اور ٹریڈز دونوں کے لیے استعمال کر سکتے ہیں۔

OpenAI

ایک بڑے لینگویج ماڈل کے لیے، میں نے OpenAI (opens in a new tab) کے ساتھ شروعات کرنے کا انتخاب کیا۔ اس ٹیوٹوریل میں ایپلیکیشن چلانے کے لیے آپ کو API رسائی کے لیے ادائیگی کرنی ہوگی۔ $5 کی کم از کم ادائیگی کافی سے زیادہ ہے۔

ڈیولپمنٹ، مرحلہ وار

ڈیولپمنٹ کو آسان بنانے کے لیے، ہم مراحل میں آگے بڑھتے ہیں۔ ہر مرحلہ GitHub میں ایک برانچ ہے۔

شروعات کرنا

UNIX یا Linux (بشمول WSL (opens in a new tab)) کے تحت شروع کرنے کے لیے اقدامات ہیں

  1. اگر آپ کے پاس پہلے سے نہیں ہے تو، Python (opens in a new tab) ڈاؤن لوڈ اور انسٹال کریں۔

  2. GitHub ریپوزٹری کو کلون کریں۔

    1git clone https://github.com/qbzzt/260215-ai-agent.git -b 01-getting-started
    2cd 260215-ai-agent
  3. uv (opens in a new tab) انسٹال کریں۔ آپ کے سسٹم پر کمانڈ مختلف ہو سکتی ہے۔

    1pipx install uv
  4. لائبریریاں ڈاؤن لوڈ کریں۔

    1uv sync
  5. ورچوئل ماحول کو فعال کریں۔

    1source .venv/bin/activate
  6. یہ تصدیق کرنے کے لیے کہ Python اور Web3 صحیح طریقے سے کام کر رہے ہیں، python3 چلائیں اور اسے یہ پروگرام فراہم کریں۔ آپ اسے >>> پرامپٹ پر درج کر سکتے ہیں۔ فائل بنانے کی کوئی ضرورت نہیں ہے۔

    1from web3 import Web3
    2MAINNET_URL = "https://eth.drpc.org"
    3w3 = Web3(Web3.HTTPProvider(MAINNET_URL))
    4w3.eth.block_number
    5quit()

بلاک چین سے پڑھنا

اگلا مرحلہ بلاک چین سے پڑھنا ہے۔ ایسا کرنے کے لیے، آپ کو 02-read-quote برانچ میں تبدیل ہونا ہوگا اور پھر پروگرام چلانے کے لیے uv کا استعمال کرنا ہوگا۔

1git checkout 02-read-quote
2uv run agent.py

آپ کو Quote آبجیکٹس کی ایک فہرست موصول ہونی چاہیے، ہر ایک میں ایک ٹائم اسٹیمپ، ایک قیمت، اور اثاثہ (فی الحال ہمیشہ WETH/USDC

یہاں لائن بہ لائن وضاحت ہے۔

1from web3 import Web3
2from web3.contract import Contract
3from decimal import Decimal, ROUND_HALF_UP
4from dataclasses import dataclass
5from datetime import datetime, timezone
6from pprint import pprint
7import time
8import functools
9import sys
سب دکھائیں

ہمیں جن لائبریریوں کی ضرورت ہے انہیں درآمد کریں۔ ان کی وضاحت نیچے کی گئی ہے جب استعمال کیا جاتا ہے۔

1print = functools.partial(print, flush=True)

Python کے print کو ایک ایسے ورژن سے بدل دیتا ہے جو ہمیشہ آؤٹ پٹ کو فوری طور پر فلش کرتا ہے۔ یہ ایک طویل چلنے والے اسکرپٹ میں مفید ہے کیونکہ ہم اسٹیٹس اپ ڈیٹس یا ڈیبگنگ آؤٹ پٹ کا انتظار نہیں کرنا چاہتے۔

1MAINNET_URL = "https://eth.drpc.org"

مین نیٹ تک پہنچنے کے لیے ایک URL۔ آپ اسے نوڈ بطور سروس سے حاصل کر سکتے ہیں یا Chainlist (opens in a new tab) میں مشتہر کردہ میں سے ایک استعمال کر سکتے ہیں۔

1BLOCK_TIME_SECONDS = 12
2MINUTE_BLOCKS = int(60 / BLOCK_TIME_SECONDS)
3HOUR_BLOCKS = MINUTE_BLOCKS * 60
4DAY_BLOCKS = HOUR_BLOCKS * 24

ایک ایتھیریم مین نیٹ بلاک عام طور پر ہر بارہ سیکنڈ میں ہوتا ہے، لہذا یہ ان بلاکس کی تعداد ہے جن کی ہم ایک مدت میں ہونے کی توقع کریں گے۔ نوٹ کریں کہ یہ ایک درست اعداد و شمار نہیں ہے۔ جب بلاک پروپوزر ڈاؤن ہوتا ہے، تو اس بلاک کو چھوڑ دیا جاتا ہے، اور اگلے بلاک کا وقت 24 سیکنڈ ہوتا ہے۔ اگر ہم کسی ٹائم اسٹیمپ کے لیے بالکل درست بلاک حاصل کرنا چاہتے ہیں، تو ہم بائنری سرچ (opens in a new tab) استعمال کریں گے۔ تاہم، یہ ہمارے مقاصد کے لیے کافی قریب ہے۔ مستقبل کی پیش گوئی کوئی قطعی سائنس نہیں ہے۔

1CYCLE_BLOCKS = DAY_BLOCKS

سائیکل کا سائز۔ ہم ہر سائیکل میں ایک بار کوٹس کا جائزہ لیتے ہیں اور اگلے سائیکل کے اختتام پر قدر کا تخمینہ لگانے کی کوشش کرتے ہیں۔

1# جس پول کو ہم پڑھ رہے ہیں اس کا پتہ
2WETHUSDC_ADDRESS = Web3.to_checksum_address("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640")

کوٹ کی قدریں Uniswap 3 USDC/WETH پول سے ایڈریس 0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640 (opens in a new tab) پر لی جاتی ہیں۔ یہ پتہ پہلے سے ہی چیکسم فارم میں ہے، لیکن کوڈ کو دوبارہ قابل استعمال بنانے کے لیے Web3.to_checksum_address (opens in a new tab) استعمال کرنا بہتر ہے۔

1POOL_ABI = [
2 { "name": "slot0", ... },
3 { "name": "token0", ... },
4 { "name": "token1", ... },
5]
6
7ERC20_ABI = [
8 { "name": "symbol", ... },
9 { "name": "decimals", ... }
10]
سب دکھائیں

یہ ان دو معاہدوں کے لیے ABIs (opens in a new tab) ہیں جن سے ہمیں رابطہ کرنے کی ضرورت ہے۔ کوڈ کو مختصر رکھنے کے لیے، ہم صرف ان فنکشنز کو شامل کرتے ہیں جنہیں ہمیں کال کرنے کی ضرورت ہے۔

1w3 = Web3(Web3.HTTPProvider(MAINNET_URL))

Web3 (opens in a new tab) لائبریری شروع کریں اور ایک ایتھیریم نوڈ سے جڑیں۔

1@dataclass(frozen=True)
2class ERC20Token:
3 address: str
4 symbol: str
5 decimals: int
6 contract: Contract

یہ Python میں ڈیٹا کلاس بنانے کا ایک طریقہ ہے۔ Contract (opens in a new tab) ڈیٹا ٹائپ معاہدے سے جڑنے کے لیے استعمال ہوتا ہے۔ (frozen=True) پر غور کریں۔ Python میں بولینز (opens in a new tab) کو True یا False کے طور پر بیان کیا جاتا ہے، جو بڑے حروف میں ہوتے ہیں۔ یہ ڈیٹا کلاس frozen ہے، جس کا مطلب ہے کہ فیلڈز میں ترمیم نہیں کی جا سکتی۔

انڈینٹیشن پر غور کریں۔ C- اخذ کردہ زبانوں (opens in a new tab) کے برعکس، Python بلاکس کو ظاہر کرنے کے لیے انڈینٹیشن کا استعمال کرتا ہے۔ Python مترجم جانتا ہے کہ درج ذیل تعریف اس ڈیٹا کلاس کا حصہ نہیں ہے کیونکہ یہ ڈیٹا کلاس فیلڈز کی طرح اسی انڈینٹیشن سے شروع نہیں ہوتی ہے۔

1@dataclass(frozen=True)
2class PoolInfo:
3 address: str
4 token0: ERC20Token
5 token1: ERC20Token
6 contract: Contract
7 asset: str
8 decimal_factor: Decimal = 1

Decimal (opens in a new tab) قسم اعشاریہ کسروں کو درست طریقے سے ہینڈل کرنے کے لیے استعمال ہوتی ہے۔

1 def get_price(self, block: int) -> Decimal:

یہ Python میں ایک فنکشن کی تعریف کرنے کا طریقہ ہے۔ تعریف کو یہ دکھانے کے لیے انڈینٹ کیا گیا ہے کہ یہ اب بھی PoolInfo کا حصہ ہے۔

ایک فنکشن میں جو ڈیٹا کلاس کا حصہ ہے، پہلا پیرامیٹر ہمیشہ self ہوتا ہے، ڈیٹا کلاس کا وہ نمونہ جو یہاں کال کیا گیا ہے۔ یہاں ایک اور پیرامیٹر ہے، بلاک نمبر۔

1 assert block <= w3.eth.block_number, "بلاک مستقبل میں ہے"

اگر ہم مستقبل پڑھ سکتے، تو ہمیں ٹریڈنگ کے لیے AI کی ضرورت نہیں ہوتی۔

1 sqrt_price_x96 = Decimal(self.contract.functions.slot0().call(block_identifier=block)[0])

Web3 سے EVM پر فنکشن کال کرنے کا سنٹیکس یہ ہے: <contract object>.functions.<function name>().call(<parameters>)۔ پیرامیٹرز EVM فنکشن کے پیرامیٹرز ہو سکتے ہیں (اگر کوئی ہو؛ یہاں کوئی نہیں ہیں) یا بلاک چین کے رویے میں ترمیم کے لیے نامزد پیرامیٹرز (opens in a new tab)۔ یہاں ہم ایک، block_identifier، بلاک نمبر کی وضاحت کے لیے استعمال کرتے ہیں جس میں ہم چلنا چاہتے ہیں۔

نتیجہ یہ struct ہے، ارے فارم میں (opens in a new tab)۔ پہلی قدر دو ٹوکنز کے درمیان شرح تبادلہ کا ایک فنکشن ہے۔

1 raw_price = (sqrt_price_x96 / Decimal(2**96)) ** 2

آن چین حسابات کو کم کرنے کے لیے، Uniswap v3 اصل ایکسچینج فیکٹر کو ذخیرہ نہیں کرتا بلکہ اس کا مربع جڑ ذخیرہ کرتا ہے۔ چونکہ EVM فلوٹنگ پوائنٹ ریاضی یا کسروں کو سپورٹ نہیں کرتا، اس لیے اصل قدر کے بجائے، جواب price296 ہوتا ہے۔

1 # (ٹوکن1 فی ٹوکن0)
2 return 1/(raw_price * self.decimal_factor)

ہمیں جو خام قیمت ملتی ہے وہ ہر token1 کے لیے ملنے والے token0 کی تعداد ہے۔ ہمارے پول میں token0 USDC (امریکی ڈالر کے برابر قدر والا stablecoin) ہے اور token1 WETH (opens in a new tab) ہے۔ جو قدر ہم واقعی چاہتے ہیں وہ فی WETH ڈالر کی تعداد ہے، نہ کہ اس کا الٹ۔

اعشاریہ عنصر دو ٹوکنز کے لیے اعشاریہ عوامل (opens in a new tab) کے درمیان کا تناسب ہے۔

1@dataclass(frozen=True)
2class Quote:
3 timestamp: str
4 price: Decimal
5 asset: str

یہ ڈیٹا کلاس ایک کوٹ کی نمائندگی کرتی ہے: ایک مخصوص وقت پر ایک مخصوص اثاثہ کی قیمت۔ اس وقت، asset فیلڈ غیر متعلقہ ہے کیونکہ ہم ایک ہی پول استعمال کرتے ہیں اور اس لیے ہمارے پاس ایک ہی اثاثہ ہے۔ تاہم، ہم بعد میں مزید اثاثے شامل کریں گے۔

1def read_token(address: str) -> ERC20Token:
2 token = w3.eth.contract(address=address, abi=ERC20_ABI)
3 symbol = token.functions.symbol().call()
4 decimals = token.functions.decimals().call()
5
6 return ERC20Token(
7 address=address,
8 symbol=symbol,
9 decimals=decimals,
10 contract=token
11 )
سب دکھائیں

یہ فنکشن ایک پتہ لیتا ہے اور اس پتے پر ٹوکن معاہدے کے بارے میں معلومات واپس کرتا ہے۔ ایک نیا Web3 Contract (opens in a new tab) بنانے کے لیے، ہم w3.eth.contract کو پتہ اور ABI فراہم کرتے ہیں۔

1def read_pool(address: str) -> PoolInfo:
2 pool_contract = w3.eth.contract(address=address, abi=POOL_ABI)
3 token0Address = pool_contract.functions.token0().call()
4 token1Address = pool_contract.functions.token1().call()
5 token0 = read_token(token0Address)
6 token1 = read_token(token1Address)
7
8 return PoolInfo(
9 address=address,
10 asset=f"{token1.symbol}/{token0.symbol}",
11 token0=token0,
12 token1=token1,
13 contract=pool_contract,
14 decimal_factor=Decimal(10) ** Decimal(token0.decimals - token1.decimals)
15 )
سب دکھائیں

یہ فنکشن ایک مخصوص پول (opens in a new tab) کے بارے میں ہمیں درکار ہر چیز واپس کرتا ہے۔ سنٹیکس f"<string>" ایک فارمیٹڈ سٹرنگ (opens in a new tab) ہے۔

1def get_quote(pool: PoolInfo, block_number: int = None) -> Quote:

ایک Quote آبجیکٹ حاصل کریں۔ block_number کے لیے ڈیفالٹ ویلیو None (کوئی ویلیو نہیں) ہے۔

1 if block_number is None:
2 block_number = w3.eth.block_number

اگر بلاک نمبر کی وضاحت نہیں کی گئی تھی، تو w3.eth.block_number استعمال کریں، جو کہ تازہ ترین بلاک نمبر ہے۔ یہ ایک if اسٹیٹمنٹ (opens in a new tab) کے لیے سنٹیکس ہے۔

ایسا لگ سکتا ہے کہ ڈیفالٹ کو صرف w3.eth.block_number پر سیٹ کرنا بہتر ہوتا، لیکن یہ اچھی طرح سے کام نہیں کرتا کیونکہ یہ فنکشن کی تعریف کے وقت بلاک نمبر ہوتا۔ ایک طویل چلنے والے ایجنٹ میں، یہ ایک مسئلہ ہوگا۔

1 block = w3.eth.get_block(block_number)
2 price = pool.get_price(block_number)
3 return Quote(
4 timestamp=datetime.fromtimestamp(block.timestamp, timezone.utc).isoformat(),
5 price=price.quantize(Decimal("0.01")),
6 asset=pool.asset
7 )

اسے انسانوں اور بڑے لینگویج ماڈلز (LLMs) کے لیے پڑھنے کے قابل فارمیٹ میں فارمیٹ کرنے کے لیے datetime لائبریری (opens in a new tab) کا استعمال کریں۔ قدر کو دو اعشاریہ مقامات تک راؤنڈ کرنے کے لیے Decimal.quantize (opens in a new tab) کا استعمال کریں۔

1def get_quotes(pool: PoolInfo, start_block: int, end_block: int, step: int) -> list[Quote]:

Python میں آپ list[<type>] کا استعمال کرتے ہوئے ایک فہرست (opens in a new tab) کی تعریف کرتے ہیں جو صرف ایک مخصوص قسم پر مشتمل ہو سکتی ہے۔

1 quotes = []
2 for block in range(start_block, end_block + 1, step):

Python میں for لوپ (opens in a new tab) عام طور پر ایک فہرست پر تکرار کرتا ہے۔ کوٹس تلاش کرنے کے لیے بلاک نمبروں کی فہرست range (opens in a new tab) سے آتی ہے۔

1 quote = get_quote(pool, block)
2 quotes.append(quote)
3 return quotes

ہر بلاک نمبر کے لیے، ایک Quote آبجیکٹ حاصل کریں اور اسے quotes فہرست میں شامل کریں۔ پھر اس فہرست کو واپس کریں۔

1pool = read_pool(WETHUSDC_ADDRESS)
2quotes = get_quotes(
3 pool,
4 w3.eth.block_number - 12*CYCLE_BLOCKS,
5 w3.eth.block_number,
6 CYCLE_BLOCKS
7)
8
9pprint(quotes)
سب دکھائیں

یہ اسکرپٹ کا مرکزی کوڈ ہے۔ پول کی معلومات پڑھیں، بارہ کوٹس حاصل کریں، اور انہیں pprint (opens in a new tab) کریں۔

ایک پرامپٹ بنانا

اگلا، ہمیں کوٹس کی اس فہرست کو LLM کے لیے ایک پرامپٹ میں تبدیل کرنا ہوگا اور ایک متوقع مستقبل کی قدر حاصل کرنی ہوگی۔

1git checkout 03-create-prompt
2uv run agent.py

آؤٹ پٹ اب LLM کو ایک پرامپٹ ہوگا، جیسا کہ:

1یہ کوٹس دیے گئے ہیں:
2اثاثہ: WETH/USDC
3 2026-01-20T16:34 3016.21
4 .
5 .
6 .
7 2026-02-01T17:49 2299.10
8
9اثاثہ: WBTC/WETH
10 2026-01-20T16:34 29.84
11 .
12 .
13 .
14 2026-02-01T17:50 33.46
15
16
17آپ توقع کریں گے کہ WETH/USDC کی قیمت وقت 2026-02-02T17:56 پر کیا ہوگی؟
18
19اپنا جواب دو اعشاریہ مقامات تک گول ایک ہی نمبر کے طور پر فراہم کریں،
20کسی اور متن کے بغیر۔
سب دکھائیں

غور کریں کہ یہاں دو اثاثوں کے لیے کوٹس ہیں، WETH/USDC اور WBTC/WETH۔ کسی دوسرے اثاثے سے کوٹس شامل کرنے سے پیشین گوئی کی درستگی بہتر ہو سکتی ہے۔

ایک پرامپٹ کیسا لگتا ہے

اس پرامپٹ میں تین حصے ہیں، جو LLM پرامپٹس میں بہت عام ہیں۔

  1. معلومات۔ LLMs کے پاس اپنی تربیت سے بہت سی معلومات ہوتی ہیں، لیکن ان کے پاس عام طور پر تازہ ترین معلومات نہیں ہوتیں۔ یہی وجہ ہے کہ ہمیں یہاں تازہ ترین کوٹس بازیافت کرنے کی ضرورت ہے۔ ایک پرامپٹ میں معلومات شامل کرنا ریٹریول آگمینٹڈ جنریشن (RAG) (opens in a new tab) کہلاتا ہے۔

  2. اصل سوال۔ یہ وہ ہے جو ہم جاننا چاہتے ہیں۔

  3. آؤٹ پٹ فارمیٹنگ ہدایات۔ عام طور پر، ایک LLM ہمیں ایک تخمینہ دے گا جس میں یہ بتایا جائے گا کہ یہ اس تک کیسے پہنچا۔ یہ انسانوں کے لیے بہتر ہے، لیکن ایک کمپیوٹر پروگرام کو صرف نچلی لائن کی ضرورت ہوتی ہے۔

کوڈ کی وضاحت

یہاں نیا کوڈ ہے۔

1from datetime import datetime, timezone, timedelta

ہمیں LLM کو وہ وقت فراہم کرنے کی ضرورت ہے جس کے لیے ہم تخمینہ چاہتے ہیں۔ مستقبل میں "n منٹ/گھنٹے/دن" کا وقت حاصل کرنے کے لیے، ہم timedelta کلاس (opens in a new tab) کا استعمال کرتے ہیں۔

1# جن پولز کو ہم پڑھ رہے ہیں ان کے پتے
2WETHUSDC_ADDRESS = Web3.to_checksum_address("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640")
3WETHWBTC_ADDRESS = Web3.to_checksum_address("0xCBCdF9626bC03E24f779434178A73a0B4bad62eD")

ہمارے پاس دو پول ہیں جنہیں ہمیں پڑھنے کی ضرورت ہے۔

1@dataclass(frozen=True)
2class PoolInfo:
3 .
4 .
5 .
6 reverse: bool = False
7
8 def get_price(self, block: int) -> Decimal:
9 assert block <= w3.eth.block_number, "بلاک مستقبل میں ہے"
10 sqrt_price_x96 = Decimal(self.contract.functions.slot0().call(block_identifier=block)[0])
11 raw_price = (sqrt_price_x96 / Decimal(2**96)) ** 2 # (ٹوکن1 فی ٹوکن0)
12 if self.reverse:
13 return 1/(raw_price * self.decimal_factor)
14 else:
15 return raw_price * self.decimal_factor
سب دکھائیں

WETH/USDC پول میں، ہم جاننا چاہتے ہیں کہ token0 (USDC) میں سے کتنے کی ضرورت ہے تاکہ token1 (WETH) کا ایک خریدا جا سکے۔ WETH/WBTC پول میں، ہم جاننا چاہتے ہیں کہ token1 (WETH) میں سے کتنے کی ضرورت ہے تاکہ token0 (WBTC, جو کہ لپیٹا ہوا Bitcoin ہے) کا ایک خریدا جا سکے۔ ہمیں یہ ٹریک کرنے کی ضرورت ہے کہ آیا پول کے تناسب کو الٹنے کی ضرورت ہے۔

1def read_pool(address: str, reverse: bool = False) -> PoolInfo:
2 .
3 .
4 .
5
6 return PoolInfo(
7 .
8 .
9 .
10
11 asset= f"{token1.symbol}/{token0.symbol}" if reverse else f"{token0.symbol}/{token1.symbol}",
12 reverse=reverse
13 )
سب دکھائیں

یہ جاننے کے لیے کہ آیا کسی پول کو الٹنے کی ضرورت ہے، ہم اسے read_pool کے ان پٹ کے طور پر حاصل کرتے ہیں۔ اس کے علاوہ، اثاثہ کی علامت کو صحیح طریقے سے ترتیب دینے کی ضرورت ہے۔

سنٹیکس <a> if <b> else <c> ٹرنری کنڈیشنل آپریٹر (opens in a new tab) کا Python مساوی ہے، جو C-اخذ کردہ زبان میں <b> ? <a> : <c> ہوگا۔

1def format_quotes(quotes: list[Quote]) -> str:
2 result = f"اثاثہ: {quotes[0].asset}\n"
3 for quote in quotes:
4 result += f"\t{quote.timestamp[0:16]} {quote.price.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)}\n"
5 return result

یہ فنکشن ایک سٹرنگ بناتا ہے جو Quote آبجیکٹس کی فہرست کو فارمیٹ کرتا ہے، یہ فرض کرتے ہوئے کہ وہ سب ایک ہی اثاثے پر لاگو ہوتے ہیں۔

1def make_prompt(quotes: list[list[Quote]], expected_time: str, asset: str) -> str:
2 return f"""

Python میں ملٹی لائن سٹرنگ لٹرلز (opens in a new tab) کو """ .... کے طور پر لکھا جاتا ہے۔ """۔

1یہ کوٹس دیے گئے ہیں:
2{
3 functools.reduce(lambda acc, q: acc + '\n' + q,
4 map(lambda q: format_quotes(q), quotes))
5}

یہاں، ہم ہر کوٹ فہرست کے لیے format_quotes کے ساتھ ایک سٹرنگ بنانے کے لیے MapReduce (opens in a new tab) پیٹرن کا استعمال کرتے ہیں، پھر انہیں پرامپٹ میں استعمال کے لیے ایک ہی سٹرنگ میں کم کرتے ہیں۔

1آپ توقع کریں گے کہ {asset} کی قیمت وقت {expected_time} پر کیا ہوگی؟
2
3اپنا جواب دو اعشاریہ مقامات تک گول ایک ہی نمبر کے طور پر فراہم کریں،
4کسی اور متن کے بغیر۔
5 """

پرامپٹ کا باقی حصہ توقع کے مطابق ہے۔

1wethusdc_pool = read_pool(WETHUSDC_ADDRESS, True)
2wethusdc_quotes = get_quotes(
3 wethusdc_pool,
4 w3.eth.block_number - 12*CYCLE_BLOCKS,
5 w3.eth.block_number,
6 CYCLE_BLOCKS,
7)
8
9wethwbtc_pool = read_pool(WETHWBTC_ADDRESS)
10wethwbtc_quotes = get_quotes(
11 wethwbtc_pool,
12 w3.eth.block_number - 12*CYCLE_BLOCKS,
13 w3.eth.block_number,
14 CYCLE_BLOCKS
15)
سب دکھائیں

دونوں پولز کا جائزہ لیں اور دونوں سے کوٹس حاصل کریں۔

1future_time = (datetime.now(timezone.utc) + timedelta(days=1)).isoformat()[0:16]
2
3print(make_prompt(wethusdc_quotes + wethwbtc_quotes, future_time, wethusdc_pool.asset))

مستقبل کے اس وقت کا تعین کریں جس کے لیے ہم تخمینہ چاہتے ہیں، اور پرامپٹ بنائیں۔

LLM کے ساتھ انٹرفیسنگ

اگلا، ہم ایک حقیقی LLM کو پرامپٹ کرتے ہیں اور ایک متوقع مستقبل کی قدر حاصل کرتے ہیں۔ میں نے یہ پروگرام OpenAI کا استعمال کرتے ہوئے لکھا ہے، لہذا اگر آپ کوئی مختلف فراہم کنندہ استعمال کرنا چاہتے ہیں، تو آپ کو اسے ایڈجسٹ کرنا ہوگا۔

  1. ایک OpenAI اکاؤنٹ (opens in a new tab) حاصل کریں

  2. اکاؤنٹ میں فنڈ ڈالیں (opens in a new tab)—لکھنے کے وقت کم از کم رقم $5 ہے

  3. ایک API کلید بنائیں (opens in a new tab)

  4. کمانڈ لائن میں، API کلید برآمد کریں تاکہ آپ کا پروگرام اسے استعمال کر سکے

    1export OPENAI_API_KEY=sk-<باقی کلید یہاں جاتی ہے>
  5. ایجنٹ کو چیک آؤٹ کریں اور چلائیں

    1git checkout 04-interface-llm
    2uv run agent.py

یہاں نیا کوڈ ہے۔

1from openai import OpenAI
2
3open_ai = OpenAI() # کلائنٹ OPENAI_API_KEY ماحولیاتی متغیر کو پڑھتا ہے

OpenAI API کو امپورٹ اور انسٹینٹیٹ کریں۔

1response = open_ai.chat.completions.create(
2 model="gpt-4-turbo",
3 messages=[
4 {"role": "user", "content": prompt}
5 ],
6 temperature=0.0,
7 max_tokens=16,
8)

جواب بنانے کے لیے OpenAI API (open_ai.chat.completions.create) کو کال کریں۔

1expected_price = Decimal(response.choices[0].message.content.strip())
2current_price = wethusdc_quotes[-1].price
3
4print ("موجودہ قیمت:", wethusdc_quotes[-1].price)
5print(f"{future_time} میں، متوقع قیمت: {expected_price} USD")
6
7if (expected_price > current_price):
8 print(f"خریدیں، مجھے امید ہے کہ قیمت {expected_price - current_price} USD تک بڑھ جائے گی")
9else:
10 print(f"بیچیں، مجھے امید ہے کہ قیمت {current_price - expected_price} USD تک گر جائے گی")
سب دکھائیں

قیمت کو آؤٹ پٹ کریں اور خرید و فروخت کی سفارش فراہم کریں۔

پیشین گوئیوں کی جانچ

اب جب کہ ہم پیشین گوئیاں پیدا کر سکتے ہیں، ہم تاریخی ڈیٹا کا بھی استعمال کر سکتے ہیں تاکہ یہ اندازہ لگایا جا سکے کہ کیا ہم مفید پیشین گوئیاں پیدا کرتے ہیں۔

1uv run test-predictor.py

متوقع نتیجہ اس جیسا ہے:

12026-01-05T19:50 کے لیے پیشین گوئی: پیشین گوئی 3138.93 USD، اصل 3218.92 USD، غلطی 79.99 USD
22026-01-06T19:56 کے لیے پیشین گوئی: پیشین گوئی 3243.39 USD، اصل 3221.08 USD، غلطی 22.31 USD
32026-01-07T20:02 کے لیے پیشین گوئی: پیشین گوئی 3223.24 USD، اصل 3146.89 USD، غلطی 76.35 USD
42026-01-08T20:11 کے لیے پیشین گوئی: پیشین گوئی 3150.47 USD، اصل 3092.04 USD، غلطی 58.43 USD
5.
6.
7.
82026-01-31T22:33 کے لیے پیشین گوئی: پیشین گوئی 2637.73 USD، اصل 2417.77 USD، غلطی 219.96 USD
92026-02-01T22:41 کے لیے پیشین گوئی: پیشین گوئی 2381.70 USD، اصل 2318.84 USD، غلطی 62.86 USD
102026-02-02T22:49 کے لیے پیشین گوئی: پیشین گوئی 2234.91 USD، اصل 2349.28 USD، غلطی 114.37 USD
1129 پیشین گوئیوں پر اوسط پیشین گوئی کی غلطی: 83.87103448275862068965517241 USD
12فی سفارش اوسط تبدیلی: 4.787931034482758620689655172 USD
13تبدیلیوں کا معیاری تغیر: 104.42 USD
14منافع بخش دن: 51.72%
15نقصان والے دن: 48.28%
سب دکھائیں

ٹیسٹر کا زیادہ تر حصہ ایجنٹ کی طرح ہی ہے، لیکن یہاں وہ حصے ہیں جو نئے یا ترمیم شدہ ہیں۔

1CYCLES_FOR_TEST = 40 # بیک ٹیسٹ کے لیے، ہم کتنے سائیکلوں کی جانچ کرتے ہیں
2
3# بہت سے کوٹس حاصل کریں
4wethusdc_pool = read_pool(WETHUSDC_ADDRESS, True)
5wethusdc_quotes = get_quotes(
6 wethusdc_pool,
7 w3.eth.block_number - CYCLE_BLOCKS*CYCLES_FOR_TEST,
8 w3.eth.block_number,
9 CYCLE_BLOCKS,
10)
11
12wethwbtc_pool = read_pool(WETHWBTC_ADDRESS)
13wethwbtc_quotes = get_quotes(
14 wethwbtc_pool,
15 w3.eth.block_number - CYCLE_BLOCKS*CYCLES_FOR_TEST,
16 w3.eth.block_number,
17 CYCLE_BLOCKS
18)
سب دکھائیں

ہم CYCLES_FOR_TEST (یہاں 40 کے طور پر بیان کیا گیا ہے) دن پیچھے دیکھتے ہیں۔

1# پیشین گوئیاں بنائیں اور انہیں حقیقی تاریخ کے خلاف چیک کریں
2
3total_error = Decimal(0)
4changes = []

دو قسم کی غلطیاں ہیں جن میں ہمیں دلچسپی ہے۔ پہلا، total_error، صرف پیش گو نے کی گئی غلطیوں کا مجموعہ ہے۔

دوسرے، changes، کو سمجھنے کے لیے، ہمیں ایجنٹ کے مقصد کو یاد رکھنے کی ضرورت ہے۔ یہ WETH/USDC تناسب (ETH قیمت) کی پیش گوئی کرنا نہیں ہے۔ یہ فروخت اور خرید کی سفارشات جاری کرنا ہے۔ اگر قیمت فی الحال $2000 ہے اور یہ کل $2010 کی پیش گوئی کرتا ہے، تو ہمیں کوئی اعتراض نہیں اگر اصل نتیجہ $2020 ہو اور ہم اضافی رقم کمائیں۔ لیکن ہمیں اس وقت اعتراض ہوتا ہے جب اس نے $2010 کی پیش گوئی کی ہو، اور اس سفارش کی بنیاد پر ETH خریدا ہو، اور قیمت $1990 تک گر جائے۔

1for index in range(0,len(wethusdc_quotes)-CYCLES_BACK):

ہم صرف ان معاملات کو دیکھ سکتے ہیں جہاں مکمل تاریخ (پیشین گوئی کے لیے استعمال ہونے والی قدریں اور اس سے موازنہ کرنے کے لیے حقیقی دنیا کی قدر) دستیاب ہے۔ اس کا مطلب ہے کہ سب سے نیا کیس وہ ہونا چاہیے جو CYCLES_BACK پہلے شروع ہوا تھا۔

1 wethusdc_slice = wethusdc_quotes[index:index+CYCLES_BACK]
2 wethwbtc_slice = wethwbtc_quotes[index:index+CYCLES_BACK]

سلائسز (opens in a new tab) کا استعمال کریں تاکہ نمونوں کی اتنی ہی تعداد حاصل کی جا سکے جتنی ایجنٹ استعمال کرتا ہے۔ یہاں اور اگلے حصے کے درمیان کا کوڈ وہی ہے جو ایجنٹ میں موجود پیشین گوئی حاصل کرنے والا کوڈ ہے۔

1 predicted_price = Decimal(response.choices[0].message.content.strip())
2 real_price = wethusdc_quotes[index+CYCLES_BACK].price
3 prediction_time_price = wethusdc_quotes[index+CYCLES_BACK-1].price

پیشین گوئی کی گئی قیمت، حقیقی قیمت، اور پیشین گوئی کے وقت کی قیمت حاصل کریں۔ یہ تعین کرنے کے لیے کہ سفارش خریدنے کی تھی یا بیچنے کی، ہمیں پیشین گوئی کے وقت کی قیمت کی ضرورت ہے۔

1 error = abs(predicted_price - real_price)
2 total_error += error
3 print (f"Prediction for {prediction_time}: predicted {predicted_price} USD, real {real_price} USD, error {error} USD")

غلطی کا اندازہ لگائیں، اور اسے کل میں شامل کریں۔

1 recomended_action = 'buy' if predicted_price > prediction_time_price else 'sell'
2 price_increase = real_price - prediction_time_price
3 changes.append(price_increase if recomended_action == 'buy' else -price_increase)

changes کے لیے، ہم ایک ETH خریدنے یا بیچنے کے مالیاتی اثرات چاہتے ہیں۔ لہذا پہلے، ہمیں سفارش کا تعین کرنے کی ضرورت ہے، پھر یہ اندازہ لگانا ہے کہ اصل قیمت کس طرح تبدیل ہوئی، اور کیا سفارش نے پیسہ کمایا (مثبت تبدیلی) یا پیسہ خرچ کیا (منفی تبدیلی)۔

1print (f"Mean prediction error over {len(wethusdc_quotes)-CYCLES_BACK} predictions: {total_error / Decimal(len(wethusdc_quotes)-CYCLES_BACK)} USD")
2
3length_changes = Decimal(len(changes))
4mean_change = sum(changes, Decimal(0)) / length_changes
5print (f"Mean change per recommendation: {mean_change} USD")
6var = sum((x - mean_change) ** 2 for x in changes) / length_changes
7print (f"Standard variance of changes: {var.sqrt().quantize(Decimal("0.01"))} USD")

نتائج کی اطلاع دیں۔

1print (f"Profitable days: {len(list(filter(lambda x: x > 0, changes)))/length_changes:.2%}")
2print (f"Losing days: {len(list(filter(lambda x: x < 0, changes)))/length_changes:.2%}")

منافع بخش دنوں اور مہنگے دنوں کی تعداد گننے کے لیے filter (opens in a new tab) کا استعمال کریں۔ نتیجہ ایک فلٹر آبجیکٹ ہے، جسے ہمیں لمبائی حاصل کرنے کے لیے ایک فہرست میں تبدیل کرنے کی ضرورت ہے۔

ٹرانزیکشنز جمع کرنا

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

یہاں ایک مقامی فورک بنانے اور ٹریڈنگ کو فعال کرنے کے اقدامات ہیں۔

  1. Foundry (opens in a new tab) انسٹال کریں

  2. anvil (opens in a new tab) شروع کریں

    1anvil --fork-url https://eth.drpc.org --block-time 12

    anvil Foundry کے لیے ڈیفالٹ URL، http://localhost:8545 (opens in a new tab) پر سن رہا ہے، لہذا ہمیں cast کمانڈ (opens in a new tab) کے لیے URL کی وضاحت کرنے کی ضرورت نہیں ہے جسے ہم بلاک چین میں ہیرا پھیری کے لیے استعمال کرتے ہیں۔

  3. anvil میں چلتے وقت، دس ٹیسٹ اکاؤنٹس ہیں جن میں ETH ہے — پہلے والے کے لیے ماحولیاتی متغیرات سیٹ کریں

    1PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
    2ADDRESS=`cast wallet address $PRIVATE_KEY`
  4. یہ وہ معاہدے ہیں جنہیں ہمیں استعمال کرنے کی ضرورت ہے۔ SwapRouter (opens in a new tab) Uniswap v3 معاہدہ ہے جسے ہم اصل میں ٹریڈ کرنے کے لیے استعمال کرتے ہیں۔ ہم براہ راست پول کے ذریعے ٹریڈ کر سکتے ہیں، لیکن یہ بہت آسان ہے۔

    نیچے کے دو متغیرات Uniswap v3 کے راستے ہیں جو WETH اور USDC کے درمیان تبادلہ کرنے کے لیے درکار ہیں۔

    1WETH_ADDRESS=0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
    2USDC_ADDRESS=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
    3POOL_ADDRESS=0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640
    4SWAP_ROUTER=0xE592427A0AEce92De3Edee1F18E0157C05861564
    5WETH_TO_USDC=0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc20001F4A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
    6USDC_TO_WETH=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB480001F4C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
  5. ہر ٹیسٹ اکاؤنٹ میں 10,000 ETH ہیں۔ ٹریڈنگ کے لیے 1000 WETH حاصل کرنے کے لیے 1000 ETH کو لپیٹنے کے لیے WETH معاہدہ استعمال کریں۔

    1cast send $WETH_ADDRESS "deposit()" --value 1000ether --private-key $PRIVATE_KEY
  6. USDC کے لیے 500 WETH ٹریڈ کرنے کے لیے SwapRouter کا استعمال کریں۔

    1cast send $WETH_ADDRESS "approve(address,uint256)" $SWAP_ROUTER 500ether --private-key $PRIVATE_KEY
    2MAXINT=`cast max-int uint256`
    3cast send $SWAP_ROUTER \
    4 "exactInput((bytes,address,uint256,uint256,uint256))" \
    5 "($WETH_TO_USDC,$ADDRESS,$MAXINT,500ether,1000000)" \
    6 --private-key $PRIVATE_KEY

    approve کال ایک الاؤنس بناتی ہے جو SwapRouter کو ہمارے کچھ ٹوکنز خرچ کرنے کی اجازت دیتی ہے۔ معاہدے واقعات کی نگرانی نہیں کر سکتے، لہذا اگر ہم براہ راست SwapRouter معاہدے میں ٹوکن منتقل کرتے ہیں، تو اسے یہ معلوم نہیں ہوگا کہ اسے ادائیگی کی گئی ہے۔ اس کے بجائے، ہم SwapRouter معاہدے کو ایک خاص رقم خرچ کرنے کی اجازت دیتے ہیں، اور پھر SwapRouter یہ کرتا ہے۔ یہ SwapRouter کے ذریعے کال کیے گئے فنکشن کے ذریعے کیا جاتا ہے، لہذا یہ جانتا ہے کہ آیا یہ کامیاب تھا۔

  7. تصدیق کریں کہ آپ کے پاس دونوں ٹوکنز کافی ہیں۔

    1cast call $WETH_ADDRESS "balanceOf(address)" $ADDRESS | cast from-wei
    2echo `cast call $USDC_ADDRESS "balanceOf(address)" $ADDRESS | cast to-dec`/10^6 | bc

اب جب کہ ہمارے پاس WETH اور USDC ہے، ہم اصل میں ایجنٹ چلا سکتے ہیں۔

1git checkout 05-trade
2uv run agent.py

آؤٹ پٹ اس جیسا نظر آئے گا:

1(ai-trading-agent) qbzzt@Ori-Cloudnomics:~/260215-ai-agent$ uv run agent.py
2موجودہ قیمت: 1843.16
32026-02-06T23:07 میں، متوقع قیمت: 1724.41 USD
4ٹریڈ سے پہلے اکاؤنٹ بیلنس:
5USDC بیلنس: 927301.578272
6WETH بیلنس: 500
7بیچیں، مجھے امید ہے کہ قیمت 118.75 USD تک گر جائے گی
8منظور شدہ ٹرانزیکشن بھیجی گئی: 74e367ddbb407c1aaf567d87aa5863049991b1d2aa092b6b85195d925e2bd41f
9منظور شدہ ٹرانزیکشن مائن ہو گئی۔
10فروخت ٹرانزیکشن بھیجی گئی: fad1bcf938585c9e90364b26ac7a80eea9efd34c37e5db81e58d7655bcae28bf
11فروخت ٹرانزیکشن مائن ہو گئی۔
12ٹریڈ کے بعد اکاؤنٹ بیلنس:
13USDC بیلنس: 929143.797116
14WETH بیلنس: 499
سب دکھائیں

اسے اصل میں استعمال کرنے کے لیے، آپ کو کچھ معمولی تبدیلیوں کی ضرورت ہے۔

  • لائن 14 میں، MAINNET_URL کو ایک حقیقی رسائی پوائنٹ میں تبدیل کریں، جیسے https://eth.drpc.org
  • لائن 28 میں، PRIVATE_KEY کو اپنی ذاتی کلید میں تبدیل کریں
  • جب تک آپ بہت امیر نہ ہوں اور ایک غیر ثابت شدہ ایجنٹ کے لیے ہر روز 1 ETH خرید یا بیچ سکتے ہوں، آپ WETH_TRADE_AMOUNT کو کم کرنے کے لیے 29 کو تبدیل کرنا چاہ سکتے ہیں۔

کوڈ کی وضاحت

یہاں نیا کوڈ ہے۔

1SWAP_ROUTER_ADDRESS=Web3.to_checksum_address("0xE592427A0AEce92De3Edee1F18E0157C05861564")
2WETH_TO_USDC=bytes.fromhex("C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc20001F4A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48")
3USDC_TO_WETH=bytes.fromhex("A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB480001F4C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2")
4PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"

وہی متغیرات جو ہم نے مرحلہ 4 میں استعمال کیے تھے۔

1WETH_TRADE_AMOUNT=1

ٹریڈ کرنے کی رقم۔

1ERC20_ABI = [
2 { "name": "symbol", ... },
3 { "name": "decimals", ... },
4 { "name": "balanceOf", ...},
5 { "name": "approve", ...}
6]

اصل میں ٹریڈ کرنے کے لیے، ہمیں approve فنکشن کی ضرورت ہے۔ ہم پہلے اور بعد میں بیلنس بھی دکھانا چاہتے ہیں، لہذا ہمیں balanceOf کی بھی ضرورت ہے۔

1SWAP_ROUTER_ABI = [
2 { "name": "exactInput", ...},
3]

SwapRouter ABI میں ہمیں صرف exactInput کی ضرورت ہے۔ ایک متعلقہ فنکشن ہے، exactOutput، جسے ہم بالکل ایک WETH خریدنے کے لیے استعمال کر سکتے ہیں، لیکن سادگی کے لیے ہم دونوں صورتوں میں صرف exactInput استعمال کرتے ہیں۔

1account = w3.eth.account.from_key(PRIVATE_KEY)
2swap_router = w3.eth.contract(
3 address=SWAP_ROUTER_ADDRESS,
4 abi=SWAP_ROUTER_ABI
5)

account (opens in a new tab) اور SwapRouter معاہدے کے لیے Web3 کی تعریفیں۔

1def txn_params() -> dict:
2 return {
3 "from": account.address,
4 "value": 0,
5 "gas": 300000,
6 "nonce": w3.eth.get_transaction_count(account.address),
7 }

ٹرانزیکشن کے پیرامیٹرز۔ ہمیں یہاں ایک فنکشن کی ضرورت ہے کیونکہ nonce (opens in a new tab) ہر بار تبدیل ہونا چاہیے۔

1def approve_token(contract: Contract, amount: int):

SwapRouter کے لیے ٹوکن الاؤنس منظور کریں۔

1 txn = contract.functions.approve(SWAP_ROUTER_ADDRESS, amount).build_transaction(txn_params())
2 signed_txn = w3.eth.account.sign_transaction(txn, private_key=PRIVATE_KEY)
3 tx_hash = w3.eth.send_raw_transaction(signed_txn.raw_transaction)

یہ وہ طریقہ ہے جس سے ہم Web3 میں ٹرانزیکشن بھیجتے ہیں۔ پہلے ہم ٹرانزیکشن بنانے کے لیے Contract آبجیکٹ (opens in a new tab) کا استعمال کرتے ہیں۔ پھر ہم PRIVATE_KEY کا استعمال کرتے ہوئے، ٹرانزیکشن پر دستخط کرنے کے لیے web3.eth.account.sign_transaction (opens in a new tab) کا استعمال کرتے ہیں۔ آخر میں، ہم ٹرانزیکشن بھیجنے کے لیے w3.eth.send_raw_transaction (opens in a new tab) کا استعمال کرتے ہیں۔

1 print(f"Approve transaction sent: {tx_hash.hex()}")
2 w3.eth.wait_for_transaction_receipt(tx_hash)
3 print("Approve transaction mined.")

w3.eth.wait_for_transaction_receipt (opens in a new tab) ٹرانزیکشن کے مائن ہونے تک انتظار کرتا ہے۔ یہ ضرورت پڑنے پر رسید واپس کرتا ہے۔

1SELL_PARAMS = {
2 "path": WETH_TO_USDC,
3 "recipient": account.address,
4 "deadline": 2**256 - 1,
5 "amountIn": WETH_TRADE_AMOUNT * 10 ** wethusdc_pool.token1.decimals,
6 "amountOutMinimum": 0,
7}

یہ WETH بیچتے وقت کے پیرامیٹرز ہیں۔

1def make_buy_params(quote: Quote) -> dict:
2 return {
3 "path": USDC_TO_WETH,
4 "recipient": account.address,
5 "deadline": 2**256 - 1,
6 "amountIn": int(quote.price*WETH_TRADE_AMOUNT) * 10**wethusdc_pool.token0.decimals,
7 "amountOutMinimum": 0,
8 }

SELL_PARAMS کے برعکس، خرید کے پیرامیٹرز تبدیل ہو سکتے ہیں۔ ان پٹ کی رقم 1 WETH کی قیمت ہے، جیسا کہ quote میں دستیاب ہے۔

1def buy(quote: Quote):
2 buy_params = make_buy_params(quote)
3 approve_token(wethusdc_pool.token0.contract, buy_params["amountIn"])
4 txn = swap_router.functions.exactInput(buy_params).build_transaction(txn_params())
5 signed_txn = w3.eth.account.sign_transaction(txn, private_key=PRIVATE_KEY)
6 tx_hash = w3.eth.send_raw_transaction(signed_txn.raw_transaction)
7 print(f"Buy transaction sent: {tx_hash.hex()}")
8 w3.eth.wait_for_transaction_receipt(tx_hash)
9 print("Buy transaction mined.")
10
11
12def sell():
13 approve_token(wethusdc_pool.token1.contract,
14 WETH_TRADE_AMOUNT * 10**wethusdc_pool.token1.decimals)
15 txn = swap_router.functions.exactInput(SELL_PARAMS).build_transaction(txn_params())
16 signed_txn = w3.eth.account.sign_transaction(txn, private_key=PRIVATE_KEY)
17 tx_hash = w3.eth.send_raw_transaction(signed_txn.raw_transaction)
18 print(f"Sell transaction sent: {tx_hash.hex()}")
19 w3.eth.wait_for_transaction_receipt(tx_hash)
20 print("Sell transaction mined.")
سب دکھائیں

buy() اور sell() فنکشنز تقریباً ایک جیسے ہیں۔ پہلے ہم SwapRouter کے لیے کافی الاؤنس منظور کرتے ہیں، اور پھر ہم اسے صحیح راستے اور رقم کے ساتھ کال کرتے ہیں۔

1def balances():
2 token0_balance = wethusdc_pool.token0.contract.functions.balanceOf(account.address).call()
3 token1_balance = wethusdc_pool.token1.contract.functions.balanceOf(account.address).call()
4
5 print(f"{wethusdc_pool.token0.symbol} Balance: {Decimal(token0_balance) / Decimal(10 ** wethusdc_pool.token0.decimals)}")
6 print(f"{wethusdc_pool.token1.symbol} Balance: {Decimal(token1_balance) / Decimal(10 ** wethusdc_pool.token1.decimals)}")

دونوں کرنسیوں میں صارف کے بیلنس کی اطلاع دیں۔

1print("ٹریڈ سے پہلے اکاؤنٹ بیلنس:")
2balances()
3
4if (expected_price > current_price):
5 print(f"خریدیں، مجھے امید ہے کہ قیمت {expected_price - current_price} USD تک بڑھ جائے گی")
6 buy(wethusdc_quotes[-1])
7else:
8 print(f"بیچیں، مجھے امید ہے کہ قیمت {current_price - expected_price} USD تک گر جائے گی")
9 sell()
10
11print("ٹریڈ کے بعد اکاؤنٹ بیلنس:")
12balances()
سب دکھائیں

یہ ایجنٹ فی الحال صرف ایک بار کام کرتا ہے۔ تاہم، آپ اسے crontab (opens in a new tab) سے چلا کر یا لائن 368-400 کو ایک لوپ میں لپیٹ کر اور time.sleep (opens in a new tab) کا استعمال کرکے اسے مسلسل کام کرنے کے لیے تبدیل کر سکتے ہیں تاکہ اگلے سائیکل کا وقت آنے تک انتظار کیا جا سکے۔

ممکنہ بہتری

یہ ایک مکمل پروڈکشن ورژن نہیں ہے؛ یہ صرف بنیادی باتیں سکھانے کے لیے ایک مثال ہے۔ یہاں بہتری کے لیے کچھ خیالات ہیں۔

ہوشیار ٹریڈنگ

دو اہم حقائق ہیں جنہیں ایجنٹ نظر انداز کرتا ہے جب وہ فیصلہ کرتا ہے کہ کیا کرنا ہے۔

  • متوقع تبدیلی کی شدت۔ ایجنٹ ایک مقررہ رقم کا WETH فروخت کرتا ہے اگر قیمت میں کمی کی توقع ہو، چاہے کمی کی شدت کچھ بھی ہو۔ یقیناً، معمولی تبدیلیوں کو نظر انداز کرنا اور اس بات کی بنیاد پر فروخت کرنا بہتر ہوگا کہ ہم قیمت میں کتنی کمی کی توقع کرتے ہیں۔
  • موجودہ پورٹ فولیو۔ اگر آپ کے پورٹ فولیو کا 10% WETH میں ہے اور آپ کو لگتا ہے کہ قیمت بڑھے گی، تو شاید مزید خریدنا سمجھ میں آتا ہے۔ لیکن اگر آپ کے پورٹ فولیو کا 90% WETH میں ہے، تو آپ کافی حد تک بے نقاب ہو سکتے ہیں، اور مزید خریدنے کی ضرورت نہیں ہے۔ الٹا سچ ہے اگر آپ کو قیمت کم ہونے کی توقع ہے۔

اگر آپ اپنی ٹریڈنگ کی حکمت عملی کو خفیہ رکھنا چاہتے ہیں تو کیا ہوگا؟

AI وینڈرز آپ کے LLMs کو بھیجے گئے سوالات دیکھ سکتے ہیں، جو آپ کے ایجنٹ کے ساتھ تیار کردہ جینئس ٹریڈنگ سسٹم کو بے نقاب کر سکتے ہیں۔ ایک ٹریڈنگ سسٹم جسے بہت سے لوگ استعمال کرتے ہیں وہ بیکار ہے کیونکہ بہت سے لوگ اس وقت خریدنے کی کوشش کرتے ہیں جب آپ خریدنا چاہتے ہیں (اور قیمت بڑھ جاتی ہے) اور اس وقت بیچنے کی کوشش کرتے ہیں جب آپ بیچنا چاہتے ہیں (اور قیمت گر جاتی ہے)۔

آپ مقامی طور پر ایک LLM چلا سکتے ہیں، مثال کے طور پر، LM-Studio (opens in a new tab) کا استعمال کرتے ہوئے، اس مسئلے سے بچنے کے لیے۔

AI بوٹ سے AI ایجنٹ تک

آپ ایک اچھا کیس بنا سکتے ہیں کہ یہ ایک AI بوٹ ہے، نہ کہ AI ایجنٹ۔ یہ ایک نسبتاً آسان حکمت عملی کو نافذ کرتا ہے جو پہلے سے طے شدہ معلومات پر انحصار کرتا ہے۔ ہم خود کو بہتر بنانے کو فعال کر سکتے ہیں، مثال کے طور پر، Uniswap v3 پولز کی ایک فہرست اور ان کی تازہ ترین قدریں فراہم کرکے اور یہ پوچھ کر کہ کس امتزاج کی بہترین پیشین گوئی کی قدر ہے۔

سلپیج پروٹیکشن

فی الحال کوئی سلپیج پروٹیکشن (opens in a new tab) نہیں ہے۔ اگر موجودہ کوٹ $2000 ہے، اور متوقع قیمت $2100 ہے، تو ایجنٹ خریدے گا۔ تاہم، اگر ایجنٹ کے خریدنے سے پہلے لاگت $2200 تک بڑھ جاتی ہے، تو مزید خریدنے کا کوئی مطلب نہیں ہے۔

سلپیج پروٹیکشن کو نافذ کرنے کے لیے، agent.py (opens in a new tab) کی لائن 325 اور 334 میں amountOutMinimum کی قدر کی وضاحت کریں۔

نتیجہ

امید ہے، اب آپ AI ایجنٹس کے ساتھ شروع کرنے کے لیے کافی جانتے ہیں۔ یہ اس موضوع کا ایک جامع جائزہ نہیں ہے؛ اس کے لیے پوری کتابیں وقف ہیں، لیکن یہ آپ کو شروع کرنے کے لیے کافی ہے۔ گڈ لک!

میرے مزید کام کے لیے یہاں دیکھیں (opens in a new tab)۔

صفحہ کی آخری تازہ کاری: 10 فروری، 2026

کیا یہ ٹیوٹوریل کارآمد تھا؟