বাইনারেন্স ফিউচার মাল্টি-ভারেন্সি হেজিং স্ট্র্যাটেজি পার্ট 4 এর উপর গবেষণা

লেখক:ভাল, তৈরিঃ 2020-05-14 15:18:56, আপডেটঃ 2023-11-04 19:51:33

img

Binance futures multi-currency hedging strategy's সাম্প্রতিক পর্যালোচনা এবং মিনিট স্তরের K-line backtest ফলাফল

বাইনারেন্সের মাল্টি মুদ্রা হেজিং কৌশল সম্পর্কে তিনটি গবেষণা প্রতিবেদন প্রকাশিত হয়েছে, এখানে চতুর্থটি রয়েছে। প্রথম তিনটি নিবন্ধের সংযোগ, আপনি যদি এটি না পড়ে থাকেন তবে আপনাকে এটি আবার পড়তে হবে, আপনি কৌশলটির গঠনের ধারণা, নির্দিষ্ট পরামিতিগুলির সেটিং এবং কৌশল যুক্তি বুঝতে পারেন।

বাইনারেন্স ফিউচারস মাল্টি মুদ্রা হেজিং কৌশল অংশ ১ এর উপর গবেষণাঃhttps://www.fmz.com/digest-topic/5584

বাইনারেন্স ফিউচার মাল্টি-ভারেন্সি হেজিং স্ট্র্যাটেজি পার্ট ২ এর উপর গবেষণাঃhttps://www.fmz.com/digest-topic/5588

বাইনারেন্স ফিউচার মাল্টি-কার্উয়েন্সি হেজিং স্ট্র্যাটেজি পার্ট ৩ এর উপর গবেষণাঃhttps://www.fmz.com/digest-topic/5605

এই নিবন্ধটি সাম্প্রতিক সপ্তাহের প্রকৃত বাজারের পরিস্থিতি পর্যালোচনা করতে এবং লাভ এবং ক্ষতির সংক্ষিপ্তসার করতে। গত দুই মাসের বিন্যান্স ফিউচার মিনিটের কে লাইন ডেটা ক্রল করার পরে, মূল 1h কে লাইন ব্যাকটেস্টের ফলাফলগুলি আপডেট করা যেতে পারে, যা কিছু পরামিতি সেটিংসের অর্থ আরও ভালভাবে ব্যাখ্যা করতে পারে।

# Libraries to import
import pandas as pd
import requests
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
%matplotlib inline
symbols = ['BTC','ETH', 'BCH', 'XRP', 'EOS', 'LTC', 'TRX', 'ETC', 'LINK', 'XLM', 'ADA', 'XMR', 'DASH', 'ZEC', 'XTZ', 'BNB', 'ATOM', 'ONT', 'IOTA', 'BAT', 'VET', 'NEO', 'QTUM', 'IOST']

মিনিট স্তরের K লাইন ডেটা

২১ ফেব্রুয়ারি থেকে ১৫ এপ্রিল দুপুর ২টা পর্যন্ত, মোট ৭৭১৬০*২৪, যা আমাদের ব্যাকটেস্টের গতিকে ব্যাপকভাবে হ্রাস করেছে, ব্যাকটেস্ট ইঞ্জিনটি যথেষ্ট দক্ষ নয়, আপনি এটি নিজেরাই অপ্টিমাইজ করতে পারেন। ভবিষ্যতে, আমি নিয়মিত সর্বশেষতম ডেটা ট্র্যাক করব।

