Strategi lindung nilai multi-mata wang niaga hadapan Binance
Tiga laporan penyelidikan mengenai strategi lindung nilai pelbagai mata wang Binance telah diterbitkan, inilah yang keempat. hubungan tiga artikel pertama, anda mesti membacanya lagi jika anda belum membacanya, anda boleh memahami idea pembentukan strategi, penetapan parameter tertentu dan logik strategi.
Penyelidikan mengenai Strategi Hedging Multi-mata wang Binance Futures Bahagian 1:https://www.fmz.com/digest-topic/5584
Penyelidikan mengenai Strategi Hedging Multi-mata wang Binance Futures Bahagian 2:https://www.fmz.com/digest-topic/5588
Penyelidikan mengenai Strategi Hedging Multi-mata wang Binance Futures Bahagian 3:https://www.fmz.com/digest-topic/5605
Artikel ini adalah untuk mengkaji semula keadaan pasaran sebenar minggu lalu, dan meringkaskan keuntungan dan kerugian.
# 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']
Data dari 21 Februari hingga 15 April pukul dua petang, jumlahnya 77160 * 24, yang sangat mengurangkan kelajuan backtest kami, enjin backtest tidak cukup cekap, anda boleh mengoptimumkannya sendiri.
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']]
Kod strategi telah dikeluarkan di kumpulan WeChat pada 10 April. Pada mulanya, sekumpulan orang menjalankan strategi 2 ((pendek over-rise dan long over-fall). Pada tiga hari pertama, pulangan sangat baik, dan retracement sangat rendah. pada hari-hari berikutnya, beberapa peniaga memperbesar leverage, ada yang bahkan menggunakan keseluruhan jumlah dana mereka untuk beroperasi, dan keuntungan mencapai 10% dalam satu hari. Strategy Square juga mengeluarkan banyak strategi pasaran sebenar, ramai orang mula tidak berpuas hati dengan parameter yang disyorkan konservatif, dan telah memperkuat jumlah transaksi. Selepas 13 April, kerana trend bebas BNB
let's take a look at the full currency backtest of Strategy 2. Di sini, kerana ia adalah kemas kini tahap minit, parameter Alpha perlu diselaraskan. Dari sudut pasaran sebenar, trend lengkung adalah konsisten, menunjukkan bahawa backtest kami boleh digunakan sebagai rujukan yang kuat. Nilai bersih telah mencapai puncak nilai bersih dari 4.13 dan seterusnya dan telah berada dalam fasa retracement dan sisi.
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);
Strategi 1, strategi altcoin pendek mencapai pulangan positif
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);
Strategi 2 membeli keuntungan yang terlalu tinggi dan menjual keuntungan yang lebih tinggi analisis
Mencetak maklumat akaun akhir menunjukkan bahawa kebanyakan mata wang telah membawa keuntungan, dan BNB telah mengalami kerugian yang paling banyak.
pd.DataFrame(stragey_2a.account).T.apply(lambda x:round(x,3)).sort_values(by='realised_profit')
# 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);
Jika BNB dan ATOM dikeluarkan, hasilnya lebih baik, tetapi strategi masih dalam peringkat retracement baru-baru ini.
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);
Dalam dua hari yang lalu, ia telah menjadi popular untuk menjalankan strategi mata wang arus perdana. Mari kita backtest strategi ini. Oleh kerana penurunan dalam pelbagai mata wang, trade_value telah meningkat dengan tepat sebanyak 4 kali untuk perbandingan, dan hasilnya berjalan dengan baik, terutamanya kerana retracement baru-baru ini kecil.
Perlu diperhatikan bahawa hanya mata wang arus perdana tidak sebaik mata wang penuh dalam masa yang lebih lama backtest, dan terdapat lebih banyak retracements.
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);
Oleh kerana beberapa laporan pertama menggunakan garis k tahap jam, dan parameter sebenar sangat berbeza dengan situasi pasaran sebenar, sekarang dengan minit tahap k garis, anda boleh melihat bagaimana untuk menetapkan beberapa parameter.
Alpha = 0.03 Parameter Alpha purata bergerak eksponensial. Semakin besar tetapan, semakin sensitif penjejakan harga penanda aras dan lebih sedikit urus niaga. Kedudukan pegangan akhir juga akan lebih rendah, yang mengurangkan leverage, tetapi juga akan mengurangkan pulangan dan retracements maksimum.
Update_base_price_time_interval = 30 * 60 Seberapa kerap untuk mengemas kini harga asas, dalam saat, berkaitan dengan parameter Alpha, yang lebih kecil tetapan Alpha, yang lebih kecil selang boleh ditetapkan
Trade_value: Setiap 1% daripada harga altcoin (didenominasi BTC) menyimpang dari nilai pegangan indeks, yang perlu ditentukan mengikut jumlah dana yang dilaburkan dan keutamaan risiko. Adalah disyorkan untuk menetapkan 3-10% daripada jumlah dana. Anda boleh melihat saiz lever melalui backtest persekitaran penyelidikan. Trade_value boleh kurang daripada Adjust_value, seperti separuh dari Adjust_value, yang bersamaan dengan nilai pegangan 2% dari indeks.
Adjust_value: Nilai kontrak (nilai USDT) menyesuaikan nilai penyimpangan. Apabila indeks menyimpang dari * Trade_value-posisi semasa> Adjust_value, iaitu, perbezaan antara kedudukan sasaran dan kedudukan semasa melebihi nilai ini, perdagangan akan dimulakan. Penyesuaian yang terlalu besar lambat, urus niaga yang terlalu kecil kerap dan tidak boleh kurang daripada 10, jika tidak urus niaga minimum tidak akan dicapai, disyorkan untuk menetapkannya lebih daripada 40% dari Trade_value.
Tidak perlu dikatakan, Trade_value adalah langsung berkaitan dengan keuntungan dan risiko kita. Jika Trade_value tidak berubah, ia harus menguntungkan setakat ini.
Oleh kerana Alpha mempunyai data frekuensi yang lebih tinggi kali ini, jelas lebih munasabah untuk mengemas kini setiap 1 minit.
Adjust_value selalu disyorkan lebih daripada 40% dari Trade_value. Tetapan baris 1h K asal mempunyai sedikit kesan. Sesetengah orang mahu menyesuaikannya sangat rendah, supaya ia boleh lebih dekat dengan kedudukan sasaran. Di sini kita akan menganalisis mengapa ia tidak boleh dilakukan.
Mula-mula menganalisis masalah pengurusan yuran
Ia boleh dilihat bahawa di bawah kadar lalai 0.00075, yuran pengendalian adalah 293 dan keuntungan adalah 270, yang merupakan perkadaran yang sangat tinggi.
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);
Hasilnya adalah garis lurus ke atas, BNB hanya membawa sedikit pusingan dan pusingan, nilai Adjust_value yang lebih rendah menangkap setiap turun naik.
Bagaimana jika adjustment_value kecil jika terdapat sejumlah kecil yuran pengendalian?
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);
Hasilnya, ia juga keluar dari lengkung lurus ke bawah. ia mudah difahami jika anda berfikir mengenainya, pelarasan kerap dalam spread kecil hanya akan kehilangan yuran pengendalian.
Secara keseluruhan, semakin rendah tahap yuran, semakin kecil nilai Adjust_value boleh ditetapkan, lebih kerap transaksi, dan lebih tinggi keuntungan.
Masalah dengan tetapan Alpha
Oleh kerana terdapat garis minit, harga penanda aras akan dikemas kini sekali setiap minit, di sini kita hanya melakukan backtest untuk menentukan saiz alpha.
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
Akhirnya, lihatlah hasil backtest jangka panjang. Hanya sekarang, satu demi satu meningkat, dan kekayaan bersih hari ini berada pada tahap terendah baru. Mari kita berikan keyakinan berikut. Kerana kekerapan garis minit lebih tinggi, ia akan membuka dan menutup kedudukan dalam masa sejam, jadi keuntungan akan jauh lebih tinggi.
Satu lagi titik, kita sentiasa telah menggunakan trade_value tetap, yang membuat penggunaan dana dalam tempoh kemudian tidak mencukupi, dan kadar pulangan sebenar masih boleh meningkat banyak.
Di mana kita dalam tempoh uji balik dua bulan?
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);
(stragey_2f.df['leverage']/stragey_2e.initial_balance).plot(figsize=(17,6),grid = True);