ডিজিটাল মুদ্রা ফিউচার ট্রেডিং এর যুক্তি সম্পর্কে কিছু চিন্তাভাবনা

লেখক:লিডিয়া, সৃষ্টিঃ ২০২২-১১-৩০ 17:12:20, আপডেটঃ ২০২৩-০৯-১১ ১৯ঃ৫৯ঃ৫৫

img

ডিজিটাল মুদ্রা ফিউচার ট্রেডিং এর যুক্তি সম্পর্কে কিছু চিন্তাভাবনা

সমস্যার দৃশ্যকল্প

দীর্ঘদিন ধরে, ডিজিটাল মুদ্রা এক্সচেঞ্জের অবস্থান এপিআই ইন্টারফেসের ডেটা বিলম্ব সমস্যাটি আমাকে সবসময় বিরক্ত করেছে। আমি এই সমস্যার সাথে মোকাবিলা করার সঠিক উপায় খুঁজে পাইনি। সমস্যাটির দৃশ্যটি পুনরুত্পাদন করতে দিন। সাধারণত, চুক্তি এক্সচেঞ্জ দ্বারা সরবরাহিত বাজার মূল্য অর্ডার আসলে প্রতিপক্ষের মূল্য, তাই কখনও কখনও এটি এই তথাকথিত বাজার মূল্য অর্ডার ব্যবহার করা নির্ভরযোগ্য নয়। অতএব, যখন আমরা ডিজিটাল মুদ্রা ফিউচার ট্রেডিং কৌশলগুলি লিখি, আমরা সর্বাধিক সীমা অর্ডারটি ব্যবহার করি। প্রতিটি অর্ডার স্থাপন করার পরে, অর্ডারটি বন্ধ হয়ে গেছে এবং সংশ্লিষ্ট অবস্থানটি রাখা হয়েছে কিনা তা দেখতে আমাদের অবস্থানটি পরীক্ষা করতে হবে। সমস্যাটি এই তথ্যের অবস্থানে রয়েছে। যদি অর্ডারটি বন্ধ হয় তবে এক্সচেঞ্জের অবস্থান তথ্য ইন্টারফেসের দ্বারা ডেটা এক্সচেঞ্জটি ফিরে আসে (অর্থাৎ, আমরা যখন এক্সচেঞ্জটি পূরণ করি তখন নীচের স্তরটি আসলে অ্যাক্সেস করা ইন্টারফেসটি) খুব গুরুতর অবস্থানের তথ্য অন্তর্ভুক্ত করা উচিত। তবে, পুরানো অবস্থানের দ্বারা ডেটা ট্র্যাজেকশনটি

বাস্তব অভিজ্ঞতা

এই সমস্যার কারণে, আমি পাগলামি করে লং পজিশনে ভরা একটি কৌশল খোলা দেখেছি। সৌভাগ্যবশত, সেই সময়ে বাজার উড়ে গিয়েছিল, এবং ভাসমান মুনাফা 10 বিটিসি অতিক্রম করেছিল। সৌভাগ্যবশত, বাজার তীব্রভাবে বৃদ্ধি পেয়েছিল। যদি এটি তীব্রভাবে হ্রাস পায়, আমরা ফলাফলটি কল্পনা করতে পারি।

