# 最近(2022.08.13)負けてるクロスセクションbotについて
## ロジック概要
まず、振り返りとしてこのbotのロジックは
* UTC16時時点において、bybitのUSDT先物全銘柄のLS比および現先乖離を取得
* LSが低い銘柄順に1から順位付け
* 現物高、先物安の銘柄順に1から順位付け
* 二つの順位の合計が低い上位10銘柄をロング、高い下位10銘柄をショート
* 先物÷現物<0.9941の銘柄は取引除外(バックテスト上あまり影響はない。でも、現物が異常に高い、つまり現物買い需要から生じた乖離ではなく、ヘッジショートが大幅にかかっている売り圧の大きい銘柄のロングを避けるのが狙い)
## バックテスト結果
### バックテストプロット
___

___
### 直近の取引詳細
```
date symbol ls_rank dev_rank sum_rank pr_ch
5160 2022-08-05 16:00:00 BNXUSDT 7.0 4.0 1.0 -0.020055
5161 2022-08-05 16:00:00 CVXUSDT 16.5 6.0 2.0 0.007141
5162 2022-08-05 16:00:00 AAVEUSDT 19.0 13.0 3.0 0.006604
5163 2022-08-05 16:00:00 LPTUSDT 32.0 1.0 4.0 0.002819
5164 2022-08-05 16:00:00 AGLDUSDT 8.0 34.0 5.0 0.025416
5165 2022-08-05 16:00:00 NEARUSDT 6.0 37.0 6.0 -0.016958
5166 2022-08-05 16:00:00 BNBUSDT 12.0 32.0 7.0 0.008192
5167 2022-08-05 16:00:00 OPUSDT 5.0 41.0 8.0 0.048901
5168 2022-08-05 16:00:00 BALUSDT 43.0 8.0 9.0 0.017955
5169 2022-08-05 16:00:00 APEUSDT 15.0 38.0 10.0 0.003329
5170 2022-08-05 16:00:00 JASMYUSDT 144.0 105.0 145.0 -0.031400
5171 2022-08-05 16:00:00 AKROUSDT 119.0 132.0 146.0 -0.014150
5172 2022-08-05 16:00:00 BELUSDT 115.0 141.0 147.0 -0.031622
5173 2022-08-05 16:00:00 ZILUSDT 121.0 136.0 148.5 -0.066508
5174 2022-08-05 16:00:00 CELOUSDT 114.0 143.0 148.5 -0.021961
5175 2022-08-05 16:00:00 LINAUSDT 153.0 105.0 150.0 -0.008679
5176 2022-08-05 16:00:00 SCRTUSDT 109.0 154.0 151.0 -0.044565
5177 2022-08-05 16:00:00 AUDIOUSDT 128.0 146.0 152.0 -0.026435
5178 2022-08-05 16:00:00 KDAUSDT 135.5 144.0 153.0 -0.067599
5179 2022-08-05 16:00:00 HBARUSDT 154.0 145.0 154.0 -0.048602
date symbol ls_rank dev_rank sum_rank pr_ch
5180 2022-08-06 16:00:00 FLOWUSDT 3.0 2.0 1.0 0.002446
5181 2022-08-06 16:00:00 OPUSDT 5.0 18.0 2.0 -0.037818
5182 2022-08-06 16:00:00 CVXUSDT 22.0 4.0 3.0 -0.023983
5183 2022-08-06 16:00:00 C98USDT 29.0 10.0 4.0 -0.014166
5184 2022-08-06 16:00:00 BNXUSDT 16.0 25.0 5.0 -0.006152
5185 2022-08-06 16:00:00 APEUSDT 9.0 35.0 6.0 -0.030313
5186 2022-08-06 16:00:00 AAVEUSDT 17.0 29.0 7.0 0.003563
5187 2022-08-06 16:00:00 VETUSDT 28.0 19.0 8.0 -0.010909
5188 2022-08-06 16:00:00 BNBUSDT 8.0 43.0 9.0 0.018394
5189 2022-08-06 16:00:00 BITUSDT 45.5 6.0 10.0 -0.007988
5190 2022-08-06 16:00:00 THETAUSDT 127.0 141.0 150.0 -0.048384
5191 2022-08-06 16:00:00 OGNUSDT 149.0 124.0 151.0 0.010505
5192 2022-08-06 16:00:00 SKLUSDT 135.5 139.0 152.0 0.010712
5193 2022-08-06 16:00:00 AKROUSDT 129.5 149.0 153.0 0.004992
5194 2022-08-06 16:00:00 KDAUSDT 151.0 128.0 154.0 0.019767
5195 2022-08-06 16:00:00 WAVESUSDT 144.0 142.0 155.0 0.026019
5196 2022-08-06 16:00:00 HBARUSDT 157.0 132.0 156.0 -0.001400
5197 2022-08-06 16:00:00 RSRUSDT 139.5 158.0 157.0 0.019290
5198 2022-08-06 16:00:00 ALGOUSDT 155.0 151.0 158.0 -0.016981
5199 2022-08-06 16:00:00 BELUSDT 159.0 155.0 159.0 0.013832
date symbol ls_rank dev_rank sum_rank pr_ch
5200 2022-08-07 16:00:00 CREAMUSDT 3.0 5.0 1.0 -0.038845
5201 2022-08-07 16:00:00 LDOUSDT 2.0 21.0 2.0 0.005529
5202 2022-08-07 16:00:00 BNBUSDT 6.0 30.0 3.0 0.007606
5203 2022-08-07 16:00:00 CVXUSDT 27.0 12.0 4.0 0.063582
5204 2022-08-07 16:00:00 TRXUSDT 11.0 32.0 5.0 0.002464
5205 2022-08-07 16:00:00 CVCUSDT 43.0 3.0 6.5 0.001686
5206 2022-08-07 16:00:00 ARUSDT 21.0 25.0 6.5 0.031522
5207 2022-08-07 16:00:00 ROSEUSDT 15.0 36.0 8.0 0.142997
5208 2022-08-07 16:00:00 AVAXUSDT 14.0 38.0 9.0 0.036312
5209 2022-08-07 16:00:00 XCNUSDT 53.0 2.0 10.0 0.022608
5210 2022-08-07 16:00:00 HOTUSDT 121.5 139.0 141.0 -0.007454
5211 2022-08-07 16:00:00 CHRUSDT 144.0 117.0 142.0 -0.051167
5212 2022-08-07 16:00:00 AKROUSDT 116.5 146.0 143.0 -0.005104
5213 2022-08-07 16:00:00 MASKUSDT 127.0 137.0 144.0 0.001310
5214 2022-08-07 16:00:00 REEFUSDT 140.0 125.0 145.0 0.010055
5215 2022-08-07 16:00:00 OCEANUSDT 135.0 132.0 146.0 -0.052405
5216 2022-08-07 16:00:00 BELUSDT 148.0 126.0 147.0 -0.018357
5217 2022-08-07 16:00:00 LINAUSDT 147.0 131.0 148.0 -0.004137
5218 2022-08-07 16:00:00 RSRUSDT 136.0 150.0 149.0 -0.107034
5219 2022-08-07 16:00:00 CEEKUSDT 146.0 147.0 150.0 -0.020863
date symbol ls_rank dev_rank sum_rank pr_ch
5220 2022-08-08 16:00:00 LDOUSDT 10.0 3.0 1.0 -0.125059
5221 2022-08-08 16:00:00 TRXUSDT 14.0 20.0 2.0 -0.001685
5222 2022-08-08 16:00:00 ENSUSDT 16.0 19.0 3.0 -0.065281
5223 2022-08-08 16:00:00 BSVUSDT 29.0 9.0 4.0 -0.058543
5224 2022-08-08 16:00:00 CVCUSDT 36.5 2.0 5.0 -0.059862
5225 2022-08-08 16:00:00 SNXUSDT 31.0 8.0 6.0 -0.076742
5226 2022-08-08 16:00:00 ROSEUSDT 11.0 30.0 7.0 -0.039065
5227 2022-08-08 16:00:00 LUNA2USDT 18.0 29.0 8.0 -0.079230
5228 2022-08-08 16:00:00 OPUSDT 8.0 40.0 9.0 -0.134543
5229 2022-08-08 16:00:00 BNBUSDT 4.0 46.0 10.0 -0.029870
5230 2022-08-08 16:00:00 DASHUSDT 146.0 111.0 143.5 0.027145
5231 2022-08-08 16:00:00 ASTRUSDT 143.0 122.0 145.5 0.095622
5232 2022-08-08 16:00:00 1000BTTUSDT 136.0 129.0 145.5 -0.016536
5233 2022-08-08 16:00:00 ANKRUSDT 131.5 134.0 147.0 0.060162
5234 2022-08-08 16:00:00 DOGEUSDT 134.0 138.0 148.0 0.025589
5235 2022-08-08 16:00:00 AUDIOUSDT 133.0 148.0 149.0 0.007786
5236 2022-08-08 16:00:00 DUSKUSDT 145.0 145.0 150.0 0.029608
5237 2022-08-08 16:00:00 JASMYUSDT 147.0 153.0 151.5 0.065267
5238 2022-08-08 16:00:00 CEEKUSDT 149.0 151.0 151.5 0.045083
5239 2022-08-08 16:00:00 OGNUSDT 151.0 150.0 153.0 0.059886
date symbol ls_rank dev_rank sum_rank pr_ch
5240 2022-08-09 16:00:00 AGLDUSDT 6.0 4.0 1.0 0.055843
5241 2022-08-09 16:00:00 BNXUSDT 4.0 9.0 2.0 0.078822
5242 2022-08-09 16:00:00 BSVUSDT 12.0 18.0 3.0 0.042371
5243 2022-08-09 16:00:00 LPTUSDT 30.0 5.0 4.5 0.065865
5244 2022-08-09 16:00:00 JSTUSDT 22.0 13.0 4.5 0.057518
5245 2022-08-09 16:00:00 COTIUSDT 29.0 10.0 6.0 0.062430
5246 2022-08-09 16:00:00 REQUSDT 25.0 15.0 7.0 0.028056
5247 2022-08-09 16:00:00 FITFIUSDT 7.0 36.0 8.5 0.202348
5248 2022-08-09 16:00:00 SANDUSDT 21.0 22.0 8.5 0.038369
5249 2022-08-09 16:00:00 SNXUSDT 32.0 16.0 10.0 0.062092
5250 2022-08-09 16:00:00 SUSHIUSDT 123.0 102.0 127.0 -0.098264
5251 2022-08-09 16:00:00 C98USDT 98.5 127.0 128.0 -0.039423
5252 2022-08-09 16:00:00 HBARUSDT 136.0 91.0 129.0 -0.061576
5253 2022-08-09 16:00:00 LINAUSDT 129.0 102.0 130.0 -0.044665
5254 2022-08-09 16:00:00 JASMYUSDT 131.0 102.0 131.0 -0.062624
5255 2022-08-09 16:00:00 BICOUSDT 103.0 135.0 132.0 -0.049400
5256 2022-08-09 16:00:00 STXUSDT 105.5 133.0 133.0 -0.030936
5257 2022-08-09 16:00:00 DUSKUSDT 120.0 126.0 134.0 -0.035862
5258 2022-08-09 16:00:00 ASTRUSDT 128.0 119.0 135.0 -0.063102
5259 2022-08-09 16:00:00 CEEKUSDT 134.0 120.0 136.0 -0.017504
```
## LSと乖離で分解
原因を探るために、LSの順位だけ、現先乖離の順位だけで試しにバックテスト
### 乖離だけ(先物÷現物<0.9941銘柄除外)

