avatar of 发明者量化-小小梦 发明者量化-小小梦
پر توجہ دیں نجی پیغام
4
پر توجہ دیں
1271
پیروکار

بولنگر بینڈز پر مبنی کریپٹو کرنسی انٹر پیریڈ ثالثی حکمت عملی

میں تخلیق کیا: 2020-02-22 18:54:23, تازہ کاری: 2023-10-10 21:11:20
comments   0
hits   4202

بولنگر بینڈز پر مبنی کریپٹو کرنسی انٹر پیریڈ ثالثی حکمت عملی

I. خلاصہ

1987 میں لکھی گئی اپنی کتاب The Alchemy of Finance میں، سوروس نے ایک اہم تجویز پیش کی: مجھے یقین ہے کہ مارکیٹ کی قیمتیں ہمیشہ اس لحاظ سے غلط ہوتی ہیں کہ وہ مستقبل کے بارے میں ایک متعصبانہ نظریہ پیش کرتی ہیں۔ درحقیقت، مارکیٹ کے شرکاء ہمیشہ عقلی نہیں ہوتے، اور ہر وقت، شرکاء کے لیے تمام معلومات کو مکمل طور پر حاصل کرنا اور معروضی طور پر تشریح کرنا ناممکن ہوتا ہے، چاہے معلومات ایک جیسی ہوں، ہر ایک کی رائے مختلف ہوتی ہے۔ دوسرے لفظوں میں، قیمت میں پہلے سے ہی مارکیٹ کے شرکاء کی غلط توقعات شامل ہوتی ہیں، اس لیے مارکیٹ کی قیمتیں جوہر میں ہمیشہ غلط ہوتی ہیں۔ یہ ارباب اختیار کے لیے منافع کا ذریعہ ہو سکتا ہے۔

2. حکمت عملی کے اصول

مندرجہ بالا اصولوں کی بنیاد پر، ہم جانتے ہیں کہ ایک غیر موثر فیوچر مارکیٹ میں، مختلف ادوار میں ترسیل کے معاہدوں پر مارکیٹ کے اثرات ہمیشہ ہم آہنگ نہیں ہوتے ہیں، اور ان کی قیمتوں کا تعین مکمل طور پر موثر نہیں ہوتا ہے۔ پھر، مختلف ادوار میں ایک ہی تجارتی موضوع کی ڈیلیوری کنٹریکٹ کی قیمتوں کی بنیاد پر، اگر دونوں قیمتوں کے درمیان بڑا فرق ہے، تو آپ کراس پیریڈ آربیٹریج کرنے کے لیے ایک ہی وقت میں مختلف ادوار کے فیوچر کنٹریکٹس خرید اور فروخت کر سکتے ہیں۔ کموڈٹی فیوچرز کی طرح، ڈیجیٹل کرنسیوں میں بھی کراس پیریڈ ثالثی معاہدوں کا مجموعہ ہوتا ہے۔ مثال کے طور پر، OkEX ایکسچینج میں، یہ ہیں: ETC ہفتہ وار، ETC دو ہفتہ وار، اور ETC سہ ماہی۔

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

3. حکمت عملی کی منطق

یہ مضمون آپ کو سکھائے گا کہ ڈیجیٹل کرنسی ٹریڈنگ میں OkEX ایکسچینج میں انوینٹر کوانٹیٹیو ٹریڈنگ پلیٹ فارم اور ETC فیوچر کنٹریکٹ کا استعمال کیسے کریں، ایک سادہ ثالثی حکمت عملی کا استعمال کرتے ہوئے یہ ظاہر کرنے کے لیے کہ فوری ثالثی کے مواقع کیسے حاصل کیے جائیں اور ہیجنگ کے دوران منافع حاصل کرنے کے لیے ہر موقع سے فائدہ اٹھایا جائے۔ ممکنہ خطرات.

ایک کریپٹو کرنسی کراس پیریڈ ثالثی کی حکمت عملی بنانا مشکل: نارمل

اسٹریٹجک ماحول

  • لین دین کا موضوع: Ethereum Classic (ETC)
  • قیمت کے فرق کا ڈیٹا: ETC ہفتہ وار - ETC سہ ماہی (کوانٹیگریشن ٹیسٹ چھوڑ دیا گیا)
  • ٹریڈنگ سائیکل: 5 منٹ
  • پوزیشن کا ملاپ: 1:1
  • لین دین کی قسم: ایک ہی پروڈکٹ کراس پیریڈ

حکمت عملی کی منطق

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