সমাধান

  • সমাধান ১ কৌশলটি কেবলমাত্র একটি অর্ডার দেওয়ার জন্য ডিজাইন করা যেতে পারে, এবং অর্ডার মূল্য হ'ল বর্তমান ট্রেডিং প্রতিপক্ষের মূল্য প্লাস একটি বড় স্লাইডিং মূল্য, যাতে প্রতিপক্ষের আদেশের একটি নির্দিষ্ট গভীরতা নেওয়া যায়। এর সুবিধা হ'ল কেবলমাত্র একটি অর্ডার স্থাপন করা হবে এবং এটি অবস্থান তথ্যের ভিত্তিতে বিচার করা হবে না। এটি পুনরাবৃত্তি আদেশের সমস্যা এড়াতে পারে, তবে কখনও কখনও অর্ডার স্থাপন করা যখন দামের পরিবর্তন তুলনামূলকভাবে বড় হয় তখন এক্সচেঞ্জের মূল্য সীমা প্রক্রিয়াটি ট্রিগার করতে পারে এবং স্লাইডিং দাম বাড়ানো এবং এখনও একটি চুক্তি করতে ব্যর্থ হওয়া সম্ভব, এইভাবে সুযোগটি মিস করা।

  • সমাধান ২ এক্সচেঞ্জের মার্কেট প্রাইস অর্ডার ফাংশনের মাধ্যমে, মার্কেট প্রাইস অর্ডার হিসাবে এফএমজেড-এ -১-এ মূল্য স্থানান্তর করা হয়। বর্তমানে, ওকেএক্স ফিউচার ইন্টারফেসটি বাস্তব মার্কেট প্রাইস অর্ডারকে সমর্থন করার জন্য আপগ্রেড করা হয়েছে।

  • সমাধান ৩ আমরা এখনও পূর্ববর্তী ট্রেডিং লজিক ব্যবহার করি এবং দামের সীমা অর্ডার সহ অর্ডার রাখি, তবে অবস্থান ডেটা বিলম্বের কারণে সমস্যাটি সমাধান করার চেষ্টা করার জন্য আমরা ট্রেডিং লজিকটিতে কিছু সনাক্তকরণ যুক্ত করি। অর্ডারটি বাতিল না করেই মুলতুবি অর্ডারগুলির তালিকা থেকে সরাসরি অদৃশ্য হয়ে গেছে কিনা তা পরীক্ষা করুন (মুলতুবি অর্ডারগুলির তালিকা থেকে অদৃশ্য হওয়ার দুটি সম্ভাবনা রয়েছেঃ ১. বাতিলকরণ এবং ২. পূরণ করা হয়েছে) । যদি এই জাতীয় পরিস্থিতি সনাক্ত করা হয় এবং পুনরায় স্থাপন করা অর্ডারের পরিমাণটি শেষ অর্ডারের মতোই হয় তবে এটি লক্ষ করা গুরুত্বপূর্ণ যে অবস্থান ডেটা বিলম্বিত কিনা। অবস্থান তথ্য পুনরায় অর্জনের জন্য প্রোগ্রামটি অপেক্ষা করার লজিকটি প্রবেশ করুক, এমনকি অপেক্ষা করার সময়গুলি ট্রিগার করতে অপেক্ষা করার সময়গুলি অপ্টিমাইজ এবং বাড়িয়ে তুলুন, যদি এটি নির্দিষ্ট সংখ্যক অবস্থানের সময় অতিক্রম করে তবে এটি ইঙ্গিত করে যে ইন্টারফেস ডেটা বিলম্ব গুরুতর, যা ট্রেডিং লজিকের সমাপ্তির কারণ হয়।

সমাধান ৩ এর উপর ভিত্তি করে নকশা

// Parameters
/*
var MinAmount = 1
var SlidePrice = 5
var Interval = 500
*/

function GetPosition(e, contractType, direction) {
    e.SetContractType(contractType)
    var positions = _C(e.GetPosition);
    for (var i = 0; i < positions.length; i++) {
        if (positions[i].ContractType == contractType && positions[i].Type == direction) {
            return positions[i]
        }
    }

    return null
}

