ایتھیریم پر اپنا خود کا AI ٹریڈنگ ایجنٹ بنائیں
اس ٹیوٹوریل میں آپ سیکھیں گے کہ ایک سادہ AI ٹریڈنگ ایجنٹ کیسے بنایا جائے۔ یہ ایجنٹ ان مراحل کا استعمال کرتے ہوئے کام کرتا ہے:
- کسی ٹوکن کی موجودہ اور ماضی کی قیمتیں پڑھیں، ساتھ ہی دیگر ممکنہ طور پر متعلقہ معلومات بھی
- اس معلومات کے ساتھ ایک سوال تیار کریں، پس منظر کی معلومات کے ساتھ یہ بتانے کے لیے کہ یہ کس طرح متعلقہ ہو سکتا ہے
- سوال جمع کریں اور ایک متوقع قیمت واپس حاصل کریں
- سفارش کی بنیاد پر ٹریڈ کریں
- انتظار کریں اور دہرائیں
یہ ایجنٹ ظاہر کرتا ہے کہ معلومات کو کیسے پڑھا جائے، اسے ایک ایسے سوال میں ترجمہ کیا جائے جو قابل استعمال جواب دے، اور اس جواب کا استعمال کیا جائے۔ یہ سب ایک 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)) کے تحت شروع کرنے کے لیے اقدامات ہیں
-
اگر آپ کے پاس پہلے سے نہیں ہے تو، Python (opens in a new tab) ڈاؤن لوڈ اور انسٹال کریں۔
-
GitHub ریپوزٹری کو کلون کریں۔
1git clone https://github.com/qbzzt/260215-ai-agent.git -b 01-getting-started2cd 260215-ai-agent -
uv(opens in a new tab) انسٹال کریں۔ آپ کے سسٹم پر کمانڈ مختلف ہو سکتی ہے۔1pipx install uv -
لائبریریاں ڈاؤن لوڈ کریں۔
1uv sync -
ورچوئل ماحول کو فعال کریں۔
1source .venv/bin/activate -
یہ تصدیق کرنے کے لیے کہ Python اور Web3 صحیح طریقے سے کام کر رہے ہیں،
python3چلائیں اور اسے یہ پروگرام فراہم کریں۔ آپ اسے>>>پرامپٹ پر درج کر سکتے ہیں۔ فائل بنانے کی کوئی ضرورت نہیں ہے۔1from web3 import Web32MAINNET_URL = "https://eth.drpc.org"3w3 = Web3(Web3.HTTPProvider(MAINNET_URL))4w3.eth.block_number5quit()
بلاک چین سے پڑھنا
اگلا مرحلہ بلاک چین سے پڑھنا ہے۔ ایسا کرنے کے لیے، آپ کو 02-read-quote برانچ میں تبدیل ہونا ہوگا اور پھر پروگرام چلانے کے لیے uv کا استعمال کرنا ہوگا۔
1git checkout 02-read-quote2uv run agent.pyآپ کو Quote آبجیکٹس کی ایک فہرست موصول ہونی چاہیے، ہر ایک میں ایک ٹائم اسٹیمپ، ایک قیمت، اور اثاثہ (فی الحال ہمیشہ WETH/USDC)۔
یہاں لائن بہ لائن وضاحت ہے۔
1from web3 import Web32from web3.contract import Contract3from decimal import Decimal, ROUND_HALF_UP4from dataclasses import dataclass5from datetime import datetime, timezone6from pprint import pprint7import time8import functools9import 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 = 122MINUTE_BLOCKS = int(60 / BLOCK_TIME_SECONDS)3HOUR_BLOCKS = MINUTE_BLOCKS * 604DAY_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]67ERC20_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: str4 symbol: str5 decimals: int6 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: str4 token0: ERC20Token5 token1: ERC20Token6 contract: Contract7 asset: str8 decimal_factor: Decimal = 1Decimal (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 فلوٹنگ پوائنٹ ریاضی یا کسروں کو سپورٹ نہیں کرتا، اس لیے اصل قدر کے بجائے، جواب ہوتا ہے۔
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: str4 price: Decimal5 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()56 return ERC20Token(7 address=address,8 symbol=symbol,9 decimals=decimals,10 contract=token11 )سب دکھائیںیہ فنکشن ایک پتہ لیتا ہے اور اس پتے پر ٹوکن معاہدے کے بارے میں معلومات واپس کرتا ہے۔ ایک نیا 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)78 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.asset7 )اسے انسانوں اور بڑے لینگویج ماڈلز (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_BLOCKS7)89pprint(quotes)سب دکھائیںیہ اسکرپٹ کا مرکزی کوڈ ہے۔ پول کی معلومات پڑھیں، بارہ کوٹس حاصل کریں، اور انہیں pprint (opens in a new tab) کریں۔
ایک پرامپٹ بنانا
اگلا، ہمیں کوٹس کی اس فہرست کو LLM کے لیے ایک پرامپٹ میں تبدیل کرنا ہوگا اور ایک متوقع مستقبل کی قدر حاصل کرنی ہوگی۔
1git checkout 03-create-prompt2uv run agent.pyآؤٹ پٹ اب LLM کو ایک پرامپٹ ہوگا، جیسا کہ:
1یہ کوٹس دیے گئے ہیں:2اثاثہ: WETH/USDC3 2026-01-20T16:34 3016.214 .5 .6 .7 2026-02-01T17:49 2299.1089اثاثہ: WBTC/WETH10 2026-01-20T16:34 29.8411 .12 .13 .14 2026-02-01T17:50 33.46151617آپ توقع کریں گے کہ WETH/USDC کی قیمت وقت 2026-02-02T17:56 پر کیا ہوگی؟1819اپنا جواب دو اعشاریہ مقامات تک گول ایک ہی نمبر کے طور پر فراہم کریں،20کسی اور متن کے بغیر۔سب دکھائیںغور کریں کہ یہاں دو اثاثوں کے لیے کوٹس ہیں، WETH/USDC اور WBTC/WETH۔ کسی دوسرے اثاثے سے کوٹس شامل کرنے سے پیشین گوئی کی درستگی بہتر ہو سکتی ہے۔
ایک پرامپٹ کیسا لگتا ہے
اس پرامپٹ میں تین حصے ہیں، جو LLM پرامپٹس میں بہت عام ہیں۔
-
معلومات۔ LLMs کے پاس اپنی تربیت سے بہت سی معلومات ہوتی ہیں، لیکن ان کے پاس عام طور پر تازہ ترین معلومات نہیں ہوتیں۔ یہی وجہ ہے کہ ہمیں یہاں تازہ ترین کوٹس بازیافت کرنے کی ضرورت ہے۔ ایک پرامپٹ میں معلومات شامل کرنا ریٹریول آگمینٹڈ جنریشن (RAG) (opens in a new tab) کہلاتا ہے۔
-
اصل سوال۔ یہ وہ ہے جو ہم جاننا چاہتے ہیں۔
-
آؤٹ پٹ فارمیٹنگ ہدایات۔ عام طور پر، ایک 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 = False78 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 .56 return PoolInfo(7 .8 .9 .1011 asset= f"{token1.symbol}/{token0.symbol}" if reverse else f"{token0.symbol}/{token1.symbol}",12 reverse=reverse13 )سب دکھائیںیہ جاننے کے لیے کہ آیا کسی پول کو الٹنے کی ضرورت ہے، ہم اسے 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} پر کیا ہوگی؟23اپنا جواب دو اعشاریہ مقامات تک گول ایک ہی نمبر کے طور پر فراہم کریں،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)89wethwbtc_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_BLOCKS15)سب دکھائیںدونوں پولز کا جائزہ لیں اور دونوں سے کوٹس حاصل کریں۔
1future_time = (datetime.now(timezone.utc) + timedelta(days=1)).isoformat()[0:16]23print(make_prompt(wethusdc_quotes + wethwbtc_quotes, future_time, wethusdc_pool.asset))مستقبل کے اس وقت کا تعین کریں جس کے لیے ہم تخمینہ چاہتے ہیں، اور پرامپٹ بنائیں۔
LLM کے ساتھ انٹرفیسنگ
اگلا، ہم ایک حقیقی LLM کو پرامپٹ کرتے ہیں اور ایک متوقع مستقبل کی قدر حاصل کرتے ہیں۔ میں نے یہ پروگرام OpenAI کا استعمال کرتے ہوئے لکھا ہے، لہذا اگر آپ کوئی مختلف فراہم کنندہ استعمال کرنا چاہتے ہیں، تو آپ کو اسے ایڈجسٹ کرنا ہوگا۔
-
ایک OpenAI اکاؤنٹ (opens in a new tab) حاصل کریں
-
اکاؤنٹ میں فنڈ ڈالیں (opens in a new tab)—لکھنے کے وقت کم از کم رقم $5 ہے
-
کمانڈ لائن میں، API کلید برآمد کریں تاکہ آپ کا پروگرام اسے استعمال کر سکے
1export OPENAI_API_KEY=sk-<باقی کلید یہاں جاتی ہے> -
ایجنٹ کو چیک آؤٹ کریں اور چلائیں
1git checkout 04-interface-llm2uv run agent.py
یہاں نیا کوڈ ہے۔
1from openai import OpenAI23open_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].price34print ("موجودہ قیمت:", wethusdc_quotes[-1].price)5print(f"{future_time} میں، متوقع قیمت: {expected_price} USD")67if (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 USD22026-01-06T19:56 کے لیے پیشین گوئی: پیشین گوئی 3243.39 USD، اصل 3221.08 USD، غلطی 22.31 USD32026-01-07T20:02 کے لیے پیشین گوئی: پیشین گوئی 3223.24 USD، اصل 3146.89 USD، غلطی 76.35 USD42026-01-08T20:11 کے لیے پیشین گوئی: پیشین گوئی 3150.47 USD، اصل 3092.04 USD، غلطی 58.43 USD5.6.7.82026-01-31T22:33 کے لیے پیشین گوئی: پیشین گوئی 2637.73 USD، اصل 2417.77 USD، غلطی 219.96 USD92026-02-01T22:41 کے لیے پیشین گوئی: پیشین گوئی 2381.70 USD، اصل 2318.84 USD، غلطی 62.86 USD102026-02-02T22:49 کے لیے پیشین گوئی: پیشین گوئی 2234.91 USD، اصل 2349.28 USD، غلطی 114.37 USD1129 پیشین گوئیوں پر اوسط پیشین گوئی کی غلطی: 83.87103448275862068965517241 USD12فی سفارش اوسط تبدیلی: 4.787931034482758620689655172 USD13تبدیلیوں کا معیاری تغیر: 104.42 USD14منافع بخش دن: 51.72%15نقصان والے دن: 48.28%سب دکھائیںٹیسٹر کا زیادہ تر حصہ ایجنٹ کی طرح ہی ہے، لیکن یہاں وہ حصے ہیں جو نئے یا ترمیم شدہ ہیں۔
1CYCLES_FOR_TEST = 40 # بیک ٹیسٹ کے لیے، ہم کتنے سائیکلوں کی جانچ کرتے ہیں23# بہت سے کوٹس حاصل کریں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)1112wethwbtc_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_BLOCKS18)سب دکھائیںہم CYCLES_FOR_TEST (یہاں 40 کے طور پر بیان کیا گیا ہے) دن پیچھے دیکھتے ہیں۔
1# پیشین گوئیاں بنائیں اور انہیں حقیقی تاریخ کے خلاف چیک کریں23total_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].price3 prediction_time_price = wethusdc_quotes[index+CYCLES_BACK-1].priceپیشین گوئی کی گئی قیمت، حقیقی قیمت، اور پیشین گوئی کے وقت کی قیمت حاصل کریں۔ یہ تعین کرنے کے لیے کہ سفارش خریدنے کی تھی یا بیچنے کی، ہمیں پیشین گوئی کے وقت کی قیمت کی ضرورت ہے۔
1 error = abs(predicted_price - real_price)2 total_error += error3 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_price3 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")23length_changes = Decimal(len(changes))4mean_change = sum(changes, Decimal(0)) / length_changes5print (f"Mean change per recommendation: {mean_change} USD")6var = sum((x - mean_change) ** 2 for x in changes) / length_changes7print (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) کا استعمال کریں۔ نتیجہ ایک فلٹر آبجیکٹ ہے، جسے ہمیں لمبائی حاصل کرنے کے لیے ایک فہرست میں تبدیل کرنے کی ضرورت ہے۔
ٹرانزیکشنز جمع کرنا
اب ہمیں اصل میں ٹرانزیکشنز جمع کرنے کی ضرورت ہے۔ تاہم، میں اس وقت حقیقی رقم خرچ نہیں کرنا چاہتا، اس سے پہلے کہ سسٹم ثابت ہو جائے۔ اس کے بجائے، ہم مین نیٹ کا ایک مقامی فورک بنائیں گے، اور اس نیٹ ورک پر "ٹریڈ" کریں گے۔
یہاں ایک مقامی فورک بنانے اور ٹریڈنگ کو فعال کرنے کے اقدامات ہیں۔
-
Foundry (opens in a new tab) انسٹال کریں
-
anvil(opens in a new tab) شروع کریں1anvil --fork-url https://eth.drpc.org --block-time 12anvilFoundry کے لیے ڈیفالٹ URL، http://localhost:8545 (opens in a new tab) پر سن رہا ہے، لہذا ہمیںcastکمانڈ (opens in a new tab) کے لیے URL کی وضاحت کرنے کی ضرورت نہیں ہے جسے ہم بلاک چین میں ہیرا پھیری کے لیے استعمال کرتے ہیں۔ -
anvilمیں چلتے وقت، دس ٹیسٹ اکاؤنٹس ہیں جن میں ETH ہے — پہلے والے کے لیے ماحولیاتی متغیرات سیٹ کریں1PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff802ADDRESS=`cast wallet address $PRIVATE_KEY` -
یہ وہ معاہدے ہیں جنہیں ہمیں استعمال کرنے کی ضرورت ہے۔
SwapRouter(opens in a new tab) Uniswap v3 معاہدہ ہے جسے ہم اصل میں ٹریڈ کرنے کے لیے استعمال کرتے ہیں۔ ہم براہ راست پول کے ذریعے ٹریڈ کر سکتے ہیں، لیکن یہ بہت آسان ہے۔نیچے کے دو متغیرات Uniswap v3 کے راستے ہیں جو WETH اور USDC کے درمیان تبادلہ کرنے کے لیے درکار ہیں۔
1WETH_ADDRESS=0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc22USDC_ADDRESS=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB483POOL_ADDRESS=0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f56404SWAP_ROUTER=0xE592427A0AEce92De3Edee1F18E0157C058615645WETH_TO_USDC=0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc20001F4A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB486USDC_TO_WETH=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB480001F4C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 -
ہر ٹیسٹ اکاؤنٹ میں 10,000 ETH ہیں۔ ٹریڈنگ کے لیے 1000 WETH حاصل کرنے کے لیے 1000 ETH کو لپیٹنے کے لیے WETH معاہدہ استعمال کریں۔
1cast send $WETH_ADDRESS "deposit()" --value 1000ether --private-key $PRIVATE_KEY -
USDC کے لیے 500 WETH ٹریڈ کرنے کے لیے
SwapRouterکا استعمال کریں۔1cast send $WETH_ADDRESS "approve(address,uint256)" $SWAP_ROUTER 500ether --private-key $PRIVATE_KEY2MAXINT=`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_KEYapproveکال ایک الاؤنس بناتی ہے جوSwapRouterکو ہمارے کچھ ٹوکنز خرچ کرنے کی اجازت دیتی ہے۔ معاہدے واقعات کی نگرانی نہیں کر سکتے، لہذا اگر ہم براہ راستSwapRouterمعاہدے میں ٹوکن منتقل کرتے ہیں، تو اسے یہ معلوم نہیں ہوگا کہ اسے ادائیگی کی گئی ہے۔ اس کے بجائے، ہمSwapRouterمعاہدے کو ایک خاص رقم خرچ کرنے کی اجازت دیتے ہیں، اور پھرSwapRouterیہ کرتا ہے۔ یہSwapRouterکے ذریعے کال کیے گئے فنکشن کے ذریعے کیا جاتا ہے، لہذا یہ جانتا ہے کہ آیا یہ کامیاب تھا۔ -
تصدیق کریں کہ آپ کے پاس دونوں ٹوکنز کافی ہیں۔
1cast call $WETH_ADDRESS "balanceOf(address)" $ADDRESS | cast from-wei2echo `cast call $USDC_ADDRESS "balanceOf(address)" $ADDRESS | cast to-dec`/10^6 | bc
اب جب کہ ہمارے پاس WETH اور USDC ہے، ہم اصل میں ایجنٹ چلا سکتے ہیں۔
1git checkout 05-trade2uv run agent.pyآؤٹ پٹ اس جیسا نظر آئے گا:
1(ai-trading-agent) qbzzt@Ori-Cloudnomics:~/260215-ai-agent$ uv run agent.py2موجودہ قیمت: 1843.1632026-02-06T23:07 میں، متوقع قیمت: 1724.41 USD4ٹریڈ سے پہلے اکاؤنٹ بیلنس:5USDC بیلنس: 927301.5782726WETH بیلنس: 5007بیچیں، مجھے امید ہے کہ قیمت 118.75 USD تک گر جائے گی8منظور شدہ ٹرانزیکشن بھیجی گئی: 74e367ddbb407c1aaf567d87aa5863049991b1d2aa092b6b85195d925e2bd41f9منظور شدہ ٹرانزیکشن مائن ہو گئی۔10فروخت ٹرانزیکشن بھیجی گئی: fad1bcf938585c9e90364b26ac7a80eea9efd34c37e5db81e58d7655bcae28bf11فروخت ٹرانزیکشن مائن ہو گئی۔12ٹریڈ کے بعد اکاؤنٹ بیلنس:13USDC بیلنس: 929143.79711614WETH بیلنس: 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_ABI5)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.")101112def 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()45 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()34if (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()1011print("ٹریڈ کے بعد اکاؤنٹ بیلنس:")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