4. ایک پالیسی فریم ورک لکھیں۔

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

function Data() {}  // 基础数据函数
Data.prototype.mp = function () {}  // 持仓函数
Data.prototype.boll = function () {}  // 指标函数
Data.prototype.trade = function () {}  // 下单函数
Data.prototype.cancelOrders = function () {}  // 撤单函数
Data.prototype.isEven = function () {}  // 处理单只合约函数
Data.prototype.drawingChart = function () {}  // 画图函数

// 交易条件
function onTick() {
    var data = new Data(tradeTypeA, tradeTypeB);  // 创建一个基础数据对象
    var accountStocks = data.accountData.Stocks;  // 账户余额
    var boll = data.boll(dataLength, timeCycle);  // 计算boll技术指标
    data.trade();  // 计算交易条件下单
    data.cancelOrders();  // 撤单
    data.drawingChart(boll);  // 画图
    data.isEven();  // 处理持有单个合约
}

//入口函数
function main() {
    while (true) {  // 进入轮询模式
        onTick();  // 执行onTick函数
        Sleep(500);  // 休眠0.5秒
    }
}

5. ایک حکمت عملی لکھیں۔

اسٹریٹجک آئیڈیاز اور تجارتی عمل کا موازنہ کرکے، آپ آسانی سے حکمت عملی کا فریم ورک بنا سکتے ہیں۔ پوری حکمت عملی کو تین مراحل میں آسان بنایا جا سکتا ہے:

  • پری ٹرانزیکشن پروسیسنگ۔
  • ڈیٹا حاصل کریں اور حساب لگائیں۔
  • آرڈر دیں اور فالو اپ کو سنبھالیں۔

اگلا، ہمیں لین دین کے اصل عمل اور لین دین کی تفصیلات کی بنیاد پر حکمت عملی کے فریم ورک میں ضروری تفصیلی کوڈ کو پُر کرنے کی ضرورت ہے۔

پری ٹرانزیکشن پروسیسنگ مرحلہ 1: عالمی ماحول میں، ضروری عالمی متغیرات کا اعلان کریں۔

//声明一个配置图表的 chart 对象
var chart = { }

//调用 Chart 函数,初始化图表
var ObjChart = Chart ( chart )

//声明一个空数组,用来存储价差序列
var bars = [ ]

//声明一个记录历史数据时间戳变量
var oldTime = 0

مرحلہ 2: حکمت عملی کے بیرونی پیرامیٹرز کو ترتیب دیں۔

// 参数
var tradeTypeA = "this_week"; // 套利A合约
var tradeTypeB = "quarter"; // 套利B合约
var dataLength = 10; //指标周期长度
var timeCycle = 1; // K线周期
var name = "ETC"; // 币种
var unit = 1; // 下单量

مرحلہ 3: ڈیٹا پروسیسنگ کے افعال کی وضاحت کریں۔ بنیادی ڈیٹا فنکشن: ڈیٹا ( ) کنسٹرکٹر ڈیٹا بنائیں اور اس کی اندرونی خصوصیات کی وضاحت کریں۔ پر مشتمل ہے: اکاؤنٹ ڈیٹا، پوزیشن ڈیٹا، K-لائن ڈیٹا ٹائم اسٹیمپ، ثالثی A/B معاہدے کی بولی/پوچھی قیمت، اور فارورڈ/ریورس آربٹریج اسپریڈز۔

// 基础数据
function Data(tradeTypeA, tradeTypeB) { // 传入套利A合约和套利B合约
    this.accountData = _C(exchange.GetAccount); // 获取账户信息
    this.positionData = _C(exchange.GetPosition); // 获取持仓信息
    var recordsData = _C(exchange.GetRecords); //获取K线数据
    exchange.SetContractType(tradeTypeA); // 订阅套利A合约
    var depthDataA = _C(exchange.GetDepth); // 套利A合约深度数据
    exchange.SetContractType(tradeTypeB); // 订阅套利B合约
    var depthDataB = _C(exchange.GetDepth); // 套利B合约深度数据
    this.time = recordsData[recordsData.length - 1].Time; // 获取最新数据时间
    this.askA = depthDataA.Asks[0].Price; // 套利A合约卖一价
    this.bidA = depthDataA.Bids[0].Price; // 套利A合约买一价
    this.askB = depthDataB.Asks[0].Price; // 套利B合约卖一价
    this.bidB = depthDataB.Bids[0].Price; // 套利B合约买一价
    // 正套价差(合约A卖一价 - 合约B买一价)
    this.basb = depthDataA.Asks[0].Price - depthDataB.Bids[0].Price;
    // 反套价差(合约A买一价 - 合约B卖一价)
    this.sabb = depthDataA.Bids[0].Price - depthDataB.Asks[0].Price;
}