function Open(e, contractType, direction, opAmount) {
    var initPosition = GetPosition(e, contractType, direction);
    var isFirst = true;
    var initAmount = initPosition ? initPosition.Amount : 0;
    var nowPosition = initPosition;
    var directBreak = false 
    var preNeedOpen = 0
    var timeoutCount = 0
    while (true) {
        var ticker = _C(e.GetTicker)
        var needOpen = opAmount;
        if (isFirst) {
            isFirst = false;
        } else {
            nowPosition = GetPosition(e, contractType, direction);
            if (nowPosition) {
                needOpen = opAmount - (nowPosition.Amount - initAmount);
            }
            // Check directBreak and the position remains unchanged
            if (preNeedOpen == needOpen && directBreak) {
                Log("Suspected position data is delayed, wait for 30 seconds", "#FF0000")
                Sleep(30000)
                nowPosition = GetPosition(e, contractType, direction);
                if (nowPosition) {
                    needOpen = opAmount - (nowPosition.Amount - initAmount);
                }
                /*
                timeoutCount++
                if (timeoutCount > 10) {
                    Log("Suspected position is delayed for 10 consecutive times, and the order is failed!", "#FF0000")
                    break
                }
                */
            } else {
                timeoutCount = 0
            }
        }
        if (needOpen < MinAmount) {
            break;
        }
        
        var amount = needOpen;
        preNeedOpen = needOpen
        e.SetDirection(direction == PD_LONG ? "buy" : "sell");
        var orderId;
        if (direction == PD_LONG) {
            orderId = e.Buy(ticker.Sell + SlidePrice, amount, "open long positions", contractType, ticker);
        } else {
            orderId = e.Sell(ticker.Buy - SlidePrice, amount, "open short positions", contractType, ticker);
        }

        directBreak = false
        var n = 0
        while (true) {
            Sleep(Interval);
            var orders = _C(e.GetOrders);
            if (orders.length == 0) {
                if (n == 0) {
                    directBreak = true
                }
                break;
            }
            for (var j = 0; j < orders.length; j++) {
                e.CancelOrder(orders[j].Id);
                if (j < (orders.length - 1)) {
                    Sleep(Interval);
                }
            }
            n++
        }
    }

    var ret = {
        price: 0,
        amount: 0,
        position: nowPosition
    };
    if (!nowPosition) {
        return ret;
    }
    if (!initPosition) {
        ret.price = nowPosition.Price;
        ret.amount = nowPosition.Amount;
    } else {
        ret.amount = nowPosition.Amount - initPosition.Amount;
        ret.price = _N(((nowPosition.Price * nowPosition.Amount) - (initPosition.Price * initPosition.Amount)) / ret.amount);
    }
    return ret;
}

function Cover(e, contractType, opAmount, direction) {
    var initPosition = null;
    var position = null;
    var isFirst = true;

    while (true) {
        while (true) {
            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);
                }
            }
        }

        position = GetPosition(e, contractType, direction)
        if (!position) {
            break
        }
        if (isFirst == true) {
            initPosition = position;
            opAmount = Math.min(opAmount, initPosition.Amount)
            isFirst = false;
        }

        var amount = opAmount - (initPosition.Amount - position.Amount)
        if (amount <= 0) {
            break
        }

        var ticker = _C(exchange.GetTicker)
        if (position.Type == PD_LONG) {
            e.SetDirection("closebuy");
            e.Sell(ticker.Buy - SlidePrice, amount, "close long positions", contractType, ticker);
        } else if (position.Type == PD_SHORT) {
            e.SetDirection("closesell");
            e.Buy(ticker.Sell + SlidePrice, amount, "close short positions", contractType, ticker);
        }

        Sleep(Interval)
    }

    return position
}

$.OpenLong = function(e, contractType, amount) {
    if (typeof(e) == "string") {
        amount = contractType
        contractType = e
        e = exchange
    }

    return Open(e, contractType, PD_LONG, amount);
}

$.OpenShort = function(e, contractType, amount) {
    if (typeof(e) == "string") {
        amount = contractType
        contractType = e
        e = exchange
    }

    return Open(e, contractType, PD_SHORT, amount);
};

$.CoverLong = function(e, contractType, amount) {
    if (typeof(e) == "string") {
        amount = contractType
        contractType = e
        e = exchange
    }

    return Cover(e, contractType, amount, PD_LONG);
};

$.CoverShort = function(e, contractType, amount) {
    if (typeof(e) == "string") {
        amount = contractType
        contractType = e
        e = exchange
    }

    return Cover(e, contractType, amount, PD_SHORT);
};


function main() {
    Log(exchange.GetPosition())
    var info = $.OpenLong(exchange, "quarter", 100)
    Log(info, "#FF0000")

    Log(exchange.GetPosition())
    info = $.CoverLong(exchange, "quarter", 30)
    Log(exchange.GetPosition())
    Log(info, "#FF0000")

    info = $.CoverLong(exchange, "quarter", 80)
    Log(exchange.GetPosition())
    Log(info, "#FF0000")
}

টেমপ্লেট ঠিকানাঃhttps://www.fmz.com/strategy/203258

টেমপ্লেট ইন্টারফেস একই ভাবে বলা হয়$.OpenLong, $.CoverLongউপরের প্রধান ফাংশনে। টেমপ্লেটটি একটি বিটা সংস্করণ, এবং আপনি সুপারিশ করতে স্বাগত জানাই। আমরা এটি অপ্টিমাইজ করা চালিয়ে যাব যাতে আমরা অবস্থান তথ্য বিলম্ব সমস্যা মোকাবেলা করতে পারেন।


সম্পর্কিত

আরো