ایک بار جب آپ نے اپنے دوستوں کے ساتھ جاوا اسکرپٹ کھیلنا شروع کیا تو ، آپ کو یہ جاننے کی ضرورت ہوگی کہ یہ کیوں کام کرتا ہے ، اور آپ کو یہ جاننے کی ضرورت ہوگی کہ یہ کیسے کام کرتا ہے۔

مصنف:چھوٹا سا خواب, تخلیق: 2017-03-16 12:29:51, تازہ کاری: 2017-10-11 10:37:54

ایک مفید ٹول کے لئے یہ جاننا ضروری ہے کہ یہ کیوں مفید ہے!

آپ کے لئے یہ بہت اچھا ہے کہ آپ ہفتہ کے دن حکمت عملی لکھتے ہیں ، اور ہر روز خالی خیالات ایڈیٹر پر آتے ہیں ، شاید یہ آپ کا اگلا ٹاسک ہو ، سوچنے کے لئے بہت پرجوش! اس جذبے پر اثر انداز ہونے والا واحد چیز یہ ہے کہ تجارتی حکمت عملی کے نظام کے لئے خرید و فروخت کی منطق کو سنبھالنا ضروری ہے ، حالانکہ یہ تجارتی ماڈیول کو سنبھالنے کے لئے ضروری ہے ، لیکن یہ کچھ حد تک سست ہے اور اس کی منطق زیادہ پیچیدہ ہے۔

  • یہ بہت اچھا ہے کہ ایک اچھی طرح سے لکھا ہوا ماڈیول ہے جو براہ راست استعمال کیا جاسکتا ہے (پہلے والے مضامین میں اس کا استعمال کیا گیا ہے) ، لیکن اس کے علاوہ اس کا استعمال کرنے اور اس کے کام کرنے کا طریقہ سیکھنے کے لئے ، میں نے کوڈ پر تبصرہ کیا:

/* Interval ناکام ریٹیسٹ وقفہ ((ملی سیکنڈ) عددی شکل ((نمبر) 500 سلائیڈ ٹِک سلائیڈ قیمت پوائنٹس کی تعداد ((پوری تعداد) عددی شکل ((نمبر) 1) RiskControl ونڈ کنٹرول آن کریں بُل قسم ((true/false) false MaxTrade@RiskControl کاروباری دن میں زیادہ سے زیادہ ٹریڈنگ ٹرانزیکشنز کی تعداد عددی شکل ((نمبر) 50 MaxTradeAmount@RiskControl ایک قلم کی زیادہ سے زیادہ تعداد ایک عدد (number) 1000 */

var __orderCount = 0 // موجودہ کام کے دن کی اگلی تعداد ریکارڈ کرتا ہے var __orderDay = 0 // موجودہ کام کے دن کی تاریخ ریکارڈ کرتا ہے

