ابتدائی ایف ایم زیڈ حکمت عملی ڈیزائن میں ، اگر غیر ہم آہنگ ہم آہنگی کا استعمال کرنے کی ضرورت ہو تو صرف استعمال کیا جاسکتا ہے۔exchange.Go()
افعال کو ایف ایم زیڈ پیکڈ انٹرفیس کے ساتھ مل کر انجام دینے کے لئے استعمال کیا جاتا ہے ، لہذا کچھ اپنی مرضی کے مطابق کارروائیوں (فنکشن) کو بیک وقت انجام نہیں دیا جاسکتا ہے۔ اگرچہ اس طرح کا ڈیزائن حکمت عملی کے پروگراموں کو انجام دینے میں بہت زیادہ کارکردگی کا مظاہرہ کرتا ہے ، لیکن مقامی پروگرامنگ زبانوں میں متوازی ڈیزائن کے تجربے کے حامل ساتھیوں کے لئے یہ عام طور پر غیر معمولی محسوس ہوتا ہے۔
یہاں تک کہ نئے طالب علموں کو FMZ کے ساتھ مقداری تجارت کا استعمال کرتے ہوئے سمجھ نہیں آتاexchange.Go()
افعال کا استعمال، استعمالexchange.Go()
یہ اب بھی ایک ترتیب میں عملدرآمد شدہ کوڈ میں ایک عملدرآمد کے بیان کے بعد ایک عملدرآمد لگتا ہے۔ تو پھر اس مضمون میں ہم FMZ پلیٹ فارم کے لئے نئی متوازی دھاگوں کی خصوصیات کو دریافت کریں گے:__Thread()
مثال کے طور پر سیریز افعال کے استعمال اور حکمت عملی کے طریقہ کار کے متضاد ڈیزائن.
اگر ہم چاہتے ہیں کہ پالیسی کا مرکزی دھاگہ ایک ہی وقت میں چلتا رہے اور ہم اپنی مرضی کے مطابق فنکشن کو انجام دینے کے لئے ایک ذیلی دھاگہ چلاتے رہیں تو ہم مندرجہ ذیل کوڈ کی طرح ڈیزائن استعمال کرسکتے ہیں۔ پالیسی کوڈ میں ایک فنکشن کو اپنی مرضی کے مطابق بنائیں۔GetTickerAsync()
اس فنکشن کو لکھنے کے لئے ایک مخصوص کام کرتا ہے. یہ ایک موت کا لوپ انجام دیتا ہے.while
ایف ایم زیڈ کے لئے API انٹرفیس جس میں لوپ میں مسلسل کال کی جاتی ہے:GetTicker()
اس کے علاوہ ، آپ کو اس کے بارے میں مزید جاننے کی ضرورت ہے۔
پھر دوبارہ استعمال کریں__threadSetData(0, "ticker", t)
اس کا مطلب یہ ہے کہ یہ ایک ڈیٹا کو مین سٹرنگ میں لکھتا ہے، جس کا نام ڈیٹا نام ہے.ticker
اعداد و شمار کی قدرt
یعنیGetTicker()
اس کا مطلب یہ ہے کہ آپ کو اس کی قیمت واپس کرنا چاہئے.
__threadSetData(0, "ticker", t)
اور پھر ہم نے اپنی مرضی کے مطابق افعال کو ڈیزائن کیا ہے جو کہ ایک ساتھ چلتے ہیں اور پھر ہم اسے لکھ سکتے ہیںmain()
آپ کو یہ بھی پتہ چل جائے گا کہ آپ کو کیا کرنا ہے.main()
فنکشن شروع ہوتا ہے، ہم استعمال کرتے ہیں:
__Thread(GetTickerAsync, 0) // GetTickerAsync为需要并发执行的自定义函数,0为这个传入GetTickerAsync函数的参数
ایک متوازی تھریڈ بناتا ہے، اور یہ تھریڈ شروع ہوتا ہےGetTickerAsync()
فنکشن.main()
فنکشن اپنے آپ کو انجام دیتا ہے.while
گردش، گردش میں وصولGetTickerAsync()
فنکشن اپ ڈیٹ شدہ ڈیٹا پرنٹ کرتا ہے:
var t = __threadGetData(0, "ticker")
Log(t)
مکمل کوڈ مثال:
function GetTickerAsync(index) {
while (true) {
var t = exchanges[index].GetTicker()
__threadSetData(0, "ticker", t)
Sleep(500)
}
}
function main() {
__Thread(GetTickerAsync, 0)
while(true) {
var t = __threadGetData(0, "ticker")
Log(t)
Sleep(1000)
}
}
ریئل ڈسک پر ٹیسٹ:
یہ سب سے آسان ایپلی کیشن ڈیزائن ہے، اور اب ہم کچھ دیگر ضروریات کے ڈیزائن پر نظر ڈالیں گے۔
ایک فنکشن کو ڈیزائن کیا جاسکتا ہے جس میں بیک وقت 10 تھریڈز بنائے جاسکتے ہیں ، ہر تھریڈ میں ایک ذیلی آپریشن فنکشن انجام دیا جاتا ہے۔main()
ایک فنکشن میں ڈیزائن کریںwhile
اس کے علاوہ ، آپ کو ایک بار پھر ایک بار پھر ایک بار پھر ایک بار پھر ایک بار پھر ایک بار پھر ایک بار پھر ایک بار پھر ایک بار پھر ایک بار پھر ایک بار پھر ایک بار پھر ایک بار پھر ایک بار پھر ایک بار پھر.placeMultipleOrders
اور اس کے بعد ہم اس کو کال کریں گے.testPlaceMultipleOrders()
。
if (cmd == "placeMultipleOrders") {
// ...
}
پالیسیوں میں ترمیم کے صفحے پر پالیسیوں کے انٹرایکٹو ڈیزائن کو شامل کریں، ایک بٹن مقرر کریں، اور حکم دیں: placeMultipleOrders
مکمل کوڈ مثال:
function placeOrder(exIndex, type, price, amount) {
var id = null
if (type == "Buy") {
id = exchanges[exIndex].Buy(price, amount)
} else if (type == "Sell") {
id = exchanges[exIndex].Sell(price, amount)
} else {
throw "type error! type:" + type
}
}
function testPlaceMultipleOrders(index, beginPrice, endPrice, step, type, amount) {
Log("beginPrice:", beginPrice, ", endPrice:", endPrice, ", step:", step, ", type:", type, ", amount:", amount)
var tids = []
for (var p = beginPrice; p <= endPrice; p += step) {
var tid = __Thread(placeOrder, index, type, p, amount)
tids.push(tid)
Sleep(10)
}
Sleep(1000)
for (var i = 0; i < tids.length; i++) {
__threadTerminate(tids[i])
}
}
function main() {
while(true) {
LogStatus(_D())
var cmd = GetCommand()
if (cmd) {
if (cmd == "placeMultipleOrders") {
var t = _C(exchange.GetTicker)
var beginPrice = t.Last * 0.8
var endPrice = t.Last * 0.9
var step = t.Last * 0.01
testPlaceMultipleOrders(0, beginPrice, endPrice, step, "Buy", 0.01)
var orders = exchange.GetOrders()
for (var i = 0; i < orders.length; i++) {
Log(orders[i])
}
}
}
Sleep(1000)
}
}
ٹیسٹ کا استعمال کرتے ہوئے ہونگ مینجمنٹ کا طریقہ ، موجودہ قیمت سے 80٪ ~ 90٪ تک بڑھتا ہوا ، ایک ڈسک ماحول ٹیسٹ کا استعمال کرتے ہوئے ، ایک انٹرایکٹو بٹن پر کلک کرنے سے ٹیسٹ کا آغاز ہوتا ہے:
"پلائس ملٹی آرڈرز" بٹن پر کلک کرنے کے بعد ، یہ اشارہ کرتا ہے:
اسٹریٹیجی لاگ میں دکھایا گیا ہے:
یہ ضرورت ایک FMZ صارف کی طرف سے پیش کی گئی تھی، جس نے امید کی تھی کہ ہم ایک سادہ مثال دکھائیں گے کہ ہم آہنگ موضوعات میں کس طرح استعمال کرنا ہے.ویب ساکٹاس کے علاوہ، ہم نے اس کے بارے میں بات چیت کی ہے کہ کس طرح ہم اس کے بارے میں بات کر سکتے ہیں.main()
فنکشن۔
اصل میں یہ بہت آسان ہے، اور یہ پچھلے مثال کے طور پر متوازی دھاگہ تخلیق کرنے کے لئے تقریبا ہے؛ لیکن دھاگہ کے درمیان مواصلات کے لئے استعمال کیا جاتا ہے__threadPeekMessage()
افعال اور__threadPostMessage()
فنکشن: بِنآن ایکسچینج کے ویب ساکٹ API انٹرفیس کال کی مثال کے طور پر، ڈیزائن میں ہمیں ویب ساکٹ کنکشن کے بند ہونے کے عمل پر بھی توجہ دینے کی ضرورت ہے، مندرجہ ذیل مثال میں بھی دکھایا گیا ہے کہ کس طرح ایک متوازی تھریڈ کو مطلع کیا جائے اور اسے روک دیا جائے۔
مکمل کوڈ مثال:
var tid = null
function createWS() {
// wss://stream.binance.com:9443/ws/<streamName> , <symbol>@ticker
var stream = "wss://stream.binance.com:9443/ws/btcusdt@ticker"
var ws = Dial(stream)
Log("创建WS连接:", stream)
while (true) {
var data = ws.read()
if (data) {
__threadPostMessage(0, data)
}
Log("接收到WS链接推送的数据,data:", data)
// __threadPeekMessage 超时参数设置-1,不阻塞
var msg = __threadPeekMessage(-1)
if (msg) {
if (msg == "stop") {
Log("并发线程Id:", __threadId(), "接收到stop指令")
break
}
}
}
Log("并发线程执行完毕,关闭ws连接")
ws.close()
}
function main() {
tid = __Thread(createWS)
Log("创建并发线程,线程Id:", tid)
while(true) {
// __threadPeekMessage 的超时参数设置为0,阻塞等待数据
var data = __threadPeekMessage(0)
Log("接收到并发线程", ", Id:", tid, ", 发送的数据,data:", data, "#FF0000")
var tbl = {
type : "table",
title : "<symbol>@ticker频道推送消息",
cols : ["事件类型", "事件时间", "交易对", "24小时价格变化", "24小时价格变化百分比", "平均价格", "最新成交价格", "24小时内成交量", "24小时内成交额"],
rows : []
}
try {
data = JSON.parse(data)
tbl.rows.push([data.e, _D(data.E), data.s, data.p, data.P, data.w, data.c, data.v, data.q])
} catch (e) {
Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
}
LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`")
}
}
function onexit() {
Log("扫尾函数,向Id为", tid, "的并发线程发送stop指令")
__threadPostMessage(tid, "stop")
Log("等待Id为", tid, "的并发线程停止")
__threadJoin(tid)
Log("扫尾函数执行完毕")
}
ریئل ڈسک پر ٹیسٹ:
آپ دیکھ سکتے ہیںmain()
اس فنکشن میں مسلسل ویب ساکٹ کنکشن سے آنے والے ٹریڈنگ ڈیٹا کو وصول کیا جاتا ہے جو بیک وقت دھاگہ کے ذریعہ تخلیق کیا جاتا ہے۔
جب حکمت عملی کو بند کر دیا جاتا ہے تو ، صفائی کا کام شروع ہوجاتا ہے:
اسپارٹا کھیلنے کی مقدارایک آخری مثال کے طور پر، اگر آپ کے پاس بہت سے ڈبلیو ایس تھریڈز ہیں اور آپ کے پاس بہت سے موضوعات ہیں، تو آپ کو یہ معلوم ہونا چاہئے کہ اگر آپ کے پاس بہت سے تھریڈز ہیں، تو آپ کو کس چیز کو بہتر طور پر استعمال کرنا چاہئے؟
اسپارٹا کھیلنے کی مقدارتاروں کے مابین متغیرات کا اشتراک کرنے کا بنیادی نفاذ متغیرات کا حوالہ دینے کی حمایت نہیں کرتا ہے ، اور ہر تازہ کاری کے ساتھ اسے دوبارہ ترتیب دینا پڑتا ہے ، جو کم موثر ہے۔
ایجاد کاروں کی مقدار - خواباس کے علاوہ ، آپ کو اس کے بارے میں مزید جاننے کی ضرورت ہے۔