بائننس فیوچر ملٹی کرنسی ہیجنگ حکمت عملی پر تحقیق حصہ 2

مصنف:نیکی, تخلیق: 2020-05-09 16:03:01, تازہ کاری: 2023-11-04 19:49:47

img

اصل تحقیقی رپورٹ کا پتہ:https://www.fmz.com/digest-topic/5584آپ اسے پہلے پڑھ سکتے ہیں ، اس مضمون میں ڈپلیکیٹ مواد نہیں ہوگا۔ اس مضمون میں دوسری حکمت عملی کے اصلاح کے عمل کو اجاگر کیا جائے گا۔ اصلاح کے بعد ، دوسری حکمت عملی میں واضح طور پر بہتری آئی ہے ، اس مضمون کے مطابق حکمت عملی کو اپ گریڈ کرنے کی سفارش کی جاتی ہے۔ بیک ٹیسٹ انجن نے ہینڈلنگ فیس کے اعدادوشمار شامل کیے۔

# 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 = ['ETH', 'BCH', 'XRP', 'EOS', 'LTC', 'TRX', 'ETC', 'LINK', 'XLM', 'ADA', 'XMR', 'DASH', 'ZEC', 'XTZ', 'BNB', 'ATOM', 'ONT', 'IOTA', 'BAT', 'VET', 'NEO', 'QTUM', 'IOST']
price_usdt = pd.read_csv('https://www.fmz.com/upload/asset/20227de6c1d10cb9dd1.csv ', index_col = 0)
price_usdt.index = pd.to_datetime(price_usdt.index)
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']
            if self.date.hour in [0,8,16]:
                pass
                self.account['USDT']['realised_profit'] += -self.account[symbol]['amount']*close_price[symbol]*0.01/100
        
        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']]

کرنسی کی قسم کے انتخاب کے بعد، اصل حکمت عملی کی کارکردگی نے اچھی کارکردگی کا مظاہرہ کیا، لیکن اب بھی بہت سے ہولڈنگ پوزیشنز ہیں، عام طور پر تقریبا 4 گنا