price_usdt = pd.read_csv('https://www.fmz.com/upload/asset/2b1fa7ab641385067ad.csv',index_col = 0)
price_usdt.shape
(77160, 24)
price_usdt.index = pd.to_datetime(price_usdt.index,unit='ms')
price_usdt_norm = price_usdt/price_usdt.fillna(method='bfill').iloc[0,]
price_usdt_btc = price_usdt.divide(price_usdt['BTC'],axis=0)
price_usdt_btc_norm = price_usdt_btc/price_usdt_btc.fillna(method='bfill').iloc[0,]
class Exchange:
    
    def __init__(self, trade_symbols, leverage=20, commission=0.00005,  initial_balance=10000, log=False):
        self.initial_balance = initial_balance # Initial asset
        self.commission = commission
        self.leverage = leverage
        self.trade_symbols = trade_symbols
        self.date = ''
        self.log = log
        self.df = pd.DataFrame(columns=['margin','total','leverage','realised_profit','unrealised_profit'])
        self.account = {'USDT':{'realised_profit':0, 'margin':0, 'unrealised_profit':0, 'total':initial_balance, 'leverage':0, 'fee':0}}
        for symbol in trade_symbols:
            self.account[symbol] = {'amount':0, 'hold_price':0, 'value':0, 'price':0, 'realised_profit':0, 'margin':0, 'unrealised_profit':0,'fee':0}
            
    def Trade(self, symbol, direction, price, amount, msg=''):
        if self.date and self.log:
            print('%-20s%-5s%-5s%-10.8s%-8.6s %s'%(str(self.date), symbol, 'buy' if direction == 1 else 'sell', price, amount, msg))
            
        cover_amount = 0 if direction*self.account[symbol]['amount'] >=0 else min(abs(self.account[symbol]['amount']), amount)
        open_amount = amount - cover_amount
        
        self.account['USDT']['realised_profit'] -= price*amount*self.commission # Minus handling fee
        self.account['USDT']['fee'] += price*amount*self.commission
        self.account[symbol]['fee'] += price*amount*self.commission
        
        if cover_amount > 0: # close position first
            self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount  # profit
            self.account['USDT']['margin'] -= cover_amount*self.account[symbol]['hold_price']/self.leverage # Free margin
            
            self.account[symbol]['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount
            self.account[symbol]['amount'] -= -direction*cover_amount
            self.account[symbol]['margin'] -=  cover_amount*self.account[symbol]['hold_price']/self.leverage
            self.account[symbol]['hold_price'] = 0 if self.account[symbol]['amount'] == 0 else self.account[symbol]['hold_price']
            
        if open_amount > 0:
            total_cost = self.account[symbol]['hold_price']*direction*self.account[symbol]['amount'] + price*open_amount
            total_amount = direction*self.account[symbol]['amount']+open_amount
            
            self.account['USDT']['margin'] +=  open_amount*price/self.leverage            
            self.account[symbol]['hold_price'] = total_cost/total_amount
            self.account[symbol]['amount'] += direction*open_amount
            self.account[symbol]['margin'] +=  open_amount*price/self.leverage
            
        self.account[symbol]['unrealised_profit'] = (price - self.account[symbol]['hold_price'])*self.account[symbol]['amount']
        self.account[symbol]['price'] = price
        self.account[symbol]['value'] = abs(self.account[symbol]['amount'])*price
        
        return True
    
    def Buy(self, symbol, price, amount, msg=''):
        self.Trade(symbol, 1, price, amount, msg)
        
    def Sell(self, symbol, price, amount, msg=''):
        self.Trade(symbol, -1, price, amount, msg)
        
    def Update(self, date, close_price): # Update assets
        self.date = date
        self.close = close_price
        self.account['USDT']['unrealised_profit'] = 0
        for symbol in self.trade_symbols:
            if np.isnan(close_price[symbol]):
                continue
            self.account[symbol]['unrealised_profit'] = (close_price[symbol] - self.account[symbol]['hold_price'])*self.account[symbol]['amount']
            self.account[symbol]['price'] = close_price[symbol]
            self.account[symbol]['value'] = abs(self.account[symbol]['amount'])*close_price[symbol]
            self.account['USDT']['unrealised_profit'] += self.account[symbol]['unrealised_profit']
        
        self.account['USDT']['total'] = round(self.account['USDT']['realised_profit'] + self.initial_balance + self.account['USDT']['unrealised_profit'],6)
        self.account['USDT']['leverage'] = round(self.account['USDT']['margin']/self.account['USDT']['total'],4)*self.leverage
        self.df.loc[self.date] = [self.account['USDT']['margin'],self.account['USDT']['total'],self.account['USDT']['leverage'],self.account['USDT']['realised_profit'],self.account['USDT']['unrealised_profit']]

গত সপ্তাহের পর্যালোচনা

কৌশল কোডটি 10 এপ্রিল ওয়েচ্যাট গ্রুপে প্রকাশিত হয়েছিল। শুরুতে, একদল লোক কৌশলটি চালিয়েছিল 2 ((সংক্ষিপ্ত ওভার-রাইজ এবং দীর্ঘ ওভার-ডাউন) । প্রথম তিন দিনে, রিটার্নটি খুব ভাল ছিল, এবং রিট্র্যাকশনটি খুব কম ছিল। পরবর্তী দিনগুলিতে, কিছু ব্যবসায়ী লিভারেজটি প্রসারিত করেছিলেন, কেউ কেউ তাদের তহবিলের পুরো পরিমাণটিও অপারেট করার জন্য ব্যবহার করেছিলেন এবং এক দিনের মধ্যে লাভ 10% পৌঁছেছিল। কৌশল স্কোয়ার অনেকগুলি বাস্তব বাজারের কৌশলও প্রকাশ করেছিল, অনেক লোক সংরক্ষণশীল প্রস্তাবিত পরামিতিগুলির সাথে অসন্তুষ্ট হতে শুরু করেছিল এবং লেনদেনের পরিমাণকে প্রসারিত করেছিল। 13 এপ্রিলের পরে, বিএনবি এর স্বাধীন প্রবণতার কারণে, মুনাফা পিছিয়ে যেতে এবং পাশের দিকে ফিরে যেতে শুরু করে। আপনি যদি 3% trade_value এর ডিফল্ট প্যারামিটারগুলি দেখেন তবে এটি সম্ভবত 1% পিছিয়ে গেছে। তবে, প্রসারিত মানগুলির কারণে, অনেক ব্যবসায়ী এবং প্রত্যেকে অনেক কম আয় করে। এই রিট্র্যাকশন তরঙ্গটি

img

আসুন কৌশল ২ এর সম্পূর্ণ মুদ্রা ব্যাকটেস্ট দেখুন। এখানে, এটি একটি মিনিটের স্তরের আপডেট হওয়ায়, আলফা প্যারামিটারটি সামঞ্জস্য করা দরকার। বাস্তব বাজারের দৃষ্টিকোণ থেকে, বক্ররেখা প্রবণতা ধারাবাহিক, যা নির্দেশ করে যে আমাদের ব্যাকটেস্টটি একটি শক্তিশালী রেফারেন্স হিসাবে ব্যবহার করা যেতে পারে। নেট মূল্য 4.13 থেকে নেট মূল্যের শীর্ষে পৌঁছেছে এবং পুনরুদ্ধার এবং পাশের পর্যায়ে রয়েছে।

Alpha = 0.001
#price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.rolling(20).mean() # Ordinary moving average
price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() # Here is consistent with the strategy, using EMA
trade_symbols = list(set(symbols))
price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.00075,log=False)
trade_value = 300
for row in price_usdt.iloc[-7500:].iterrows():
    e.Update(row[0], row[1])
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm2.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,1)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        if aim_value - now_value > 0.5*trade_value:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -0.5*trade_value:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2a = e
(stragey_2a.df['total']/stragey_2d.initial_balance).plot(figsize=(17,6),grid = True);