### 乖離だけ(先物÷現物<0.9941銘柄込み)

### LS比だけ(先物÷現物<0.9941銘柄除外)

### LS比だけ(先物÷現物<0.9941銘柄込み)

## LSのエッジが消えかけてる?
バックテスト上ではLS+乖離の組み合わせよりも乖離単体の方が強くなってしまっている。
LS単体の負けが込んできた6月下旬以前では、組み合わせの方が乖離単体よりもシャープレシオにして0.1以上強かった。
## 全銘柄のLSとバックテストの傾向
バックテストの結果を見ると、負け気味なのはショート側。
直観として「LSが下がりつつある傾向の時にショートをすると、大口の人のロング傾向に逆らっているから負けやすい」というイメージがある。
そこで、Bybit銘柄全体のショートの傾向を見たいから、単なるBTCのLS比とか、OI比重平均LS比
```python
df["oi_usd"] = df["open_interest"]*df["close"]
df["ls_oiw"] = df["oi_usd"]*df["ls"]
ls_mean = df["ls_oiw"].sum()/df["oi_usd"].sum()
```
をバックテスト上にプロットしてみて、傾向を見てみる


---
どちらもBTCの比重が大きいから、グラフに大した形はない。
だからBTCを除いたls_mean、BTCとETHどちらものぞいたls_meanをプロットしてみる。
BTCETH除外