اصول:

  • مارکیٹ کی قیمتوں کا تعین اور اکاؤنٹ کی پوزیشنوں کو اپ ڈیٹ کریں ، ابتدائی قیمت کو پہلے رن میں ریکارڈ کیا جائے گا (نئی شامل کردہ کرنسیوں کا حساب شامل ہونے کے وقت کے مطابق کیا جاتا ہے)
  • انڈیکس کو اپ ڈیٹ کریں، انڈیکس altcoin-bitcoin قیمت انڈیکس ہے = اوسط (مجموعہ ((altcoin قیمت / bitcoin قیمت) / (altcoin ابتدائی قیمت / bitcoin ابتدائی قیمت))
  • انحراف کے اشاریہ کے مطابق طویل اور مختصر آپریشن کا فیصلہ کرنا ، اور انحراف کے سائز کے مطابق پوزیشن کا اندازہ کرنا
  • احکامات کی جگہ، حکم کی مقدار آئس برگ کمیشن کی حکمت عملی کی طرف سے مقرر کیا جاتا ہے اور لین دین کے مطابق عملدرآمد کیا جاتا ہے تازہ ترین قابل عمل قیمت
  • دوبارہ لوپ
trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH'])) # Remaining currencies
price_usdt_btc_norm_mean = price_usdt_btc_norm[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm.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'])
        empty_value += now_value
        if aim_value - now_value > 20:
            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 < -20:
            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

stragey_2b.df['leverage'].plot(figsize=(18,6),grid = True); # leverage

img

pd.DataFrame(e.account).T.apply(lambda x:round(x,3)) # holding position

img

کیوں بہتر بنائیں

اصل سب سے بڑا مسئلہ تازہ ترین قیمت اور حکمت عملی کے ذریعہ شروع کردہ ابتدائی قیمت کے درمیان موازنہ ہے۔ وقت گزرنے کے ساتھ ساتھ ، یہ زیادہ سے زیادہ انحراف ہوجائے گا۔ ہم ان کرنسیوں میں بہت ساری پوزیشنیں جمع کریں گے۔ فلٹرنگ کرنسیوں کے ساتھ سب سے بڑا مسئلہ یہ ہے کہ ہمارے ماضی کے تجربے کی بنیاد پر مستقبل میں ہمارے پاس ابھی بھی منفرد کرنسیاں ہوسکتی ہیں۔ مندرجہ ذیل غیر فلٹرنگ موڈ کی کارکردگی ہے۔ در حقیقت ، جب trade_value = 300 ، حکمت عملی چلانے کے وسط مرحلے میں ، اس نے پہلے ہی سب کچھ کھو دیا ہے۔ یہاں تک کہ اگر ایسا نہیں ہے تو ، LINK اور XTZ بھی 10000USDT سے اوپر کی پوزیشن رکھتے ہیں ، جو بہت بڑا ہے۔ لہذا ، ہمیں اس مسئلے کو بیک ٹیسٹ میں حل کرنا ہوگا اور تمام کرنسیوں کا ٹیسٹ پاس کرنا ہوگا۔

trade_symbols = list(set(symbols)) # Remaining currencies
price_usdt_btc_norm_mean = price_usdt_btc_norm[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm.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'])
        empty_value += now_value
        if aim_value - now_value > 20:
            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 < -20:
            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']/stragey_2c.initial_balance).plot(figsize=(17,6),grid = True);

img

pd.DataFrame(stragey_2c.account).T.apply(lambda x:round(x,3)) # Last holding position

img

((price_usdt_btc_norm.iloc[-1:] - price_usdt_btc_norm_mean[-1]).T) # Each currency deviates from the initial situation

img

چونکہ اس مسئلے کی وجہ ابتدائی قیمت سے موازنہ کرنا ہے ، لہذا یہ زیادہ سے زیادہ متعصب ہوسکتا ہے۔ ہم اس کا موازنہ ماضی کی مدت کے چلتے ہوئے اوسط سے کرسکتے ہیں ، پوری کرنسی کو بیک ٹیسٹ کرسکتے ہیں اور نیچے دیئے گئے نتائج دیکھ سکتے ہیں۔

Alpha = 0.05
#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))#All currencies
price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    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'])
        empty_value += now_value
        if aim_value - now_value > 20:
            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 < -20:
            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
#print(N,stragey_2d.df['total'][-1],pd.DataFrame(stragey_2d.account).T.apply(lambda x:round(x,3))['value'].sum())

حکمت عملی کی کارکردگی نے ہماری توقعات کو مکمل طور پر پورا کیا ہے ، اور واپسی تقریبا the ایک جیسی ہے۔ تمام کرنسیوں کی اصل کرنسی میں اکاؤنٹ کی پوزیشنوں کو پھٹنے کی صورتحال بھی آسانی سے منتقل ہوگئی ہے ، اور تقریبا no کوئی ریٹریسیشن نہیں ہے۔ ایک ہی افتتاحی پوزیشن کا سائز ، تقریبا all تمام بیعانہ 1 گنا سے کم ہے ، 12 مارچ 2020 کو قیمت گر گئی انتہائی صورت ، یہ اب بھی 4 گنا سے زیادہ نہیں ہے ، جس کا مطلب ہے کہ ہم trade_value میں اضافہ کرسکتے ہیں ، اور اسی بیعانہ کے تحت ، منافع کو دوگنا کرسکتے ہیں۔ حتمی ہولڈنگ پوزیشن صرف BCH ہے جو 1000USDT سے زیادہ ہے ، جو بہت اچھی ہے۔

پوزیشن کو کیوں کم کیا جائے گا؟ تصور کریں کہ الٹکوئن انڈیکس میں شامل ہونے میں کوئی تبدیلی نہیں آئی ہے ، ایک سکے میں 100٪ اضافہ ہوا ہے ، اور یہ طویل عرصے تک برقرار رہے گا۔ اصل حکمت عملی 300 * 100 = 30000USDT کی مختصر پوزیشنوں کو طویل عرصے تک برقرار رکھے گی ، اور نئی حکمت عملی آخر کار بینچ مارک قیمت کو ٹریک کرے گی۔ آخری قیمت پر ، آپ آخر میں کوئی پوزیشن نہیں رکھیں گے۔

(stragey_2d.df['total']/stragey_2d.initial_balance).plot(figsize=(17,6),grid = True);
#(stragey_2c.df['total']/stragey_2c.initial_balance).plot(figsize=(17,6),grid = True);

img

stragey_2d.df['leverage'].plot(figsize=(18,6),grid = True);
stragey_2b.df['leverage'].plot(figsize=(18,6),grid = True); # Screen currency strategy leverage

img

pd.DataFrame(stragey_2d.account).T.apply(lambda x:round(x,3))

img

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

#price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.rolling(50).mean()
price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=0.05).mean()
trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH'])) # Remaining currencies
price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    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'])
        empty_value += now_value
        if aim_value - now_value > 20:
            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 < -20:
            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_2d.df['total']/stragey_2d.initial_balance).plot(figsize=(17,6),grid = True);
(stragey_2e.df['total']/stragey_2e.initial_balance).plot(figsize=(17,6),grid = True);

img

stragey_2e.df['leverage'].plot(figsize=(18,6),grid = True);

img

pd.DataFrame(stragey_2e.account).T.apply(lambda x:round(x,3))

img

پیرامیٹر کی اصلاح

ایکسپونینشل موونگ ایوریج کے الفا پیرامیٹر کی ترتیب جتنی زیادہ ہوگی ، قیمت کی نگرانی کی قیمت اتنی ہی حساس ہوگی ، جتنے کم لین دین ہوں گے ، حتمی ہولڈنگ پوزیشن اتنی ہی کم ہوگی۔ جب لیوریج کو کم کیا جائے گا تو واپسی بھی کم ہوجائے گی۔ زیادہ سے زیادہ ریٹریکشن کو کم کیا جائے گا ، اس سے لین دین کا حجم بڑھ سکتا ہے۔ بیک ٹیسٹ کے نتائج کی بنیاد پر مخصوص توازن کی کارروائیوں کی ضرورت ہے۔

چونکہ بیک ٹسٹ ایک 1h K لائن ہے ، لہذا اسے صرف ایک گھنٹے میں ایک بار اپ ڈیٹ کیا جاسکتا ہے ، حقیقی مارکیٹ کو تیزی سے اپ ڈیٹ کیا جاسکتا ہے ، اور مخصوص ترتیبات کو جامع طور پر وزن کرنا ضروری ہے۔

یہ اصلاح کا نتیجہ ہے:

for Alpha in [i/100 for i in range(1,30)]:
    #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))# All currencies
    price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1)
    e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False)
    trade_value = 300
    for row in price_usdt.iloc[:].iterrows():
        e.Update(row[0], row[1])
        empty_value = 0
        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'])
            empty_value += now_value
            if aim_value - now_value > 20:
                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 < -20:
                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
    # These are the final net value, the initial maximum backtest, the final position size, and the handling fee
    print(Alpha, round(stragey_2d.account['USDT']['total'],1), round(1-stragey_2d.df['total'].min()/stragey_2d.initial_balance,2),round(pd.DataFrame(stragey_2d.account).T['value'].sum(),1),round(stragey_2d.account['USDT']['fee']))