img

কৌশল ১, শর্ট অল্টকয়েন কৌশল ইতিবাচক রিটার্ন অর্জন করে

trade_symbols = list(set(symbols)-set(['LINK','BTC','XTZ','BCH', 'ETH'])) # Selling short currencies
e = Exchange(trade_symbols+['BTC'],initial_balance=10000,commission=0.00075,log=False)
trade_value = 2000
for row in price_usdt.iloc[-7500:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        if e.account[symbol]['value'] - trade_value  < -120 :
            e.Sell(symbol, price, round((trade_value-e.account[symbol]['value'])/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if e.account[symbol]['value'] - trade_value > 120 :
            e.Buy(symbol, price, round((e.account[symbol]['value']-trade_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        empty_value += e.account[symbol]['value']
    price = row[1]['BTC']
    if e.account['BTC']['value'] - empty_value < -120:
        e.Buy('BTC', price, round((empty_value-e.account['BTC']['value'])/price,6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
    if e.account['BTC']['value'] - empty_value > 120:
        e.Sell('BTC', price, round((e.account['BTC']['value']-empty_value)/price,6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
stragey_1 = e
(stragey_1.df['total']/stragey_1.initial_balance).plot(figsize=(17,6),grid = True);

img

কৌশল ২. লং ওভার-ডাউন কেনা এবং সংক্ষিপ্ত ওভার-রাইজ বিক্রয় লাভ বিশ্লেষণ

চূড়ান্ত হিসাবের তথ্য মুদ্রণ করে দেখা যায় যে বেশিরভাগ মুদ্রায় মুনাফা হয়েছে এবং বিএনবি সর্বাধিক ক্ষতির সম্মুখীন হয়েছে। এটি মূলত কারণ বিএনবি স্বাধীন প্রবণতার তরঙ্গ থেকে বেরিয়ে এসেছে, অনেক বেশি বেড়েছে এবং বৃহত্তম বিচ্যুতি 0.06।

pd.DataFrame(stragey_2a.account).T.apply(lambda x:round(x,3)).sort_values(by='realised_profit')

img

# BNB deviation
(price_usdt_btc_norm2.iloc[-7500:].BNB-price_usdt_btc_norm_mean[-7500:]).plot(figsize=(17,6),grid = True);
#price_usdt_btc_norm_mean[-7500:].plot(figsize=(17,6),grid = True);

img

যদি বিএনবি এবং এটম সরিয়ে ফেলা হয়, তাহলে ফলাফল আরও ভাল হবে, কিন্তু কৌশলটি এখনও সাম্প্রতিক সময়ে পুনরুদ্ধারের পর্যায়ে থাকবে।

Alpha = 0.001
price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() # Here is consistent with the strategy, using EMA
trade_symbols = list(set(symbols)-set(['BNB','ATOM']))
price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.00075,log=False)
trade_value = 300
for row in price_usdt.iloc[-7500:].iterrows():
    e.Update(row[0], row[1])
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm2.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,1)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        if aim_value - now_value > 0.5*trade_value:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -0.5*trade_value:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2b = e
(stragey_2b.df['total']/stragey_2b.initial_balance).plot(figsize=(17,6),grid = True);

img

গত দুই দিনে, মূলধারার মুদ্রা কৌশলগুলি চালানো জনপ্রিয় হয়ে উঠেছে। আসুন এই কৌশলটি ব্যাকটেস্ট করি। মুদ্রার বৈচিত্র্যের হ্রাসের কারণে, তুলনা করার জন্য trade_value যথাযথভাবে 4 গুণ বৃদ্ধি পেয়েছে এবং ফলাফলগুলি ভালভাবে সম্পাদন করেছে, বিশেষত সাম্প্রতিক পুনরুদ্ধারটি ছোট ছিল।

এটি লক্ষ করা উচিত যে শুধুমাত্র মূলধারার মুদ্রা দীর্ঘ সময়ের ব্যাকটেস্টে পুরো মুদ্রার মতো ভাল নয়, এবং আরও বেশি পুনর্নির্মাণ রয়েছে। আপনি নীচের ঘন্টার লাইনে নিজের ব্যাকটেস্ট করতে পারেন, প্রধানত কারণ মুদ্রা কম ছড়িয়ে পড়ে এবং পরিবর্তে অস্থিরতা বৃদ্ধি পায়।

Alpha = 0.001
price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() # Here is consistent with the strategy, using EMA
trade_symbols = ['ETH','LTC','EOS','XRP','BCH']
price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.00075,log=False)
trade_value = 1200
for row in price_usdt.iloc[-7500:].iterrows():
    e.Update(row[0], row[1])
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm2.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,1)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        if aim_value - now_value > 0.5*trade_value:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -0.5*trade_value:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2c = e
(stragey_2c.df['total']/e.initial_balance).plot(figsize=(17,6),grid = True);

img

হ্যান্ডলিং ফি এবং কৌশল পরামিতি বিশ্লেষণ

যেহেতু প্রথম কয়েক রিপোর্ট ঘন্টা স্তর k লাইন ব্যবহৃত, এবং প্রকৃত পরামিতি বাস্তব বাজারের পরিস্থিতির সঙ্গে খুব ভিন্ন, এখন মিনিট স্তর k লাইন সঙ্গে, আপনি দেখতে পারেন কিভাবে কিছু পরামিতি সেট করতে. প্রথম ডিফল্ট পরামিতি সেটিংস তাকানঃ

  • আলফা = ০.০৩ এক্সপোনেনশিয়াল মুভিং এভারেজের আলফা প্যারামিটার। সেটিং যত বড়, বেঞ্চমার্ক মূল্য ট্র্যাকিং তত বেশি সংবেদনশীল এবং কম লেনদেন। চূড়ান্ত হোল্ডিং অবস্থানও কম হবে, যা লিভারেজ হ্রাস করবে, তবে রিটার্ন এবং সর্বাধিক পুনরুদ্ধারগুলিও হ্রাস করবে।

  • Update_base_price_time_interval = 30 * 60 আলফা প্যারামিটার সম্পর্কিত, সেকেন্ডে বেস মূল্য আপডেট করার জন্য কতবার, আলফা সেটিং ছোট, ছোট ব্যবধান সেট করা যেতে পারে

  • ট্রেড_ভ্যালুঃ অল্টকয়েন মূল্যের (বিটিসি-নাম্বিত) প্রতি 1% সূচক হোল্ডিং মান থেকে বিচ্যুত হয়, যা বিনিয়োগকৃত মোট তহবিল এবং ঝুঁকি পছন্দ অনুসারে নির্ধারণ করা দরকার। মোট তহবিলের 3-10% সেট করার পরামর্শ দেওয়া হয়। আপনি গবেষণা পরিবেশের ব্যাকটেস্টের মাধ্যমে লিভারের আকারটি দেখতে পারেন। ট্রেড_ভ্যালু অ্যাডজাস্ট_ভ্যালুর চেয়ে কম হতে পারে, যেমন অ্যাডজাস্ট_ভ্যালুর অর্ধেক, যা সূচক থেকে 2% হোল্ডিং মানের সমতুল্য।

  • Adjust_value: চুক্তির মান (USDT মূল্যায়ন) বিচ্যুতি মান সামঞ্জস্য করে। যখন সূচক * Trade_value-current position> Adjust_value থেকে বিচ্যুতি পায়, অর্থাৎ লক্ষ্য অবস্থান এবং বর্তমান অবস্থানের মধ্যে পার্থক্য এই মান অতিক্রম করে, তখন ট্রেডিং শুরু হবে। খুব বড় সমন্বয় ধীর, খুব ছোট লেনদেন ঘন এবং 10 এর কম হতে পারে না, অন্যথায় সর্বনিম্ন লেনদেনটি অর্জন করা হবে না, এটি Trade_value এর 40% এর বেশি সেট করার পরামর্শ দেওয়া হয়।

অবশ্যই, Trade_value আমাদের আয় এবং ঝুঁকিগুলির সাথে সরাসরি সম্পর্কিত। যদি Trade_value পরিবর্তন করা না হয়, তবে এটি এখন পর্যন্ত লাভজনক হওয়া উচিত।

যেহেতু আলফা এই সময় উচ্চতর ফ্রিকোয়েন্সি তথ্য আছে, এটা স্পষ্টভাবে প্রতি 1 মিনিট এটি আপডেট করার জন্য আরো যুক্তিসঙ্গত। স্বাভাবিকভাবেই, এটি মূল এক চেয়ে ছোট। নির্দিষ্ট সংখ্যা ব্যাকটেস্ট দ্বারা নির্ধারিত করা যেতে পারে।

Adjust_value সর্বদা Trade_value এর 40% এর বেশি সুপারিশ করেছে। মূল 1h K লাইন সেটিংয়ের সামান্য প্রভাব রয়েছে। কিছু লোক এটি খুব কম সামঞ্জস্য করতে চায়, যাতে এটি লক্ষ্য অবস্থানের কাছাকাছি হতে পারে। এখানে আমরা বিশ্লেষণ করব কেন এটি করা উচিত নয়।

প্রথমে ফি পরিচালনার সমস্যাটি বিশ্লেষণ করুন

এটা দেখা যায় যে 0.00075 এর ডিফল্ট হারের অধীনে, হ্যান্ডলিং ফি 293 এবং মুনাফা 270 হয়, যা একটি খুব উচ্চ অনুপাত। আমরা হ্যান্ডলিং ফি 0 এবং অ্যাডজাস্ট_ভ্যালু 10 এ সেট করি যা ঘটে তা দেখতে।

stragey_2a.account['USDT']
{'fee': 293.85972778530453,
 'leverage': 0.45999999999999996,
 'margin': 236.23559736312995,
 'realised_profit': 281.77464608744435,
 'total': 10271.146238,
 'unrealised_profit': -10.628408369648495}
Alpha = 0.001
#price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.rolling(20).mean() # Ordinary moving average
price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() # Here is consistent with the strategy, using EMA
trade_symbols = list(set(symbols))
price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0,log=False)
trade_value = 300
for row in price_usdt.iloc[-7500:].iterrows():
    e.Update(row[0], row[1])
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm2.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,1)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        if aim_value - now_value > 10:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < 10:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2d = e
(stragey_2d.df['total']/e.initial_balance).plot(figsize=(17,6),grid = True);

img

ফলস্বরূপ একটি সোজা লাইন উপরে, বিএনবি শুধুমাত্র সামান্য twists এবং twists এনেছে, নিম্ন Adjust_value প্রতিটি ওঠানামা ধরা। যদি কোন হ্যান্ডলিং ফি নেই, মুনাফা চমৎকার হবে।

যদি অ্যাডজাস্টমেন্ট_ভ্যালু ছোট হয় যদি একটি ছোট পরিমাণে হ্যান্ডলিং ফি থাকে?

Alpha = 0.001
#price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.rolling(20).mean() # Ordinary moving average
price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() # Here is consistent with the strategy, using EMA
trade_symbols = list(set(symbols))
price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.00075,log=False)
trade_value = 300
for row in price_usdt.iloc[-7500:].iterrows():
    e.Update(row[0], row[1])
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm2.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,1)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        if aim_value - now_value > 10:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < 10:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2e = e
(stragey_2e.df['total']/e.initial_balance).plot(figsize=(17,6),grid = True);

img

এটি সহজেই বোঝা যায়, যদি আপনি এটি সম্পর্কে চিন্তা করেন, একটি ছোট স্প্রেডের মধ্যে ঘন ঘন সমন্বয়গুলি কেবল হ্যান্ডলিং ফি হারাবে।

সামগ্রিকভাবে, ফি স্তর যত কম, Adjust_value যত কম সেট করা যায়, লেনদেন তত বেশি ঘন ঘন এবং মুনাফা তত বেশি।

আলফা সেটিংসে সমস্যা

যেহেতু একটি মিনিট লাইন আছে, বেঞ্চমার্ক মূল্য প্রতি মিনিটে একবার আপডেট করা হবে, এখানে আমরা কেবল আলফা আকার নির্ধারণ করার জন্য ব্যাকটেস্ট করি। বর্তমান প্রস্তাবিত আলফা সেটিং 0.001।

for Alpha in [0.0001, 0.0003, 0.0006, 0.001, 0.0015, 0.002, 0.004, 0.01, 0.02]:
#price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.rolling(20).mean() # Ordinary moving average
    price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() #Here is consistent with the strategy, using EMA
    trade_symbols = list(set(symbols))
    price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
    e = Exchange(trade_symbols,initial_balance=10000,commission=0.00075,log=False)
    trade_value = 300
    for row in price_usdt.iloc[-7500:].iterrows():
        e.Update(row[0], row[1])
        for symbol in trade_symbols:
            price = row[1][symbol]
            if np.isnan(price):
                continue
            diff = price_usdt_btc_norm2.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
            aim_value = -trade_value*round(diff/0.01,1)
            now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
            if aim_value - now_value > 0.5*trade_value:
                e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
            if aim_value - now_value < -0.5*trade_value:
                e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
    print(Alpha, e.account['USDT']['unrealised_profit']+e.account['USDT']['realised_profit'])
0.0001 -77.80281760941007
0.0003 179.38803796199724
0.0006 218.12579924541367
0.001 271.1462377177959
0.0015 250.0014065973528
0.002 207.38692166891275
0.004 129.08021828803027
0.01 65.12410041648158
0.02 58.62356792410955

গত দুই মাসের মিনিটের রেখার ব্যাকটেস্টের ফলাফল

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

আরেকটি বিষয়, আমরা সবসময় একটি স্থির trade_value ব্যবহার করা হয়েছে, যা পরবর্তী সময়ের তহবিল ব্যবহার অপর্যাপ্ত করে তোলে, এবং প্রকৃত রিটার্ন হার এখনও অনেক বৃদ্ধি করতে পারেন।

আমরা দুই মাসের ব্যাকটেস্টের সময়কালে কোথায় আছি?

img

Alpha = 0.001
#price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.rolling(20).mean() # Ordinary moving average
price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() # Here is consistent with the strategy, using EMA
trade_symbols = list(set(symbols))
price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.00075,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm2.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,1)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        if aim_value - now_value > 0.5*trade_value:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -0.5*trade_value:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2f = e
(stragey_2f.df['total']/stragey_2e.initial_balance).plot(figsize=(17,6),grid = True);

img

(stragey_2f.df['leverage']/stragey_2e.initial_balance).plot(figsize=(17,6),grid = True);

img


সম্পর্কিত

আরো