BTCのみ除外

---
## ショートの制限
BTC単体であれ、BTCとETHを除外したls_meanであれ、直近のショートが負けている時にはLSが低い傾向にあることが分かる。
とりあえず、全銘柄LSbotなわけでBTCとETHを除外したls_meanを採用してみて、適当に
> ls_mean < 0.53 のときショートをしない
の条件を加えてバックテストしてみる

まあ当然改善するのは目に見えている。
でもここからは色々なことが考えられて、
* そもそも毎日両建てすることで安定を目指しているのに、片方のポジションをなくす日を設けるのはロジックの根幹から外れてない?
* やるにしても閾値は固定0.53なのか、移動平均で取るのがいいのか?
* ロングは制限しなくてもいいのか?
などなど正直沢山ある。
## コード
```python=
from cProfile import label
from multiprocessing import Condition
from unittest import result
import requests
from datetime import datetime
from datetime import timedelta
import time
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import gc
from sympy import O
from tqdm import tqdm
from scipy import stats
import sys
import seaborn as sns
from datetime import timedelta
from datetime import timezone
from tqdm import tqdm
import pickle
import shap
import mglearn
import glob
from requests import Session
import json
import math
import traceback
import ccxt
class cate_ls:
#Binanceの全銘柄リスト取得
def ftx_binance_common_symbols(self):
while True:
try:
binance_api = requests.get("https://fapi.binance.com/fapi/v1/exchangeInfo").json()
binance_df = pd.DataFrame(binance_api["symbols"])
binance_perpdf = binance_df[(binance_df["contractType"]=="PERPETUAL")&(binance_df["quoteAsset"]=="USDT")]
#print(binance_perpdf["symbol"])
return list(binance_perpdf["symbol"])
except Exception as e:
print(e)
time.sleep(5)
#bybitの銘柄一覧取得
def bybit_symbols(self):
while True:
try:
api = requests.get(f"https://api.bybit.com/v2/public/tickers").json()
df = pd.DataFrame(api["result"])
df["symbol"] = df["symbol"].apply(lambda x: "0" if "21" in x else x)#21期限付き先物の銘柄名を文字列"0"に変える
df["symbol"] = df["symbol"].apply(lambda x: "0" if "22" in x else x)#22期限付き先物の銘柄名を文字列"0"に変える
df["symbol"] = df["symbol"].apply(lambda x: "0" if "23" in x else x)#23期限付き先物の銘柄名を文字列"0"に変える
scli = df["symbol"][df["symbol"] != "0"] #期限付きじゃないやつだけを抽出
#print(scli)
scli_usdt = scli.apply(lambda x: x if "USDT" in x else "0") #文字列USDTが入ってないやつは削除
list_usdt = list(scli_usdt[scli_usdt != "0"] )
print(list_usdt)
print(len(list_usdt))
return list_usdt
except Exception as e:
print(e)
time.sleep(30)
#bybitのapiデータ読んでプレミアム取得、集めてるlsのcsvと結合
def bybit_dev_data(self):
#"""#bybitのプレミアムapi取得###############################################
df_list00 = []
df_list01 = []
self.symbol_list2 = self.bybit_symbols()
#self.symbol_list2 = ["BTCUSDT","ETHUSDT"]
mins_periods = 60 #何分足にするか
today = datetime.now()
max_time_delta = int(pd.to_datetime(today).timestamp())-int(pd.to_datetime("2021-07-01").timestamp())#LSのデータ集め始めた2021-11-01くらいまでapi読み出しを遡る
i_max = int(max_time_delta/mins_periods/60/200)
for i in tqdm(range(0,i_max)):
df_list, df_list2 = [], []
startt = int((pd.to_datetime(today) - i*timedelta(minutes=mins_periods*199)).timestamp())
for sy in self.symbol_list2:
while True:
try:
time.sleep(0.1)#api呼び出し制限対策
future_api = requests.get(f"https://api.bybit.com/public/linear/kline?symbol={sy}&interval={mins_periods}&from={startt}&limit=200").json()
future_df = pd.DataFrame(future_api["result"])
df_list.append(future_df)
future_api2 = requests.get(f"https://api.bybit.com/public/linear/index-price-kline?symbol={sy}&interval={mins_periods}&from={startt}&limit=200").json()
future_df2 = pd.DataFrame(future_api2["result"])
df_list2.append(future_df2)
break
except Exception as e:
print("__", e)
print("retry in 15 sec")
time.sleep(15)
df = pd.concat(df_list)
dff = pd.concat(df_list2)
df_list00.append(df)
df_list01.append(dff)
time.sleep(0.01)
df = pd.concat(df_list00)
dff = pd.concat(df_list01)
df.to_pickle("df.pkl")
dff.to_pickle("dff.pkl")
df = pd.read_pickle("df.pkl")
dff = pd.read_pickle("dff.pkl")
df["date"] = df["open_time"].apply(lambda x: pd.to_datetime(x,unit="s"))
dff["date"] = dff["open_time"].apply(lambda x: pd.to_datetime(x,unit="s"))
df = df.sort_values(["date", "symbol"])
dff = dff.sort_values(["date", "symbol"])
df = df.drop_duplicates(subset=["date", "symbol"], keep="last")
dff = dff.drop_duplicates(subset=["date", "symbol"], keep="last")
df = df.reset_index(drop=True)
dff = dff.reset_index(drop=True)
df0 = pd.merge(df, dff, on=["symbol", "date"], how='outer', suffixes=['', '_s'], indicator=True)
df = df0[["date", "symbol", "open", "high", "low", "close", "close_s"]][df0["_merge"]=="both"].copy()
df.sort_values(["date", "symbol"],inplace=True)
df["open"] = df["open"].apply(float)
df["high"] = df["high"].apply(float)
df["low"] = df["low"].apply(float)
df["close"] = df["close"].apply(float)
df["close_s"] = df["close_s"].apply(float)
df.to_pickle("bybit_dev.pkl")
#"""
#"""#bybitlsのcsvを結合############################################################
csv_list = glob.iglob(f"C:/Database/bybit_ls/*.csv")
df_list = []
for f in tqdm(csv_list):
dff = pd.read_csv(f,index_col=0)
df_list.append(dff)
df_all0 = pd.concat(df_list)
df_all1 = df_all0.reset_index(drop=True)
df_all2 = df_all1.drop_duplicates(subset=["time", "symbol"], keep="last")
df = df_all2.reset_index(drop=True)
df.fillna(0, inplace=True)
df0 = df.rename(columns={"time":"date"})
df0 = df0.sort_values(["date","symbol"])
df0.reset_index(drop=True,inplace=True)
df0["date"] = df0["date"].apply(lambda x: pd.to_datetime(x)-timedelta(hours=9))#UTCに変換しておく
df0.to_pickle("bybit_ls_1h.pkl")
#"""############################################################
#"""#binance_lsのデータ整形
df = pd.read_pickle("C:/Database/binance_integration_data/arranged_data_1h.pkl")
df = df[["symbol","date", "longAccount", "tplsal"]].copy()
df.rename({"longAccount":"ls_bi"},axis=1,inplace=True)
df.to_pickle("binance_1h.pkl")
#"""
#"""LSとプレミアムを結合
df = pd.read_pickle("bybit_dev.pkl")
dff = df[["symbol", "date", "close", "close_s"]].copy()
list1 = []
dff["dev"] = (dff["close_s"]/dff["close"]-1)*100
for sy, df in dff.groupby("symbol"):#各銘柄ごとに特徴量作成
df.reset_index(drop=True, inplace=True)
df["m_dev"] = dff["dev"].rolling(30).mean()
list1.append(df)
dff = pd.concat(list1)
dff.dropna(inplace=True)
dff.reset_index(drop=True, inplace=True)
df1 = pd.read_pickle("bybit_ls_1h.pkl")
#df11 = df1[["symbol", "date", "close", "buy_ratio"]].copy()
df11 = df1.copy()
df2 = pd.merge(dff, df11, on=["symbol", "date", "close"]) #時間、銘柄、終値がちゃんと一致してるものを結合(最新の終値確定してないやつはここで弾かれる)
dfbi = pd.read_pickle("binance_1h.pkl")
df3 = pd.merge(df2, dfbi, on=["symbol","date"])
df4 = pd.merge(dff, dfbi, on=["symbol", "date"])
df2.reset_index(drop=True,inplace=True)
df3.reset_index(drop=True,inplace=True)
df4.reset_index(drop=True,inplace=True)
df2["date"] = df2["date"].apply(lambda x: x + timedelta(hours=1))#1時間足のcloseとlsを使う、dateは開始時間だから1時間足しておく
df3["date"] = df3["date"].apply(lambda x: x + timedelta(hours=1))
df4["date"] = df4["date"].apply(lambda x: x + timedelta(hours=1))
df2.rename({"buy_ratio":"ls"},axis=1,inplace=True)
df3.rename({"buy_ratio":"ls"},axis=1,inplace=True)
df2.to_pickle("bybit_ls_premium_1h.pkl")
df3.to_pickle("bin_byb_ls_premium_1h.pkl")
df4.to_pickle("bin_ls_premium.pkl")
print(df2)
print(df3)
print(df4)
#"""
return
#クロスセクション2
def all_symbol5(self):
df0 = pd.read_pickle("bybit_ls_premium_1h.pkl")
df0 = df0[df0["date"].apply(lambda x: x.hour)==16].copy()#16時(日本時間深夜1時にポジション変更)
sy_li = list(self.ftx_binance_common_symbols()) #binanceとの共通銘柄抽出
del_li = ["USDCUSDT"] #削除したい銘柄一覧
#df0 = df0[df0["symbol"].apply(lambda x: x in sy_li)]
df0 = df0[df0["symbol"].apply(lambda x: x not in del_li)] #削除したい銘柄一覧適応
df0["dev"] = df0["close"]/df0["close_s"] #現先乖離計算
df0 = df0[df0["dev"]>=0.9941].copy() #異常に先物が売られてるやつは除外
df0.reset_index(drop=True,inplace=True)
#銘柄ごとに特徴量生成################################################
def features(df):
df["pr_ch"] = df["close"].pct_change().shift(-1)
df["prch"] = df["close"].pct_change()
df["prch"] = df["prch"].apply(abs)
df["vola"] = df["prch"].rolling(7).mean() #n日平均ボラティリティ
df["dev_diff"] = df["dev"].diff()
return df
df0 = df0.groupby("symbol").apply(features)
df0.dropna(inplace=True)
df0.reset_index(drop=True,inplace=True)
#ボラに応じたロット数################################################
def lot_ratio(df):
std_vola = df["vola"][df["symbol"]=="BTCUSDT"].iloc[0] #BTCUSDTのボラを基準とする
df["lot"] = std_vola/df["vola"] #BTCUSDTよりボラが大きければ大きいほどロットが小さくなる
return df
df0 = df0.groupby("date").apply(lot_ratio)
#バックテスト################################################
sort = "sum_rank"
#sort = "ls_rank"
#sort = "dev_rank"
#sort = "dev_diff"
symboln = 10
trades = []
trades_df = []
def backtests(df):
df["ls_rank"] = df["ls"].rank()
df["dev_rank"] = df["dev"].rank()
df["sum_rank"] = df["ls_rank"] + df["dev_rank"]
df["sum_rank"] = df["sum_rank"].rank()
df.sort_values([sort],inplace=True,ascending=True) #ascending=Trueの時、特徴量の小さい順にロング、高い順にショート
longs_df = df.head(symboln)
shorts_df = df.tail(symboln)
#longs_df["pr_ch"] = (longs_df["pr_ch"]-0.0014)*longs_df["lot"]
longs_df["pr_ch"] = longs_df["pr_ch"]-0.0014
#shorts_df["pr_ch"] = (-shorts_df["pr_ch"]-0.0014)*shorts_df["lot"]
shorts_df["pr_ch"] = -shorts_df["pr_ch"]-0.0014
dic = {
"date":longs_df["date"].iloc[0],
"long_sys":list(longs_df["symbol"]),
"trade_up":longs_df["pr_ch"].sum(),
"shorts_sys":list(shorts_df["symbol"]),
"trade_down":shorts_df["pr_ch"].sum(),
}
trades.append(dic)
trades_df.append(longs_df)
trades_df.append(shorts_df)
return df
df0 = df0.groupby("date").apply(backtests)
df = pd.DataFrame(trades)
#毎日のトレードの分析#####################################
trades_df = pd.concat(trades_df)
trades_df.sort_values(["date","sum_rank"],inplace=True)
trades_df.reset_index(drop=True,inplace=True)
trades_df = trades_df.tail(100)
def results_print(df):
print(df)
return df
trades_df[["date","symbol","ls_rank","dev_rank","sum_rank","pr_ch"]].groupby("date").apply(results_print)
#結果整理################################################
df["trade"] = df["trade_up"] + df["trade_down"]
df["profit"] = df["trade"].cumsum()
df["profit2"] = df["profit"].cummax()
df["profit_up"] = df["trade_up"].cumsum()
df["profit_down"] = df["trade_down"].cumsum()
df.dropna(inplace=True)
df.reset_index(drop=True, inplace=True)
#df = df[df["date"].apply(lambda x: x<pd.to_datetime("2022-07-25"))].copy()
payoff_ratio = df["trade"][df["trade"]>0].mean()/df["trade"][df["trade"]<0].mean()
maxdd = (df["profit2"]-df["profit"]).max()
trades = df["trade"][df["trade"]!=0]
sharp = trades.mean()/trades.std()
winratio = len(trades[trades>0])/len(trades)
profit = df["trade"].sum()
print("###########################")
print(f'win ratio : {round(winratio,3)}')
print(f'sharp ratio : {round(sharp,3)}')
print(f'max drawdown : {round(maxdd,3)}')
print(f'payoff ratio : {round(abs(payoff_ratio),3)}')
print(f'profit :{round(profit,3)}')
print("###########################")
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(df["date"], df["profit"],color="black")
ax.plot(df["date"], df["profit_down"],color="red")
ax.plot(df["date"], df["profit_up"],color="green")
ax.text(0.01, 0.99, f'win ratio : {round(winratio,3)}\nsharp ratio : {round(sharp,3)}\nmax drawdown : {round(maxdd,3)}\npayoff ratio : {round(abs(payoff_ratio),3)}\nprofit : {round(profit,3)}', verticalalignment='top', transform=ax.transAxes)
ax.grid(which = "major", axis = "x", color = "blue", alpha = 0.5,linestyle = "--", linewidth = 1)
ax.grid(which = "major", axis = "y", color = "green", alpha = 0.5,linestyle = "--", linewidth = 1)
#print(df[["date","long_sys","shorts_sys"]].tail(30))
plt.show()
return
if __name__ == "__main__":
cl = cate_ls()
#cl.bybit_symbols()
#cl.bybit_dev_data() #データ集め(始めの一回は必要)
cl.all_symbol5()
```