پوزیشن فنکشن حاصل کریں: mp ( ) پوری پوزیشن اری کو عبور کریں اور مخصوص معاہدے اور سمت کی پوزیشنوں کی تعداد واپس کریں اگر کوئی نہیں ہے تو غلط واپس کریں۔

// 获取持仓
Data.prototype.mp = function (tradeType, type) {
    var positionData = this.positionData; // 获取持仓信息
    for (var i = 0; i < positionData.length; i++) {
        if (positionData[i].ContractType == tradeType) {
            if (positionData[i].Type == type) {
                if (positionData[i].Amount > 0) {
                    return positionData[i].Amount;
                }
            }
        }
    }
    return false;
}

کے لائن اور اشارے کے افعال: بول ( ) فارورڈ/ریورس آربٹریج اسپریڈ ڈیٹا کی بنیاد پر ایک نئی K-لائن ترتیب کی ترکیب کریں۔ اور بول انڈیکیٹر کے حساب سے اوپری ریل، درمیانی ریل اور لوئر ریل کا ڈیٹا لوٹاتا ہے۔

// 合成新K线数据和boll指标数据
Data.prototype.boll = function (num, timeCycle) {
    var self = {}; // 临时对象
    // 正套价差和反套价差中间值
    self.Close = (this.basb + this.sabb) / 2;
    if (this.timeA == this.timeB) {
        self.Time = this.time;
    } // 对比两个深度数据时间戳
    if (this.time - oldTime > timeCycle * 60000) {
        bars.push(self);
        oldTime = this.time;
    } // 根据指定时间周期,在K线数组里面传入价差数据对象
    if (bars.length > num * 2) {
        bars.shift(); // 控制K线数组长度
    } else {
        return;
    }
    var boll = TA.BOLL(bars, num, 2); // 调用talib库中的boll指标
    return {
        up: boll[0][boll[0].length - 1], // boll指标上轨
        middle: boll[1][boll[1].length - 1], // boll指标中轨
        down: boll[2][boll[2].length - 1] // boll指标下轨
    } // 返回一个处理好的boll指标数据
}

آرڈر کی تقریب: تجارت ( ) آرڈر کنٹریکٹ کا نام اور آرڈر کی قسم کو پاس کریں، پھر قابل غور قیمت پر آرڈر دیں، اور آرڈر دینے کے بعد نتیجہ واپس کریں۔ چونکہ ایک ہی وقت میں دو آرڈرز کو مختلف سمتوں میں دینا ضروری ہے، اس لیے خرید/فروخت کی قیمت کو آرڈر کنٹریکٹ کے نام کے مطابق فنکشن میں تبدیل کر دیا جاتا ہے۔

// 下单
Data.prototype.trade = function (tradeType, type) {
    exchange.SetContractType(tradeType); // 下单前先重新订阅合约
    var askPrice, bidPrice;
    if (tradeType == tradeTypeA) { // 如果是A合约下单
        askPrice = this.askA; // 设置askPrice
        bidPrice = this.bidA; // 设置bidPrice
    } else if (tradeType == tradeTypeB) { // 如果是B合约下单
        askPrice = this.askB; // 设置askPrice
        bidPrice = this.bidB; // 设置bidPrice
    }
    switch (type) { // 匹配下单模式
        case "buy":
            exchange.SetDirection(type); // 设置下单模式
            return exchange.Buy(askPrice, unit);
        case "sell":
            exchange.SetDirection(type); // 设置下单模式
            return exchange.Sell(bidPrice, unit);
        case "closebuy":
            exchange.SetDirection(type); // 设置下单模式
            return exchange.Sell(bidPrice, unit);
        case "closesell":
            exchange.SetDirection(type); // 设置下单模式
            return exchange.Buy(askPrice, unit);
        default:
            return false;
    }
}

آرڈر کی تقریب منسوخ کریں: کینسل آرڈرز () تمام نامکمل آرڈرز کی ایک صف حاصل کریں اور انہیں ایک ایک کرکے منسوخ کریں۔ اور اگر کوئی حکم پورا نہ ہوا ہو تو وہ باطل ہو جاتا ہے اور اگر کوئی حکم پورا نہ ہوا ہو تو وہ درست ہو جاتا ہے۔