function CanTrade ((tradeAmount) { // رسک کنٹرول ماڈیول، پیرامیٹر: ٹرانزیکشن کی تعداد if (!RiskControl) { // پہلے سے طے شدہ طور پر ونڈ کنٹرول ماڈیول کو غیر فعال کریں ، اگر یہ غیر فعال ہے تو ، CanTrade فنکشن true لوٹاتا ہے واپسی درست } if (typeof(tradeAmount) == number && tradeAmount > MaxTradeAmount) { // tradeAmount کی قسم درج کریں، اور ٹائپ کریں کہ ٹائپ کیا گیا ہے، اور ٹائپ کریں کہ ٹائپ کیا گیا ہے۔ Log ((تندور کنٹرول ماڈیول کی حد ، زیادہ سے زیادہ ڈاؤن لوڈ کی مقدار سے زیادہ ، MaxTradeAmount ، #ff0000 @) ؛ // اشارہ کی معلومات کی پیداوار ، عملدرآمد کو روکیں۔ تھرو ہولڈ کو روکنے کے لئے ہولڈ پر عملدرآمد واپس جھوٹا؛ } var nowDay = new Date (().getDate ((); // موجودہ تاریخ حاصل کریں if (nowDay!= __orderDay) { // getDate() Date آبجیکٹ سے ایک مہینے میں کسی دن (1 ~ 31) لوٹاتا ہے۔ __orderDay پہلی بار کے لئے nowDay کے برابر نہیں ہوگا __orderDay = nowDay؛ // __orderDay گلوبل متغیر ہوا کے کنٹرول ماڈیول میں پہلی بار داخل ہونے کی ٹرگر کی تاریخ کو ریکارڈ کرتا ہے۔ ہر تاریخ میں تبدیلی ہوتی ہے ، لیکن یہ ایک بار جب آپ ہوا کے کنٹرول ماڈیول میں داخل ہوتے ہیں تو ، آپ کو ایک بار پھر ٹرگر کی تاریخ کو ریکارڈ کرنا پڑتا ہے۔ __orderCount = 0؛ // __orderDay متغیر کو اپ ڈیٹ کریں، __orderCount متغیر کو دوبارہ ترتیب دیں } __orderCount++; // عالمی متغیر __orderCount اگلی واحد تعداد، خود جمع۔ if (__orderCount > MaxTrade) { // اس بات کا تعین کرتا ہے کہ آیا پیرامیٹرز کی حد سے زیادہ ہے ایک دن میں زیادہ سے زیادہ تجارت Log ((تندور کنٹرول ماڈیول کی حد ، تجارت نہیں کی جاسکتی ، زیادہ سے زیادہ نچلی واحد تعداد سے زیادہ ٹن ، میکس ٹریڈ ، #ff0000 @) ؛ // زیادہ سے زیادہ ، اشارہ کی معلومات کی پیداوار ، عملدرآمد کو روکیں۔ تھرو ہولڈ کو روکنے کے لئے ہولڈ پر عملدرآمد واپس جھوٹا؛ } واپسی درست؛ // مندرجہ بالا شرائط میں سے کوئی بھی متحرک نہیں ہے ، واپسی درست ، یعنی تجارت کی جا سکتی ہے۔ }

function init ((() { // ٹیمپلیٹ ابتدائیہ فنکشن ، جب ٹیمپلیٹ لوڈ ہوتا ہے تو پہلے اس فنکشن کو انجام دیتا ہے۔ if (typeof (((SlideTick) === undefined) { // چیک کریں کہ آیا سلائیڈ ٹِک غیر متعین ہے۔ SlideTick = 1; // سیٹ کریں ڈیفالٹ 1 } else { // تجزیہ کی سٹرنگ کو عددی میں تبدیل کیا جاتا ہے، تاہم اگر یہ غیر عددی حروف کے آغاز پر سٹرنگ ہے تو یہ NaN واپس کرے گا، جو غلطی کا سبب بن سکتا ہے SlideTick = parseInt ((سلائیڈ ٹِک) ؛ } Log (جاری ہے) }

function GetPosition ((e, contractType, direction, positions) { // ایک معاہدے کی اسی سمت کی گزشتہ پوزیشن کی موجودہ پوزیشن کو یکجا کریں، پیرامیٹرز یہ ہیں: ایکسچینج آبجیکٹ، معاہدہ کی قسم، سمت، API واپس آنے والے اسٹوریج ڈیٹا ((خالی ہے)
var allCost = 0؛ // contractType معاہدہ direction direction میں کل خرچ کی گئی رقم ، ایک ہاتھ کے معاہدے میں کتنے حصوں میں ضرب نہیں دی گئی ((کیونکہ مجموعی طور پر معاہدہ کیا جاسکتا ہے) var allAmount = 0؛ // کل معاہدے کے ہاتھ کی تعداد var allProfit = 0؛ // مجموعی طور پر منافع اور نقصان var allFrozen = 0؛ // کل منجمد تعداد var pos Margin = 0; // ہولڈنگ معاہدہ لیورج if (typeof(positions) === undefinedᅢ!positions) { // اگر پیرامیٹر API میں منتقل نہیں کیا گیا ہے تو اسٹوریج کی معلومات واپس کریں positions = _C ((e.GetPosition) ؛ // اس کے بعد API کو کال کریں اور اسٹوریج کی معلومات حاصل کریں۔ } for (var i = 0; i < positions.length; i++) { // اس ذخیرہ شدہ معلومات کے صف میں گھومتا ہے۔ if (positions[i].ContractType == contractType && // موجودہ انڈیکس کی ہولڈنگ کی معلومات کا معاہدہ کوڈ == پیرامیٹر کے ذریعہ مخصوص معاہدہ کوڈ ((contractType) اور سمت اس سمت کے برابر ہے جس میں پیرامیٹر منتقل ہوتا ہے ((direction) موجودہ پوزیشن یا پچھلی پوزیشن (((positions[i].Type == PD_LONG کے لئے positions[i].Type == PD_LONG_YD) && direction == PD_LONG) کے لئے ((positions[i].Type == PD_SHORT کے لئے positions[i].Type == PD_SHORT_YD) && direction == PD_SHORT)) ) { // if بلاک کو پورا کرتا ہے posMargin = positions[i].MarginLevel; // لیول ویلیو حاصل کریں posMargin کو قدر دیں allCost += (positions[i].Price * positions[i].Amount); // کل اخراجات ((ایک ہاتھ کے معاہدوں کی تعداد ، موجودہ انڈیکس ہولڈنگ قیمت * ہولڈنگ کی مقدار) مجموعی) allAmount += positions[i].Amount؛ // معاہدہ کرنے والے ہاتھوں کی تعداد allProfit += positions[i].Profit؛ // معاہدہ فلوٹنگ منافع اور نقصان مجموعی allFrozen += positions[i].FrozenAmount؛ // منجمد ہونے والے معاہدوں کی کل تعداد } } if (allAmount === 0) { // اگر کوریج مکمل ہونے کے بعد قابل معاہدے کے ہاتھوں کی مجموعی تعداد 0 ہے تو ، null لوٹاتا ہے ، یعنی بغیر کسی شرائط کے محدود معاہدے کا انعقاد واپسی null؛ } return { // allAmount غیر 0، ایک اعتراض جمع کرنے کے بعد ذخیرہ کی معلومات واپس کرتا ہے۔ مارجن لیول: پوسٹ مارجن، FrozenAmount: تمام منجمد، قیمت: _N ((allCost / allAmount) Amount: allAmount، Profit: allProfit، ٹائپ: سمت، ContractType: contractType معاہدہ کی قسم }؛ }

function Open ((e, contractType, direction, opAmount) { // آپریٹنگ ایک قسم کے معاہدے کی کھولی ہوئی تجارت کی تقریب، پیرامیٹرز: ایکسچینج آبجیکٹ، معاہدہ کوڈ، سمت، آپریشن کی تعداد var initPosition = GetPosition ((e, contractType, direction); // اوپر والے GetPosition فنکشن کو کال کرنے کے بعد جمع شدہ اسٹوریج کی معلومات حاصل کرتا ہے۔ var isFirst = true; // isFirst ٹیگ سیٹ کریں (بیان کرتا ہے کہ مندرجہ ذیل whilst پہلی بار کے لئے سچ ہے) var initAmount = initPosition ؟ initPosition.Amount : 0؛ // اگر initPosition null ہے تو initAmount کو 0 تفویض کریں ، ورنہ initPosition.Amount کو تفویض کریں var positionNow = initPosition؛ // ایک متغیر positionNow کا اعلان کرتا ہے جو موجودہ اسٹوریج کی معلومات کو ظاہر کرتا ہے while (true) { // while لپیٹ var needOpen = opAmount; // عارضی متغیر needOpen کا اعلان کرتا ہے اور اس کو پیرامیٹرز کی مقدار کے ساتھ ایک قدر دیتا ہے جس میں ٹرانزیکشن کی ضرورت ہوتی ہے if (isFirst) { // اگر یہ پہلی بار چل رہا ہے تو ، صرف isFirst کو اپ ڈیٹ کریں۔ یہ غلط کے طور پر نشان لگا دیا گیا ہے ، کیونکہ اپ ڈیٹ غلط ہے۔ اگلا لوپ اس وقت تک else بلاک پر عملدرآمد کرے گا۔ isFirst = false؛ } else { positionNow = GetPosition ((e, contractType, direction); // positionNow کو اپ ڈیٹ کریں ، موجودہ اسٹوریج کی معلومات۔ if (positionNow) { // اگر ہولڈنگ کی معلومات موجود ہیں تو ، اگلی تعداد میں ہولڈنگ کرنے کی ضرورت ہے needOpen برابر ہے پیرامیٹر کی ضرورت کی کارروائی کی مقدار کو کم کریں اس وقت حاصل کی جانے والی ہولڈنگ کی معلومات کا فرق پچھلے (یعنی کتنے نئے ہاتھ کھولے گئے ہیں) needOpen = opAmount - (positionNow.Amount - initAmount); } } var insDetail = _C ((e.SetContractType, contractType); // معاہدہ کی قسم مقرر کریں۔ // Log ((شروعاتی ذخیرہ کرنے کی ٹوکری ، initAmount ، موجودہ ذخیرہ کرنے کی ٹوکری ، positionNow ، ضرورت کی ٹوکری ، needOpen) ؛ if (needOpen < insDetail.MinLimitOrderVolume) { // اگر اگلی پوزیشن کھولنے کی تعداد اس معاہدے کی حد کی فہرست میں کم سے کم پوزیشن کھولنے کی تعداد سے کم ہے break؛ // لوپ سے باہر نکلیں } if (!CanTrade(opAmount)) { // ونڈ کنٹرول ماڈیول کا پتہ لگاتا ہے، اگر غلط واپس آتا ہے تو، چکر سے باہر نکلیں اور تجارت نہ کریں۔ break؛ } var depth = _C ((e.GetDepth) ؛ // مارکیٹ کی گہرائی کی معلومات حاصل کریں۔ var amount = Math.min ((insDetail.MaxLimitOrderVolume, needOpen); // محدود کریں کہ کم از کم مقدار معاہدے کی حد سے زیادہ نہیں ہوسکتی ہے e.SetDirection ((direction == PD_LONG? buy: sell); // پیرامیٹر direction کے مطابق نیچے کی سمت مقرر کریں۔ var orderId؛ if (direction == PD_LONG) { // پیرامیٹر direction کی سمت کے مطابق مختلف API کو کال کریں تاکہ لین دین کیا جا سکے ((کافی یا خالی) orderId = e.Buy ((depth.Asks[0].Price + (insDetail.PriceTick * SlideTick) ، Math.min ((amount، depth.Asks[0].Amount) ، contractType، Ask، depth.Asks[0]؛ // API دستاویزات کو دیکھیں، CTP اشیاء کی مستقبل کی قیمت میں ایک چھلانگ insDetail.PriceTick کے لئے، اس قدر کے پورے گنا ہونا ضروری ہے // API کو بلانے کے لئے اصل ڈاؤن لوڈ، اتارنا کی مقدار ایک صف کی مقدار سے زیادہ نہیں ہے } else { orderId = e.Sell ((depth.Bids[0].Price - (insDetail.PriceTick * SlideTick) ، Math.min ((amount، depth.Bids[0].Amount) ، contractType، Bid، depth.Bids[0]); } // منسوخ کریںPendingOrders while (true) { // آرڈر دینے کے بعد ایک Interval وقت کے وقفے کے ساتھ، غیر مکمل احکامات منسوخ کریں۔ نیند (انٹراول) var orders = _C ((e.GetOrders) ؛ // تمام نامکمل احکامات حاصل کرتا ہے if (orders.length === 0) { // اگر orders خالی صف ہے تو ، موجودہ while کو چھوڑ دیں break؛ } for (var j = 0; j < orders.length; j++) { // نامکمل احکامات کی صفوں میں گھومتا ہے e.CancelOrder ((orders[j].Id) ؛ // موجودہ انڈیکس میں آرڈر کی معلومات میں آئی ڈی کے مطابق آرڈر منسوخ کریں۔ if (j < (orders.length - 1)) { // وقفے وقفے سے گزرتا ہے ، ایک طرف فریکوئنسی بہت زیادہ ہے۔ Sleep ((Interval) ؛ // Sleep وقفہ وقفہ ملی سیکنڈ } } } } // اگر مین لوپ while سے باہر نکلتا ہے var ret = { // واپس کرنے کے لئے استعمال کیا جاتا ہے ایک اعتراض کا اعلان قیمت: 0، // اوسط قیمت رقم: 0 position: positionNow // حال ہی میں حاصل کردہ اس قسم کی اسٹوریج کی معلومات }؛ if (!positionNow) { // اگر کوئی اسٹوریج کی معلومات نہیں ہے تو ، براہ راست ابتدائیہ ریٹ کو واپس کریں واپسی ret؛ } if (!initPosition) { // اگر موجودہ فنکشن کو شروع کرنے پر اس قسم کی کوئی اسٹوریج کی معلومات موجود نہیں ہے۔‬ ret.price = positionNow.Price; // موجودہ ہولڈنگ کی معلومات positionNow میں قیمت اس ٹرانزیکشن کے اختتام پر ہولڈنگ کی اوسط قیمت ہے ret.amount = positionNow.Amount؛ // اسی طرح } else { // اگر شروع میں اس قسم کے بارے میں ذخیرہ شدہ معلومات موجود ہیں۔ ret.amount = positionNow.Amount - initPosition.Amount؛ // فرق نئی پوزیشنوں کی تعداد کا ہے ret.price = _N(((positionNow.Price * positionNow.Amount) - (initPosition.Price * initPosition.Amount)) / ret.amount) ؛ // اس ٹرانزیکشن کے نئے اضافے کی لاگت کو اس ٹرانزیکشن کی اوسط قیمت کے علاوہ نئی پوزیشن کھولنے سے حاصل کیا جاتا ہے۔ } return ret؛ // واپس لوٹنا ret }

function Cover ((e, contractType) { // ایک قسم کا ہموار فنکشن ، پیرامیٹر: ایکسچینج آبجیکٹ ، معاہدہ کوڈ var insDetail = _C ((e.SetContractType, contractType); // معاہدہ کی قسم مقرر کریں while (true) { // while مین سائیکل var n = 0؛ // ہموار آپریشن گنتی var opAmount = 0؛ // اعلان آپریشن متغیر var positions = _C ((e.GetPosition) ؛ // API کو کال کریں حاصل کریں ذخیرہ کرنے کی معلومات ، مندرجہ بالا فرق کریں حاصل کریں ذخیرہ کرنے کی تقریب ؛ تفصیلات کے لئے API دستاویزات دیکھیں۔ for (var i = 0; i < positions.length; i++) { // گھومنا if (positions[i].ContractType!= contractType) { // اگر موجودہ انڈیکس کی ہولڈنگ کی معلومات معاہدہ آپریشن کرنے والے معاہدے کے برابر نہیں ہے یعنی: contractType جاری رکھیں؛ } var amount = Math.min ((insDetail.MaxLimitOrderVolume, positions[i].Amount) ؛ // انوینٹری کے زیادہ سے زیادہ ٹرانزیکشنز کو کنٹرول کرتا ہے var depth؛ if (positions[i].Type == PD_LONG の の positions[i].Type == PD_LONG_YD) { // کثیر پوزیشنوں کو سنبھالنا depth = _C ((e.GetDepth); // API کو کال کریں موجودہ انبار ڈیٹا حاصل کریں opAmount = Math.min ((amount, depth.Bids[0].Amount) ؛ // حد بندی آپریشن کی مقدار ڈسک کی ایک صف سے زیادہ نہیں ہے if (!CanTrade ((opAmount)) { // ونڈ کنٹرول ماڈیول کا پتہ لگانا واپسی } e.SetDirection ((positions[i].Type == PD_LONG? closebuy_today ٹیب: closebuy ٹیب) ؛ // سیٹ کریں ٹرانزیکشن کی سمت ، تفصیلات کے لئے API دستاویزات دیکھیں۔

            e.Sell(depth.Bids[0].Price - (insDetail.PriceTick * SlideTick), opAmount, contractType, positions[i].Type == PD_LONG ? "平今" : "平昨", 'Bid', depth.Bids[0]);
                                                                                           // 执行平仓 API ,详细参见 API文档。
            n++;                                                                           // 操作计数累加
        } else if (positions[i].Type == PD_SHORT || positions[i].Type == PD_SHORT_YD) {    // 处理 空仓 类似多仓处理
            depth = _C(e.GetDepth);
            opAmount = Math.min(amount, depth.Asks[0].Amount);
            if (!CanTrade(opAmount)) {
                return;
            }
            e.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell");
            e.Buy(depth.Asks[0].Price + (insDetail.PriceTick * SlideTick), opAmount, contractType, positions[i].Type == PD_SHORT ? "平今" : "平昨", 'Ask', depth.Asks[0]);
            n++;
        }
    }
    if (n === 0) {                                                                         // 如果n 等于 0 ,即初始为0 ,在遍历时没有累加,没有可平的仓位。
        break;                                                                             // 跳出主while循环
    }
    while (true) {                                                                         // 间隔一定时间后, 取消所有挂单。类似Open函数的  CancelPendingOrders
        Sleep(Interval);
        var orders = _C(e.GetOrders);
        if (orders.length === 0) {
            break;
        }
        for (var j = 0; j < orders.length; j++) {
            e.CancelOrder(orders[j].Id);
            if (j < (orders.length - 1)) {
                Sleep(Interval);
            }
        }
    }
}

}

var trans = { // چینی زبان میں ترجمہ، لغت کے لئے استعمال کیا جاتا ہے جس میں تفصیلات کے اکاؤنٹ کی معلومات کو اسٹیٹ بار میں دکھایا گیا ہے AccountID ٹب: سرمایہ کار اکاؤنٹ ٹب Available: دستیاب: دستیاب: دستیاب: دستیاب پی آئی اے کے مطابق ، پی آئی اے کے پاس ایک اور اہم سرمایہ کار ہے ، جس نے پی آئی اے کے ساتھ معاہدہ کیا ہے ، اور اس نے پی آئی اے کے ساتھ معاہدہ کیا ہے۔ اس کے علاوہ ، اس کے بارے میں مزید معلومات حاصل کرنے کے لئے یہاں کلک کریں: پی ٹی آئی نے اپنے ایک بیان میں کہا ہے کہ پی ٹی آئی کی جانب سے پی ٹی آئی کے خلاف کارروائی کی جارہی ہے اور اس کے خلاف کارروائی جاری ہے۔ اس کے علاوہ، اس کے پاس بہت سے دوسرے اختیارات ہیں، جن میں سے کچھ میں شامل ہیں: اس کے علاوہ، ہم نے اس کے بارے میں مزید معلومات حاصل کرنے کے لئے اس کے بارے میں مزید معلومات حاصل کیں. کریڈٹ بینک: کریڈٹ بینک: کریڈٹ بینک: کریڈٹ بینک اس کے علاوہ ، اس نے اپنے صارفین کے لئے ایک نیا ورژن تیار کیا ہے جس میں وہ اپنے صارفین کے لئے ایک نیا ورژن تیار کرسکتے ہیں۔ کرنسی آئی ڈی ٹن: کرنسی کے لئے کوڈ ٹن، اس کے علاوہ ، اس کے بارے میں مزید معلومات حاصل کرنے کے لئے ، آپ کو اس کے بارے میں مزید جاننے کی ضرورت ہوگی: ڈیپازٹ ٹون: سونے کی رقم ٹون میں ڈالیں، ایکسپورٹ ڈیلیوری مارجن: ایکسپورٹ ڈیلیوری مارجن: ایکسپورٹ ڈیلیوری مارجن: سونے کے تبادلے کے مارجن کے بارے میں: سونے کے تبادلے میں سونے کے مارجن کی ضمانت دی جاتی ہے ٹھنڈی نقد رقم: ٹھنڈی نقد رقم کی ٹوکریاں ٹھنڈی کمیشن ٹھنڈی: ٹھنڈی فیس ٹنڈر، ٹھنڈی فیس ٹنڈر، ٹھنڈی فیس ٹنڈر ٹھنڈی مارجن ٹماٹر: ٹھنڈی ضمانت والی سونے کی ٹماٹر FundMortgageAvailable: پیسے کی رہن کا بیلنس اس کے علاوہ ، یہ بھی کہا جاتا ہے کہ یہ ایک بہت بڑا سرمایہ ہے ، اور اس کی قیمتوں کا تعین کرنے کے لئے ، یہ ایک بہت بڑا سرمایہ ہے۔ اس کے علاوہ ، یہ بھی کہا جاتا ہے کہ یہ ایک بہت ہی اہم مسئلہ ہے ، اور اس کے بارے میں آپ کو کیا پتہ ہونا چاہئے: انٹرسٹ: سود کی آمدنی میں اضافہ انٹرسٹ بیس بیس: انٹرسٹ بیس بیس بیس، ہوم بین الاقوامی ہوم بینک: ہوم بینک ہوم بینک یہ ایک بہت ہی اہم اور قابل اعتماد فنڈ ہے جو آپ کو اپنے قرضوں کے لئے ادائیگی کرنے کی اجازت دیتا ہے. اس کے علاوہ ، یہ بھی کہا جاتا ہے کہ یہ ایک بہت بڑا نقصان ہے ، لیکن اس کا مطلب یہ نہیں ہے کہ یہ ایک بہت بڑا نقصان ہے۔ اس کے علاوہ ، اس نے اپنے پیسے کے لئے ایک بینک اکاؤنٹ بنایا ، جس میں اس نے اپنے پیسے کے لئے ادائیگی کی تھی۔ Previous PostPreCredit : پچھلے قرضے میں اضافہ ہوا تھا PreDeposit: پچھلی جمع رقم کی حد Previous articleپری فنڈ رہن قرض میں اضافہ: گزشتہ مالی سال میں قرض کی رقم میں اضافہ اس کے علاوہ ، اس کے پاس بہت سے دوسرے فنڈز بھی ہیں جو اس نے پہلے ہی ادا کیے ہیں۔ اس کے علاوہ ، اس کے پاس بہت سارے بینک اکاؤنٹ ہیں ، جن میں سے بہت سے بینک اکاؤنٹس ہیں ، لیکن ان میں سے بہت سے بینک اکاؤنٹس نہیں ہیں۔ Previous PostPreMortgage: پچھلی بار رہن کی رقم میں اضافہ ہوا تھا ایتھن ریزرو ایتھن: ایتھن بنیادی ذخیرہ ایتھن، ریزرو بیلنس ریزرو: ریزرو بیلنس ریزرو: ریزرو بیلنس ریزرو: ریزرو بیلنس ریزرو: ریزرو بیلنس ریزرو: ریزرو بیلنس ریزرو: ریزرو بیلنس ریزرو: ریزرو بیلنس ریزرو: SettlementID: سیٹلمنٹ نمبر اسپیک پروڈکٹ قریبی منافع کا نشان: اسپیک پروڈکٹ قریبی منافع کا نشان۔ اسپیک پروڈکٹ کمیشن: اسپیک پروڈکٹ کمیشن: اسپیک پروڈکٹ کمیشن: اسپیکٹ پروڈکٹ ایکسچینج مارجن: اسپیکٹ پروڈکٹ ایکسچینج میں سونے کی ضمانت دی جاتی ہے ، اور اس کی قیمت میں اضافہ ہوتا ہے۔ SpecProductFrozenCommission ٹونٹی: ٹونٹی کے لئے خصوصی مصنوعات کی منجمد کرنے کی فیس ٹونٹی، اسپیک پروڈکٹ منجمد مارجن آئل: خصوصی مصنوعات کی منجمد گارنٹی والی سونے کی آئل ، جو کہ ایک خاص قسم کی آئل ہے۔ اسپیک پروڈکٹ مارجن: اسپیک پروڈکٹ مارجن میں گارنٹی والی رقم ہے ، جس میں اسپیک پروڈکٹ مارجن میں اضافہ ہوا ہے۔ اسپیک پروڈکٹ پوزیشن منافع منافع: اسپیک پروڈکٹ پوزیشن منافع یا نقصان کا باعث بنتی ہے۔ SpecProductPositionProfitByAlg: مخصوص مصنوعات کی اسٹاک میں منافع اور نقصان کی پیمائش کی گئی ہے جو اسٹاک میں منافع اور نقصان کے الگورتھم کے مطابق حساب کی جاتی ہے۔ ٹریڈنگ ڈے ٹریڈنگ: ٹریڈنگ ڈے ٹریڈنگ کیلنڈر اس کے علاوہ ، آپ کو اپنے پیسے کے ساتھ رقم نکالنے کی ضرورت ہے ، لیکن آپ کو اس کے ساتھ کچھ بھی نہیں کرنا ہے۔ اس کے علاوہ ، آپ کو اپنے پیسے نکالنے کی ضرورت نہیں ہے ، لیکن آپ کو اپنے پیسے نکالنے کی ضرورت ہے۔ }؛

function AccountToTable ((jsStr, title) { // فنکشن فنکشن اکاؤنٹ کی معلومات کو اسٹیٹس ٹیبل فارم میں برآمد کرتی ہے، پیرامیٹر: ظاہر کرنے کے لئے JSON ساختہ سٹرنگ، ہیڈر if (typeof(title) === undefined) { // اگر title پیرامیٹر نہیں دیا گیا ہے تو: اکاؤنٹ کی معلومات ٹائٹل = اکاؤنٹ کی معلومات کی ٹب؛ } var tbl = { // ایک ٹیبل آبجیکٹ کا اعلان کرتا ہے جو لاگ اسٹیٹس فنکشن کو منتقل کرنے کے لئے استعمال کیا جاتا ہے ، جو اسٹیٹس بار میں ظاہر ہوتا ہے type: table, // قسم table کے طور پر متعین title: title, // متبادل title tbl کے عنوان فیلڈ کو قدر دینا cols: [ٹائل فیلڈ ٹائل، ٹائل بیان ٹائل، تھرمل ٹائل] // ٹیبل کالم عنوان rows: [] // ٹیبل کی ہر سطر پر اعداد و شمار کو ذخیرہ کرنے کے لئے ایک صف کے میدان، ابتدائی طور پر خالی صفوں کے طور پر. }؛ try { // غیر معمولی دریافت کریں var fields = JSON.parse ((jsStr) ؛ // jsStr سٹرنگ کا تجزیہ کریں for (var k in fields) { // fields اعتراض کی صفات کو گھومنا ، k صفات کی قیمت ہے ، سمجھ میں نہیں آتا کہ جے ایس ٹیوٹوریل دیکھ سکتے ہیں۔ if (k == AccountID k == BrokerID ) { // اگر موجودہ گھومنے والی خصوصیات ان دونوں خصوصیات ہیں تو ، اس کو چھوڑ دیں۔ جاری رکھیں } var desc = trans[k]؛ // trans لغت کے پراپرٹی نام کے مطابق چینی میں desc کی وضاحت حاصل کریں var v = fields[k]؛ // موجودہ پراپرٹی نام کی قدر حاصل کریں if (typeof(v) === number) { // اگر پراپرٹی ویلیو عددی ہے تو 5 بٹ کا عدد برقرار رکھیں۔ v = _N ((v، 5) ؛ } tbl.rows.push (([k, typeof(desc) === undefined? : desc, v]); // موجودہ صفات، صفات کی تفصیلات، صفات کی اقدار کے مجموعے کی ایک جہتی صف کو ٹیبل آبجیکٹ tbl کی صفوں کی صف میں دبائیں۔ } } catch (e) {} // غیر معمولی گرفت، لیکن عمل نہیں return tbl; // tbl آبجیکٹ واپس کرتا ہے }

var PositionManager = (function() { // ایک متغیر کا اعلان کرتا ہے PositionManager ایک گمنام فنکشن کی واپسی کی قدر قبول کرتا ہے جو ایک تعمیر شدہ اعتراض کے طور پر واپسی کی قدر کرتا ہے function PositionManager ((e) { // ایک تقریب کا اعلان کرتا ہے PositionManager ایک گمنام تقریب کے اندر ہے۔ if (typeof(e) === undefined) { // اگر آپریٹر e داخل نہیں کیا گیا ہے تو ، ڈیفالٹ کے ذریعہ عالمی متغیر تبادلہ آبجیکٹ کا تبادلہ e کو تفویض کریں e = تبادلہ؛ } if (e.GetName()!== Futures_CTP) { // بنیادی تبادلے کا پتہ لگاتا ہے کہ آیا آبجیکٹ e ایک تجارتی مستقبل کی تجارت ہے یا نہیں ، اگر نہیں تو ، غیر معمولی طور پر پھینک دیں۔ throw Only support CTP; // صرف CTP کی حمایت کرتا ہے } this.e = e; // موجودہ فنکشن (اصل میں ایک اعتراض بھی ہے) کو ایک خاصیت e شامل کریں اور اس کے لئے ایک پیرامیٹر e تفویض کریں this.account = null; // ایک اکاؤنٹ شامل کریں متغیر ابتدائی طور پر null } // کیشے حاصل کریں PositionManager.prototype.Account = function (() { // اوپر بیان کردہ PositionManager کو طریقہ کار اکاؤنٹ فنکشن میں شامل کریں if (!this.account) { // اگر PositionManager کی account پراپرٹی null ہے this.account = _C ((this.e.GetAccount) ؛ // اس.e. ایکسچینج آبجیکٹ کی GetAccount فنکشن (یعنی ایکسچینج آبجیکٹ API) کو کال کریں تاکہ اکاؤنٹ کی معلومات حاصل کی جاسکے۔ } return this.account؛ // یہ طریقہ اس PositionManager.account اکاؤنٹ کی معلومات واپس کرتا ہے۔ }؛ PositionManager.prototype.GetAccount = function ((getTable) { // طریقہ شامل کریں یہ طریقہ تازہ ترین اکاؤنٹ کی معلومات حاصل کرتا ہے۔ اس.اکاؤنٹ = _C ((this.e.GetAccount) ؛ if (typeof ((getTable)!== undefined txt && getTable) { // اگر آپ کو تازہ ترین حاصل کردہ اکاؤنٹ کی معلومات کی تفصیلات کو کسی شے کے طور پر واپس کرنا ہے تو ، getTable کو سچ ہونا چاہئے return AccountToTable ((this.e.GetRawJSON))) // GetRawJSON فنکشن مزید API دستاویزات دیکھیں } return this.account; // واپس آ جاتا ہے اکاؤنٹ کی معلومات جو اپ ڈیٹ ہو چکی ہیں۔ }؛

PositionManager.prototype.GetPosition = function(contractType, direction, positions) { // 给 PositionManager 添加方法 用于在主策略中调用该模板的 函数
    return GetPosition(this.e, contractType, direction, positions);
};

PositionManager.prototype.OpenLong = function(contractType, shares) {                  // 添加 开多仓 方法
    if (!this.account) {
        this.account = _C(this.e.GetAccount);
    }
    return Open(this.e, contractType, PD_LONG, shares);
};

PositionManager.prototype.OpenShort = function(contractType, shares) {                 // 添加 开空仓 方法
    if (!this.account) {
        this.account = _C(this.e.GetAccount);
    }
    return Open(this.e, contractType, PD_SHORT, shares);
};

PositionManager.prototype.Cover = function(contractType) {                             // 添加 平仓 方法
    if (!this.account) {
        this.account = _C(this.e.GetAccount);
    }
    return Cover(this.e, contractType);
};
PositionManager.prototype.CoverAll = function() {                                      // 添加 所有仓位全平方法
    if (!this.account) {
        this.account = _C(this.e.GetAccount);
    }
    while (true) {
        var positions = _C(this.e.GetPosition)
        if (positions.length == 0) {
            break
        }
        for (var i = 0; i < positions.length; i++) {                                   // 首先平掉 对冲合约 对冲合约 举例 MA709&MA705
            // Cover Hedge Position First
            if (positions[i].ContractType.indexOf('&') != -1) {
                Cover(this.e, positions[i].ContractType)
                Sleep(1000)
            }
        }
        for (var i = 0; i < positions.length; i++) {
            if (positions[i].ContractType.indexOf('&') == -1) {
                Cover(this.e, positions[i].ContractType)
                Sleep(1000)
            }
        }
    }
};
PositionManager.prototype.Profit = function(contractType) {                            // 添加计算收益的方法
    var accountNow = _C(this.e.GetAccount);
    return _N(accountNow.Balance - this.account.Balance);
};

return PositionManager;                                                                // 匿名函数返回 在自身内声明的 PositionManager 函数(对象)。

})();

$.NewPositionManager = function(e) { // ایک PositionManager آبجیکٹ بنانے کے لئے ایک تقریب برآمد return new PositionManager ((e) ؛ }؛

// بذریعہ:http://mt.sohu.com/20160429/n446860150.shtml$.IsTrading = function ((symbol) { // معاہدے کا فیصلہ کرتا ہے کہ آیا یہ تجارت میں ہے یا نہیں وقت کی حد میں ، پیرامیٹر symbol معاہدہ کا کوڈ var now = new Date ((); // موجودہ وقت کا اعتراض حاصل کرتا ہے var day = now.getDay ((); // موجودہ وقت کو ہفتے کے کسی خاص دن پر حاصل کرتا ہے۔ var hour = now.getHours ((); // 24 گھنٹے میں سے ایک گھنٹے حاصل کریں var minute = now.getMinutes ((); // منٹ میں ایک منٹ میں سے کون سا منٹ حاصل کریں

if (day === 0 || (day === 6 && (hour > 2 || hour == 2 && minute > 30))) {              // 第一个过滤, day == 0 星期天  或者  day == 6 星期六并且
    return false;                                                                      // 2点30以后 。 星期五 夜盘结束。  返回 false  即所有品种不在交易时间
}
symbol = symbol.replace('SPD ', '').replace('SP ', '');                                // 正则表达式 匹配其交易系统用“SPD”表示跨期套利交易,若指令买进“SPD CF1609&CF17...
                                                                                       // 过滤掉 跨期套利的 合约编码
var p, i, shortName = "";
for (i = 0; i < symbol.length; i++) {                                                  // 遍历合约代码字符串,取出 代码(排除数字的部分)赋值给shortName 并且转换为大写
    var ch = symbol.charCodeAt(i);
    if (ch >= 48 && ch <= 57) {
        break;
    }
    shortName += symbol[i].toUpperCase();
}

var period = [                                                                         // 通常交易时间  9:00 - 10:15,
    [9, 0, 10, 15],                                                                    //             10:30 - 11:30
    [10, 30, 11, 30],                                                                  //              13:30 - 15:00
    [13, 30, 15, 0]
];
if (shortName === "IH" || shortName === "IF" || shortName === "IC") {                  // 如果是这些 品种,交易时间 period 调整
    period = [
        [9, 30, 11, 30],
        [13, 0, 15, 0]
    ];
} else if (shortName === "TF" || shortName === "T") {                                  // 国债品种  时间调整
    period = [
        [9, 15, 11, 30],
        [13, 0, 15, 15]
    ];
}


if (day >= 1 && day <= 5) {                                                            // 如果是 周一 到周五, 不考虑夜盘。 判断当前时间是否符合 period 设定的时间表
    for (i = 0; i < period.length; i++) {
        p = period[i];
        if ((hour > p[0] || (hour == p[0] && minute >= p[1])) && (hour < p[2] || (hour == p[2] && minute < p[3]))) {
            return true;                                                               // 符合遍历出的  时间表 中的 时间段,  即该品种在交易时间内。
        }
    }
}

var nperiod = [                                                                        // 额外判断 夜盘品种  nperiod[n][0] 是夜盘时间相同的一类
                                                                                       // 品种汇总,nperiod[n][1] 就是该类品种的夜盘交易时间
    [
        ['AU', 'AG'],
        [21, 0, 02, 30]
    ],
    [
        ['CU', 'AL', 'ZN', 'PB', 'SN', 'NI'],
        [21, 0, 01, 0]
    ],
    [
        ['RU', 'RB', 'HC', 'BU'],
        [21, 0, 23, 0]
    ],
    [
        ['P', 'J', 'M', 'Y', 'A', 'B', 'JM', 'I'],
        [21, 0, 23, 30]
    ],
    [
        ['SR', 'CF', 'RM', 'MA', 'TA', 'ZC', 'FG', 'IO'],
        [21, 0, 23, 30]
    ],
];
for (i = 0; i < nperiod.length; i++) {                                                // 遍历所有夜盘品种 交易时间段,对比当前时间。
    for (var j = 0; j < nperiod[i][0].length; j++) {
        if (nperiod[i][0][j] === shortName) {
            p = nperiod[i][1];
            var condA = hour > p[0] || (hour == p[0] && minute >= p[1]);
            var condB = hour < p[2] || (hour == p[2] && minute < p[3]);
            // in one day
            if (p[2] >= p[0]) {
                if ((day >= 1 && day <= 5) && condA && condB) {
                    return true;
                }
            } else {
                if (((day >= 1 && day <= 5) && condA) || ((day >= 2 && day <= 6) && condB)) {
                    return true;
                }
            }
            return false;
        }
    }
}
return false;

};

$.NewTaskQueue = function ((onTaskFinish) { // کثیر اقسام کے لین دین کے لئے قطار کی شے کی تعمیر کا کام کرتا ہے۔ Parameters: callback function when the task is completed. var self = {} // ایک خالی اعتراض کا اعلان کرتا ہے self.ERR_SUCCESS = 0 // تعریف کی واپسی کی معلومات کامیاب self.ERR_SET_SYMBOL = 1 // معاہدہ ترتیب دینے میں خرابی self.ERR_GET_RECORDS = 2 // K لائن کی خرابی self.ERR_GET_ORDERS = 3 // نامکمل آرڈر کی خرابی self.ERR_GET_POS = 4 // اسٹوریج کی معلومات حاصل کرنے میں خرابی self.ERR_TRADE = 5 // ٹرانزیکشن کی خرابی self.ERR_GET_DEPTH = 6 // گہرائی کی تلاش میں خرابی self.ERR_NOT_TRADING = 7 // ٹریڈنگ کے وقت نہیں self.ERR_BUSY = 8 // بلاک

self.onTaskFinish = typeof(onTaskFinish) === 'undefined' ? null : onTaskFinish  // 如果在 初始化队列对象时没有 传入需要回调的匿名函数,该属性赋值为null,否则赋值回调函数
self.retryInterval = 300                                                        // 重试间隔 毫秒数
self.tasks = []                                                                 // 这个是一个重要的属性,队列中储存任务的数组。
self.pushTask = function(e, symbol, action, amount, arg, onFinish) {            // 给空对象添加函数,该函数是压入 新任务 到任务数组中。参数分别为:
                                                                                // 交易所对象、合约代码、执行动作、数量、回调函数参数、回调函数
    var task = {                                                                // 构造一个任务对象
        e: e,                                                                   // 交易所对象
        action: action,                                                         // 执行的动作
        symbol: symbol,                                                         // 合约代码
        amount: amount,                                                         // 操作数量
        init: false,                                                            // 是否初始化
        finished: false,                                                        // 是否任务完成
        dealAmount: 0,                                                          // 已处理的 量
        preAmount: 0,                                                           // 上一次的 量
        preCost: 0,                                                             // 上一次的 花费
        retry: 0,                                                               // 重试次数
        maxRetry: 10,                                                           // 最大重试次数
        arg: typeof(onFinish) !== 'undefined' ? arg : undefined,                // 如果没有传入 回调函数,此项 设置为 undefined
        onFinish: typeof(onFinish) == 'undefined' ? arg : onFinish              // 如果没有传入回调函数,把 arg 复制给 onFinish(实际上是 arg没传入,中间隔过去了)
    }
    
    switch (task.action) {                                                      // 根据执行的动作初始化描述信息
        case "buy":
            task.desc = task.symbol + " 开多仓, 数量 " + task.amount
            break
        case "sell":
            task.desc = task.symbol + " 开空仓, 数量 " + task.amount
            break
        case "closebuy":
            task.desc = task.symbol + " 平多仓, 数量 " + task.amount
            break
        case "closesell":
            task.desc = task.symbol + " 平空仓, 数量 " + task.amount
            break
        default:
            task.desc = task.symbol + " " + task.action + ", 数量 " + task.amount
    }

    self.tasks.push(task)                                                       // 压入任务数组中
    Log("接收到任务", task.desc)                                                  // 输出日志 显示 接收到任务。
}

self.cancelAll = function(e) {                                                  // 添加函数,取消所有,参数: 交易所对象
    while (true) {                                                              // 遍历未完成的所有订单,逐个取消。
        var orders = e.GetOrders();
        if (!orders) {                                                          // 所有API 调用都不重试,如果API调用失败,立即返回。
            return self.ERR_GET_ORDERS;
        }
        if (orders.length == 0) {
            break;
        }
        for (var i = 0; i < orders.length; i++) {
            e.CancelOrder(orders[i].Id);
            Sleep(self.retryInterval);
        }
    }
    return self.ERR_SUCCESS                                                      // 返回 完成标记
}

self.pollTask = function(task) {                                                 // 执行数组中弹出的任务
    var insDetail = task.e.SetContractType(task.symbol);                         // 切换到当前 任务 task 对象保存的合约类型
    if (!insDetail) {                                                            // 切换失败 立即返回
        return self.ERR_SET_SYMBOL;
    }
    var ret = null;
    var isCover = task.action != "buy" && task.action != "sell";                 // 根据执行的动作,设置 是否是平仓的 标记
    do {                                                                         // do while 循环,先执行 do 以内
        if (!$.IsTrading(task.symbol)) {                                         // 判断是否在交易时间
            return self.ERR_NOT_TRADING;                                         // 不在交易时间立即返回
        }
        if (self.cancelAll(task.e) != self.ERR_SUCCESS) {                        // 调用全部取消函数 ,如果不等于 完成状态
            return self.ERR_TRADE;                                               // 返回交易失败
        }
        if (!CanTrade(task.amount)) {                                            // 风控模块检测。
            ret = null
            break
        }
        var positions = task.e.GetPosition();                                    // 获取持仓信息
        // Error
        if (!positions) {
            return self.ERR_GET_POS;                                             // 如果调用获取持仓 API 错误,立即返回
        }
        // search position
        var pos = null;
        for (var i = 0; i < positions.length; i++) {                             // 遍历持仓信息,查找持仓合并持仓,类似 上面的 GetPosition 函数
            if (positions[i].ContractType == task.symbol && (((positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) && (task.action == "buy" || task.action == "closebuy")) || ((positions[i].Type == PD_SHORT || positions[i].Type == PD_SHORT_YD) && (task.action == "sell" || task.action == "closesell")))) {
                if (!pos) {
                    pos = positions[i];
                    pos.Cost = positions[i].Price * positions[i].Amount;
                } else {
                    pos.Amount += positions[i].Amount;
                    pos.Profit += positions[i].Profit;
                    pos.Cost += positions[i].Price * positions[i].Amount;
                }
            }
        }
        // record pre position
        if (!task.init) {                                                        // 如果任务没有初始化,执行以下
            task.init = true;                                                    // 更新为已初始化
            if (pos) {                                                           // 如果查找到之前的持仓,把之前的持仓数量、 花费 复制给task 的相应变量保存
                task.preAmount = pos.Amount;
                task.preCost = pos.Cost;
            } else {                                                             // 如果执行这个任务 时没有 ,同样的方向  同样合约的持仓,把task相关变量赋值0
                task.preAmount = 0;
                task.preCost = 0;
                if (isCover) {                                                   // 如果是 平仓动作,输出日志 : 找不到仓位,跳出循环。
                    Log("找不到仓位", task.symbol, task.action);
                    ret = null;
                    break;
                }
            }
        }
        var remain = task.amount;                                                // 声明一个局部变量,用 任务的属性 amount(任务设定的交易量) 初始化
        if (isCover && !pos) {                                                   // 如果 第二次循环中 , 该任务动作是平仓,并且 没有持仓了,给pos 赋值
            pos = {Amount:0, Cost: 0, Price: 0}
        }
        if (pos) {                                                               // 如果 pos 不为null 
            task.dealAmount = pos.Amount - task.preAmount;                       // 已经处理的任务量 等于 每次获取的持仓信息持仓量 与最初开始循环的初始持仓信息持仓量的差值
            if (isCover) {                                                       // 如果是 平仓动作, dealAmount 是负值, 这里取反操作
                task.dealAmount = -task.dealAmount;
            }
            remain = parseInt(task.amount - task.dealAmount);                    // 任务的 交易量 减去 已经处理的交易量  得出 剩余需要处理的交易量
            if (remain <= 0 || task.retry >= task.maxRetry) {                    // 如果剩余需要的交易量小于等于0(此处分析应该是不会小于0,有兴趣的可以分析下。) 或者重试次数大于最大重试上限.
                ret = {                                                          // 更新ret 对象,  更新为已经成交的信息,和 当前仓位信息。
                    price: (pos.Cost - task.preCost) / (pos.Amount - task.preAmount),
                    amount: (pos.Amount - task.preAmount),
                    position: pos
                };
                if (isCover) {                                                   // 如果是 平仓动作
                    ret.amount = -ret.amount;                                    // 平仓时计算出的是负值  ,取反操作
                    if (pos.Amount == 0) {                                       // 如果持仓量为0了, 把ret 的持仓信息 赋值为 null
                        ret.position = null;
                    }
                }
                break;                                                           // remain <= 0 || task.retry >= task.maxRetry 符合这个条件,跳出while循环
            }
        } else if (task.retry >= task.maxRetry) {                                // 如果不是 平仓操作。pos 为null 没有持仓(平仓操作 pos 此处不会是null)
            ret = null;                                                          // 并且 该任务重试测试 大于最大重试次数。跳出循环。
            break;                                                               // 即此时  , 超过最大重试次数,并且 没有增加持仓(开仓 每次都失败了。),跳出循环
        }

        var depth = task.e.GetDepth();                                           // 获取 深度数据
        if (!depth) {
            return self.ERR_GET_DEPTH;                                           // 获取失败立即返回
        }
        var orderId = null;                                                      // 订单ID
        var slidePrice = insDetail.PriceTick * SlideTick;                        // 计算具体滑价值
        if (isCover) {                                                           // 如果是平仓操作
            for (var i = 0; i < positions.length; i++) {                         // 遍历本轮的  API 返回的持仓信息。
                if (positions[i].ContractType !== task.symbol) {                 // 不是当前任务 品种的  跳过。
                    continue;
                }
                if (parseInt(remain) < 1) {                                      // 需要处理的 交易的量 如果小于1,跳出 while
                    break
                }
                var amount = Math.min(insDetail.MaxLimitOrderVolume, positions[i].Amount, remain);  // 在合约规定的最大下单量、持仓量、需要处理的量中取最小值。 
                if (task.action == "closebuy" && (positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD)) {   // 如果是平多仓, 持仓信息 为 今日多仓  或者 昨日多仓
                    task.e.SetDirection(positions[i].Type == PD_LONG ? "closebuy_today" : "closebuy");                  // 设置方向
                    amount = Math.min(amount, depth.Bids[0].Amount)                                                     // 根据盘口量 和 下单量 再取一个最小值。
                    orderId = task.e.Sell(_N(depth.Bids[0].Price - slidePrice, 2), amount, task.symbol, positions[i].Type == PD_LONG ? "平今" : "平昨", 'Bid', depth.Bids[0]);
                                                                                                                        // 执行具体的 API 操作,以下平空类似
                } else if (task.action == "closesell" && (positions[i].Type == PD_SHORT || positions[i].Type == PD_SHORT_YD)) {
                    task.e.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell");
                    amount = Math.min(amount, depth.Asks[0].Amount)
                    orderId = task.e.Buy(_N(depth.Asks[0].Price + slidePrice, 2), amount, task.symbol, positions[i].Type == PD_SHORT ? "平今" : "平昨", 'Ask', depth.Asks[0]);
                }
                // assume order is success insert
                remain -= amount;                                                // 假设是成功执行, 需要处理的交易量 减去 此次交易的量。
            }
        } else {                                                                 // 开仓
            if (task.action == "buy") {
                task.e.SetDirection("buy");
                orderId = task.e.Buy(_N(depth.Asks[0].Price + slidePrice, 2), Math.min(remain, depth.Asks[0].Amount), task.symbol, 'Ask', depth.Asks[0]);
            } else {
                task.e.SetDirection("sell");
                orderId = task.e.Sell(_N(depth.Bids[0].Price - slidePrice, 2), Math.min(remain, depth.Bids[0].Amount), task.symbol, 'Bid', depth.Bids[0]);
            }
        }
        // symbol not in trading or other else happend
        if (!orderId) {                                                          // 没有返回具体的ID ,可能是 交易不在交易队列,或者其他错误。
            task.retry++;                                                        // 累计重试次数
            return self.ERR_TRADE;                                               // 返回错误信息。即使不成功, 重新 执行该任务的时候 会重新一次流程。除了task对象的数据 所有数据都会刷新
        }
    } while (true);                                                              // 循环判断 恒为真
    task.finished = true                                                         // 如果在 while 循环中没有直接 return  顺序执行到此,则任务完成                                                      

    if (self.onTaskFinish) {                                                     // 如果队列控制对象的 回调函数 设置 不为null(即 self.onTaskFinish 存在)
        self.onTaskFinish(task, ret)                                             // 执行回调函数。把 task 任务 对象  和 交易的结果  ret 对象 传入回调函数。 
    }

    if (task.onFinish) {                                                         // 处理 任务的回调函数
        task.onFinish(task, ret);
    }
    return self.ERR_SUCCESS;
}

self.poll = function() {                                                         // 迭代执行 弹出 tasks 中的任务 ,并调用 pollTask 执行任务。
    var processed = 0                                                            // 未执行完成的任务计数 ,每次初始0
    _.each(self.tasks, function(task) {                                          // 迭代  可以搜索 _.each 的用法
        if (!task.finished) {                                                    // 如果 任务不是完成状态,
            processed++                                                          // 未完成任务 计数 累计
            self.pollTask(task)                                                  // 执行弹出的任务
        }
    })
    if (processed == 0) {                                                        // 如果没有未完成的任务,即 所有任务队列内的任务完成 ,执行清空 队列对象中 tasks 数组.
        self.tasks = []
    }
}

self.size = function() {                                                         // 给队列对象添加 函数 size 获取 任务队列 中 任务个数
    return self.tasks.length
}

return self                                                                      // 返回构造好的队列对象

}

$.accountToTable = AccountToTable؛


مزید