0.01 21116.2 0.14 15480.0 2178.0
0.02 20555.6 0.07 12420.0 2184.0
0.03 20279.4 0.06 9990.0 2176.0
0.04 20021.5 0.04 8580.0 2168.0
0.05 19719.1 0.03 7740.0 2157.0
0.06 19616.6 0.03 7050.0 2145.0
0.07 19344.0 0.02 6450.0 2133.0
0.08 19174.0 0.02 6120.0 2117.0
0.09 18988.4 0.01 5670.0 2104.0
0.1 18734.8 0.01 5520.0 2090.0
0.11 18532.7 0.01 5310.0 2078.0
0.12 18354.2 0.01 5130.0 2061.0
0.13 18171.7 0.01 4830.0 2047.0
0.14 17960.4 0.01 4770.0 2032.0
0.15 17779.8 0.01 4531.3 2017.0
0.16 17570.1 0.01 4441.3 2003.0
0.17 17370.2 0.01 4410.0 1985.0
0.18 17203.7 0.0 4320.0 1971.0
0.19 17016.9 0.0 4290.0 1955.0
0.2 16810.6 0.0 4230.6 1937.0
0.21 16664.1 0.0 4051.3 1921.0
0.22 16488.2 0.0 3930.6 1902.0
0.23 16378.9 0.0 3900.6 1887.0
0.24 16190.8 0.0 3840.0 1873.0
0.25 15993.0 0.0 3781.3 1855.0
0.26 15828.5 0.0 3661.3 1835.0
0.27 15673.0 0.0 3571.3 1816.0
0.28 15559.5 0.0 3511.3 1800.0
0.29 15416.4 0.0 3481.3 1780.0

متعلقہ

مزید