// 取消订单
Data.prototype.cancelOrders = function () {
    Sleep(500); // 撤单前先延时,因为有些交易所你懂的
    var orders = _C(exchange.GetOrders); // 获取未成交订单数组
    if (orders.length > 0) { // 如果有未成交的订单
        for (var i = 0; i < orders.length; i++) { //遍历未成交订单数组
            exchange.CancelOrder(orders[i].Id); //逐个取消未成交的订单
            Sleep(500); //延时0.5秒
        }
        return false; // 如果取消了未成交的单子就返回false
    }
    return true; //如果没有未成交的订单就返回true
}

ایک ہی معاہدے کے انعقاد کو سنبھالنا: isEven() ثالثی تجارت میں سنگل ٹانگ کی صورت حال سے نمٹنے کے وقت، ہم اسے سنبھالنے کے لیے تمام پوزیشنوں کو بند کر دیتے ہیں۔ بلاشبہ، آپ فالو اپ آرڈر کے طریقہ کار کو بھی تبدیل کر سکتے ہیں۔

// 处理持有单个合约
Data.prototype.isEven = function () {
    var positionData = this.positionData; // 获取持仓信息
    var type = null; // 转换持仓方向
    // 如果持仓数组长度余2不等于0或者持仓数组长度不等于2
    if (positionData.length % 2 != 0 || positionData.length != 2) {
        for (var i = 0; i < positionData.length; i++) { // 遍历持仓数组
            if (positionData[i].Type == 0) { // 如果是多单
                type = 10; // 设置下单参数
            } else if (positionData[i].Type == 1) { // 如果是空单
                type = -10; // 设置下单参数
            }
            // 平掉所有仓位
            this.trade(positionData[i].ContractType, type, positionData[i].Amount);
        }
    }
}

ڈرائنگ فنکشن: ڈرائنگ چارٹ ( ) چارٹ میں ضروری مارکیٹ ڈیٹا اور اشارے کا ڈیٹا کھینچنے کے لیے ObjChart.add() طریقہ کو کال کریں: اپر ٹریک، درمیانی ٹریک، لوئر ٹریک، اور مثبت/منفی پھیلاؤ۔

// 画图
Data.prototype.drawingChart = function (boll) {
    var nowTime = new Date().getTime();
    ObjChart.add([0, [nowTime, boll.up]]);
    ObjChart.add([1, [nowTime, boll.middle]]);
    ObjChart.add([2, [nowTime, boll.down]]);
    ObjChart.add([3, [nowTime, this.basb]]);
    ObjChart.add([4, [nowTime, this.sabb]]);
    ObjChart.update(chart);
}

مرحلہ 4: انٹری فنکشن مین () میں پری ٹرانزیکشن پری پروسیسنگ کوڈ پر عمل کریں یہ کوڈ پروگرام شروع ہونے کے بعد صرف ایک بار چلتا ہے۔ شامل ہیں:

  • کنسول میں کم اہم پیغامات کو فلٹر کریں SetErrorFilter ()
  • ڈیجیٹل کرنسی کو تبادلے کے لیے سیٹ کریں۔ IO ( )
  • پروگرام شروع ہونے سے پہلے پہلے سے تیار کردہ چارٹ کو صاف کریں ObjChart.reset ( )
  • پروگرام شروع ہونے سے پہلے اسٹیٹس بار کی پچھلی معلومات کو صاف کریں LogProfitReset ( )
//入口函数
function main() {
    // 过滤控制台中不是很重要的信息
    SetErrorFilter("429|GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout|Futures_OP");
    exchange.IO("currency", name + '_USDT'); //设置要交易的数字货币币种
    ObjChart.reset(); //程序启动前清空之前绘制的图表
    LogProfitReset(); //程序启动前清空之前的状态栏信息
}

مذکورہ بالا پری ٹریڈنگ پری پروسیسنگ کی وضاحت کرنے کے بعد، ہم اگلے مرحلے پر جائیں گے، پولنگ موڈ میں داخل ہوں گے، اور بار بار onTick() فنکشن کو انجام دیں گے۔ اور نیند کا وقت مقرر کریں جب Sleep() پولز ہوں، کیونکہ کچھ cryptocurrency exchange APIs کے پاس ایک مخصوص مدت کے اندر اندر رسائی کی حد ہوتی ہے۔

//入口函数
function main() {
    // 过滤控制台中不是很重要的信息
    SetErrorFilter("429|GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout|Futures_OP");
    exchange.IO("currency", name + '_USDT'); //设置要交易的数字货币币种
    ObjChart.reset(); //程序启动前清空之前绘制的图表
    LogProfitReset(); //程序启动前清空之前的状态栏信息
    while (true) { // 进入轮询模式
        onTick(); // 执行onTick函数
        Sleep(500); // 休眠0.5秒
    }
}

ڈیٹا حاصل کریں اور حساب لگائیں۔ مرحلہ 1: ٹریڈنگ منطق میں استعمال کے لیے بنیادی ڈیٹا آبجیکٹ، اکاؤنٹ بیلنس، اور بول انڈیکیٹر ڈیٹا حاصل کریں۔

// 交易条件
function onTick() {
    var data = new Data(tradeTypeA, tradeTypeB); // 创建一个基础数据对象
    var accountStocks = data.accountData.Stocks; // 账户余额
    var boll = data.boll(dataLength, timeCycle); // 获取boll指标数据
    if (!boll) return; // 如果没有boll数据就返回
}

آرڈر دیں اور فالو اپ کریں۔ مرحلہ 1: اوپر دی گئی حکمت عملی کی منطق کے مطابق خرید و فروخت کی کارروائیوں کو انجام دیں۔ سب سے پہلے، یہ تعین کرتا ہے کہ آیا قیمت اور اشارے کی شرائط پوری ہوئی ہیں، پھر تعین کرتا ہے کہ آیا پوزیشن کی شرائط پوری ہوئی ہیں، اور آخر میں تجارت ( ) آرڈر فنکشن کو انجام دیتا ہے۔

// 交易条件
function onTick() {
    var data = new Data(tradeTypeA, tradeTypeB); // 创建一个基础数据对象
    var accountStocks = data.accountData.Stocks; // 账户余额
    var boll = data.boll(dataLength, timeCycle); // 获取boll指标数据
    if (!boll) return; // 如果没有boll数据就返回
    // 价差说明
    // basb = (合约A卖一价 - 合约B买一价)
    // sabb = (合约A买一价 - 合约B卖一价)
    if (data.sabb > boll.middle && data.sabb < boll.up) { // 如果sabb高于中轨
        if (data.mp(tradeTypeA, 0)) { // 下单前检测合约A是否有多单
            data.trade(tradeTypeA, "closebuy"); // 合约A平多
        }
        if (data.mp(tradeTypeB, 1)) { // 下单前检测合约B是否有空单
            data.trade(tradeTypeB, "closesell"); // 合约B平空
        }
    } else if (data.basb < boll.middle && data.basb > boll.down) { // 如果basb低于中轨
        if (data.mp(tradeTypeA, 1)) { // 下单前检测合约A是否有空单
            data.trade(tradeTypeA, "closesell"); // 合约A平空
        }
        if (data.mp(tradeTypeB, 0)) { // 下单前检测合约B是否有多单
            data.trade(tradeTypeB, "closebuy"); // 合约B平多
        }
    }
    if (accountStocks * Math.max(data.askA, data.askB) > 1) { // 如果账户有余额
        if (data.basb < boll.down) { // 如果basb价差低于下轨
            if (!data.mp(tradeTypeA, 0)) { // 下单前检测合约A是否有多单
                data.trade(tradeTypeA, "buy"); // 合约A开多
            }
            if (!data.mp(tradeTypeB, 1)) { // 下单前检测合约B是否有空单
                data.trade(tradeTypeB, "sell"); // 合约B开空
            }
        } else if (data.sabb > boll.up) { // 如果sabb价差高于上轨
            if (!data.mp(tradeTypeA, 1)) { // 下单前检测合约A是否有空单
                data.trade(tradeTypeA, "sell"); // 合约A开空
            }
            if (!data.mp(tradeTypeB, 0)) { // 下单前检测合约B是否有多单
                data.trade(tradeTypeB, "buy"); // 合约B开多
            }
        }
    }
}

مرحلہ 2: آرڈر دینے کے بعد، غیر معمولی حالات جیسے کہ نامکمل آرڈرز اور ایک ہی کنٹریکٹ کو سنبھالنے کی ضرورت ہے۔ اور ڈرائنگ چارٹس۔

// 交易条件
function onTick() {
    var data = new Data(tradeTypeA, tradeTypeB); // 创建一个基础数据对象
    var accountStocks = data.accountData.Stocks; // 账户余额
    var boll = data.boll(dataLength, timeCycle); // 获取boll指标数据
    if (!boll) return; // 如果没有boll数据就返回
    // 价差说明
    // basb = (合约A卖一价 - 合约B买一价)
    // sabb = (合约A买一价 - 合约B卖一价)
    if (data.sabb > boll.middle && data.sabb < boll.up) { // 如果sabb高于中轨
        if (data.mp(tradeTypeA, 0)) { // 下单前检测合约A是否有多单
            data.trade(tradeTypeA, "closebuy"); // 合约A平多
        }
        if (data.mp(tradeTypeB, 1)) { // 下单前检测合约B是否有空单
            data.trade(tradeTypeB, "closesell"); // 合约B平空
        }
    } else if (data.basb < boll.middle && data.basb > boll.down) { // 如果basb低于中轨
        if (data.mp(tradeTypeA, 1)) { // 下单前检测合约A是否有空单
            data.trade(tradeTypeA, "closesell"); // 合约A平空
        }
        if (data.mp(tradeTypeB, 0)) { // 下单前检测合约B是否有多单
            data.trade(tradeTypeB, "closebuy"); // 合约B平多
        }
    }
    if (accountStocks * Math.max(data.askA, data.askB) > 1) { // 如果账户有余额
        if (data.basb < boll.down) { // 如果basb价差低于下轨
            if (!data.mp(tradeTypeA, 0)) { // 下单前检测合约A是否有多单
                data.trade(tradeTypeA, "buy"); // 合约A开多
            }
            if (!data.mp(tradeTypeB, 1)) { // 下单前检测合约B是否有空单
                data.trade(tradeTypeB, "sell"); // 合约B开空
            }
        } else if (data.sabb > boll.up) { // 如果sabb价差高于上轨
            if (!data.mp(tradeTypeA, 1)) { // 下单前检测合约A是否有空单
                data.trade(tradeTypeA, "sell"); // 合约A开空
            }
            if (!data.mp(tradeTypeB, 0)) { // 下单前检测合约B是否有多单
                data.trade(tradeTypeB, "buy"); // 合约B开多
            }
        }
    }
    data.cancelOrders(); // 撤单
    data.drawingChart(boll); // 画图
    data.isEven(); // 处理持有单个合约
}

6. مکمل حکمت عملی

مندرجہ بالا میں، ہم نے صرف 200 لائنوں میں ایک سادہ ڈیجیٹل کرنسی انٹر پیریڈ ثالثی حکمت عملی بنائی ہے۔ مکمل کوڈ درج ذیل ہے:

// 全局变量
// 声明一个配置图表的 chart 对象
var chart = {
    __isStock: true,
    tooltip: {
        xDateFormat: '%Y-%m-%d %H:%M:%S, %A'
    },
    title: {
        text: '交易盈亏曲线图(详细)'
    },
    rangeSelector: {
        buttons: [{
            type: 'hour',
            count: 1,
            text: '1h'
        }, {
            type: 'hour',
            count: 2,
            text: '3h'
        }, {
            type: 'hour',
            count: 8,
            text: '8h'
        }, {
            type: 'all',
            text: 'All'
        }],
        selected: 0,
        inputEnabled: false
    },
    xAxis: {
        type: 'datetime'
    },
    yAxis: {
        title: {
            text: '价差'
        },
        opposite: false,
    },
    series: [{
        name: "上轨",
        id: "线1,up",
        data: []
    }, {
        name: "中轨",
        id: "线2,middle",
        data: []
    }, {
        name: "下轨",
        id: "线3,down",
        data: []
    }, {
        name: "basb",
        id: "线4,basb",
        data: []
    }, {
        name: "sabb",
        id: "线5,sabb",
        data: []
    }]
};
var ObjChart = Chart(chart); // 画图对象
var bars = []; // 存储价差序列
var oldTime = 0; // 记录历史数据时间戳

// 参数
var tradeTypeA = "this_week"; // 套利A合约
var tradeTypeB = "quarter"; // 套利B合约
var dataLength = 10; //指标周期长度
var timeCycle = 1; // K线周期
var name = "ETC"; // 币种
var unit = 1; // 下单量

// 基础数据
function Data(tradeTypeA, tradeTypeB) { // 传入套利A合约和套利B合约
    this.accountData = _C(exchange.GetAccount); // 获取账户信息
    this.positionData = _C(exchange.GetPosition); // 获取持仓信息
    var recordsData = _C(exchange.GetRecords); //获取K线数据
    exchange.SetContractType(tradeTypeA); // 订阅套利A合约
    var depthDataA = _C(exchange.GetDepth); // 套利A合约深度数据
    exchange.SetContractType(tradeTypeB); // 订阅套利B合约
    var depthDataB = _C(exchange.GetDepth); // 套利B合约深度数据
    this.time = recordsData[recordsData.length - 1].Time; // 获取最新数据时间
    this.askA = depthDataA.Asks[0].Price; // 套利A合约卖一价
    this.bidA = depthDataA.Bids[0].Price; // 套利A合约买一价
    this.askB = depthDataB.Asks[0].Price; // 套利B合约卖一价
    this.bidB = depthDataB.Bids[0].Price; // 套利B合约买一价
    // 正套价差(合约A卖一价 - 合约B买一价)
    this.basb = depthDataA.Asks[0].Price - depthDataB.Bids[0].Price;
    // 反套价差(合约A买一价 - 合约B卖一价)
    this.sabb = depthDataA.Bids[0].Price - depthDataB.Asks[0].Price;
}

// 获取持仓
Data.prototype.mp = function (tradeType, type) {
    var positionData = this.positionData; // 获取持仓信息
    for (var i = 0; i < positionData.length; i++) {
        if (positionData[i].ContractType == tradeType) {
            if (positionData[i].Type == type) {
                if (positionData[i].Amount > 0) {
                    return positionData[i].Amount;
                }
            }
        }
    }
    return false;
}

// 合成新K线数据和boll指标数据
Data.prototype.boll = function (num, timeCycle) {
    var self = {}; // 临时对象
    // 正套价差和反套价差中间值
    self.Close = (this.basb + this.sabb) / 2;
    if (this.timeA == this.timeB) {
        self.Time = this.time;
    } // 对比两个深度数据时间戳
    if (this.time - oldTime > timeCycle * 60000) {
        bars.push(self);
        oldTime = this.time;
    } // 根据指定时间周期,在K线数组里面传入价差数据对象
    if (bars.length > num * 2) {
        bars.shift(); // 控制K线数组长度
    } else {
        return;
    }
    var boll = TA.BOLL(bars, num, 2); // 调用talib库中的boll指标
    return {
        up: boll[0][boll[0].length - 1], // boll指标上轨
        middle: boll[1][boll[1].length - 1], // boll指标中轨
        down: boll[2][boll[2].length - 1] // boll指标下轨
    } // 返回一个处理好的boll指标数据
}

// 下单
Data.prototype.trade = function (tradeType, type) {
    exchange.SetContractType(tradeType); // 下单前先重新订阅合约
    var askPrice, bidPrice;
    if (tradeType == tradeTypeA) { // 如果是A合约下单
        askPrice = this.askA; // 设置askPrice
        bidPrice = this.bidA; // 设置bidPrice
    } else if (tradeType == tradeTypeB) { // 如果是B合约下单
        askPrice = this.askB; // 设置askPrice
        bidPrice = this.bidB; // 设置bidPrice
    }
    switch (type) { // 匹配下单模式
        case "buy":
            exchange.SetDirection(type); // 设置下单模式
            return exchange.Buy(askPrice, unit);
        case "sell":
            exchange.SetDirection(type); // 设置下单模式
            return exchange.Sell(bidPrice, unit);
        case "closebuy":
            exchange.SetDirection(type); // 设置下单模式
            return exchange.Sell(bidPrice, unit);
        case "closesell":
            exchange.SetDirection(type); // 设置下单模式
            return exchange.Buy(askPrice, unit);
        default:
            return false;
    }
}

// 取消订单
Data.prototype.cancelOrders = function () {
    Sleep(500); // 撤单前先延时,因为有些交易所你懂的
    var orders = _C(exchange.GetOrders); // 获取未成交订单数组
    if (orders.length > 0) { // 如果有未成交的订单
        for (var i = 0; i < orders.length; i++) { //遍历未成交订单数组
            exchange.CancelOrder(orders[i].Id); //逐个取消未成交的订单
            Sleep(500); //延时0.5秒
        }
        return false; // 如果取消了未成交的单子就返回false
    }
    return true; //如果没有未成交的订单就返回true
}

// 处理持有单个合约
Data.prototype.isEven = function () {
    var positionData = this.positionData; // 获取持仓信息
    var type = null; // 转换持仓方向
    // 如果持仓数组长度余2不等于0或者持仓数组长度不等于2
    if (positionData.length % 2 != 0 || positionData.length != 2) {
        for (var i = 0; i < positionData.length; i++) { // 遍历持仓数组
            if (positionData[i].Type == 0) { // 如果是多单
                type = 10; // 设置下单参数
            } else if (positionData[i].Type == 1) { // 如果是空单
                type = -10; // 设置下单参数
            }
            // 平掉所有仓位
            this.trade(positionData[i].ContractType, type, positionData[i].Amount);
        }
    }
}

// 画图
Data.prototype.drawingChart = function (boll) {
    var nowTime = new Date().getTime();
    ObjChart.add([0, [nowTime, boll.up]]);
    ObjChart.add([1, [nowTime, boll.middle]]);
    ObjChart.add([2, [nowTime, boll.down]]);
    ObjChart.add([3, [nowTime, this.basb]]);
    ObjChart.add([4, [nowTime, this.sabb]]);
    ObjChart.update(chart);
}

// 交易条件
function onTick() {
    var data = new Data(tradeTypeA, tradeTypeB); // 创建一个基础数据对象
    var accountStocks = data.accountData.Stocks; // 账户余额
    var boll = data.boll(dataLength, timeCycle); // 获取boll指标数据
    if (!boll) return; // 如果没有boll数据就返回
    // 价差说明
    // basb = (合约A卖一价 - 合约B买一价)
    // sabb = (合约A买一价 - 合约B卖一价)
    if (data.sabb > boll.middle && data.sabb < boll.up) { // 如果sabb高于中轨
        if (data.mp(tradeTypeA, 0)) { // 下单前检测合约A是否有多单
            data.trade(tradeTypeA, "closebuy"); // 合约A平多
        }
        if (data.mp(tradeTypeB, 1)) { // 下单前检测合约B是否有空单
            data.trade(tradeTypeB, "closesell"); // 合约B平空
        }
    } else if (data.basb < boll.middle && data.basb > boll.down) { // 如果basb低于中轨
        if (data.mp(tradeTypeA, 1)) { // 下单前检测合约A是否有空单
            data.trade(tradeTypeA, "closesell"); // 合约A平空
        }
        if (data.mp(tradeTypeB, 0)) { // 下单前检测合约B是否有多单
            data.trade(tradeTypeB, "closebuy"); // 合约B平多
        }
    }
    if (accountStocks * Math.max(data.askA, data.askB) > 1) { // 如果账户有余额
        if (data.basb < boll.down) { // 如果basb价差低于下轨
            if (!data.mp(tradeTypeA, 0)) { // 下单前检测合约A是否有多单
                data.trade(tradeTypeA, "buy"); // 合约A开多
            }
            if (!data.mp(tradeTypeB, 1)) { // 下单前检测合约B是否有空单
                data.trade(tradeTypeB, "sell"); // 合约B开空
            }
        } else if (data.sabb > boll.up) { // 如果sabb价差高于上轨
            if (!data.mp(tradeTypeA, 1)) { // 下单前检测合约A是否有空单
                data.trade(tradeTypeA, "sell"); // 合约A开空
            }
            if (!data.mp(tradeTypeB, 0)) { // 下单前检测合约B是否有多单
                data.trade(tradeTypeB, "buy"); // 合约B开多
            }
        }
    }
    data.cancelOrders(); // 撤单
    data.drawingChart(boll); // 画图
    data.isEven(); // 处理持有单个合约
}

//入口函数
function main() {
    // 过滤控制台中不是很重要的信息
    SetErrorFilter("429|GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout|Futures_OP");
    exchange.IO("currency", name + '_USDT'); //设置要交易的数字货币币种
    ObjChart.reset(); //程序启动前清空之前绘制的图表
    LogProfitReset(); //程序启动前清空之前的状态栏信息
    while (true) { // 进入轮询模式
        onTick(); // 执行onTick函数
        Sleep(500); // 休眠0.5秒
    }
}

پالیسی کا پتہ: https://www.fmz.com/strategy/104964

VII

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

وجہ یہ ہے کہ ڈیجیٹل کرنسی ایکسچینج کی فیوچر مارکیٹ چاہے کوئی بھی ہو، مارجن قانونی کرنسی نہیں ہے۔ آج کل، اس سال کے آغاز سے تقریباً تمام ڈیجیٹل کرنسیوں میں تقریباً 70% کی کمی واقع ہوئی ہے۔ دوسرے الفاظ میں، حکمت عملی ہمیشہ پیسہ کماتی ہے، لیکن کرنسی کی قیمت گر رہی ہے. اردگرد نظر ڈالیں، ایسا لگتا ہے کہ ڈیجیٹل کرنسی مارکیٹ کو بلاک چین سے الگ کر دیا گیا ہے، بالکل اسی طرح جیسے اس وقت، قیمتیں ہمیشہ لوگوں کی توقعات اور اعتماد سے آتی ہیں، اور اعتماد قیمتوں سے آتا ہے…