Spaces:
Sleeping
Sleeping
anaucoin commited on
Commit ·
dd2e8c7
1
Parent(s): ea9526a
update style and pb backtest date
Browse files- .streamlit/config.toml +16 -3
- app.py +71 -47
- history_new.csv +21 -0
- pb-history-old.csv +31 -0
.streamlit/config.toml
CHANGED
|
@@ -1,6 +1,19 @@
|
|
| 1 |
[server]
|
| 2 |
port=8501
|
| 3 |
-
enableCORS = false
|
| 4 |
-
enableXsrfProtection = false
|
| 5 |
[theme]
|
| 6 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
[server]
|
| 2 |
port=8501
|
|
|
|
|
|
|
| 3 |
[theme]
|
| 4 |
+
|
| 5 |
+
# Primary accent for interactive elements
|
| 6 |
+
primaryColor = '#21D4E1'
|
| 7 |
+
|
| 8 |
+
# Background color for the main content area
|
| 9 |
+
backgroundColor = '#0A0A0A'
|
| 10 |
+
|
| 11 |
+
# Background color for sidebar and most interactive widgets
|
| 12 |
+
secondaryBackgroundColor = '#454545'
|
| 13 |
+
# Color used for almost all text
|
| 14 |
+
textColor = '#FFFFFF'
|
| 15 |
+
|
| 16 |
+
# Font family for all text in the app, except code blocks
|
| 17 |
+
# Accepted values (serif | sans serif | monospace)
|
| 18 |
+
# Default: "sans serif"
|
| 19 |
+
font = "sans serif"
|
app.py
CHANGED
|
@@ -184,48 +184,62 @@ def filt_df(df, cheader, symbol_selections):
|
|
| 184 |
def load_data(filename, account, exchange, otimeheader, fmat):
|
| 185 |
cols = ['id','datetime', 'exchange', 'subaccount', 'pair', 'side', 'action', 'amount', 'price']
|
| 186 |
df = pd.read_csv(filename, header = 0, names= cols)
|
| 187 |
-
|
| 188 |
filtdf = df[(df.exchange == exchange) & (df.subaccount == account)].dropna()
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 216 |
dateheader = 'Date'
|
| 217 |
theader = 'Time'
|
| 218 |
|
| 219 |
-
|
| 220 |
-
|
| 221 |
|
| 222 |
-
|
| 223 |
-
|
| 224 |
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
return newdf
|
| 229 |
|
| 230 |
def get_pl(bot_selections, df, dca1, dca2, dca3, dollar_cap, lev, principal_balance):
|
| 231 |
signal_map = {'Long': 1, 'Short':-1}
|
|
@@ -276,7 +290,7 @@ def runapp() -> None:
|
|
| 276 |
dollar_cap = 1000000000.00
|
| 277 |
|
| 278 |
pn_data = load_data('history.csv', 'Pumpernickel Test', 'Bybit Futures', otimeheader, fmat)
|
| 279 |
-
pb_data = load_data('
|
| 280 |
|
| 281 |
df = pd.concat([pn_data, pb_data])
|
| 282 |
|
|
@@ -432,32 +446,42 @@ def runapp() -> None:
|
|
| 432 |
line = {'smoothing': 1.0, 'color' :'green'}, name = 'DOGE Buy & Hold Return')
|
| 433 |
)
|
| 434 |
|
|
|
|
|
|
|
| 435 |
fig.add_layout_image(
|
| 436 |
dict(
|
| 437 |
source=pyLogo,
|
| 438 |
xref="paper",
|
| 439 |
yref="paper",
|
| 440 |
-
x = 0.
|
| 441 |
-
y =
|
| 442 |
-
sizex=
|
| 443 |
-
sizey=
|
| 444 |
-
|
| 445 |
-
opacity=0.2,
|
| 446 |
layer = "below")
|
| 447 |
)
|
| 448 |
|
| 449 |
#style layout
|
| 450 |
fig.update_layout(
|
| 451 |
-
height =
|
| 452 |
xaxis=dict(
|
| 453 |
title="Exit Date",
|
| 454 |
tickmode='array',
|
|
|
|
| 455 |
),
|
| 456 |
yaxis=dict(
|
| 457 |
-
title="Cumulative P/L"
|
| 458 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 459 |
|
| 460 |
-
st.plotly_chart(fig, theme=None, use_container_width=True,height=
|
| 461 |
|
| 462 |
df['Per Trade Return Rate'] = df['Return Per Trade']-1
|
| 463 |
|
|
|
|
| 184 |
def load_data(filename, account, exchange, otimeheader, fmat):
|
| 185 |
cols = ['id','datetime', 'exchange', 'subaccount', 'pair', 'side', 'action', 'amount', 'price']
|
| 186 |
df = pd.read_csv(filename, header = 0, names= cols)
|
| 187 |
+
|
| 188 |
filtdf = df[(df.exchange == exchange) & (df.subaccount == account)].dropna()
|
| 189 |
+
|
| 190 |
+
if not filtdf.empty:
|
| 191 |
+
filtdf = filtdf.sort_values('datetime')
|
| 192 |
+
filtdf = filtdf.iloc[np.where(filtdf.action == 'open')[0][0]:, :] #get first open signal in dataframe
|
| 193 |
+
|
| 194 |
+
tnum = 0
|
| 195 |
+
dca = 0
|
| 196 |
+
newdf = pd.DataFrame([], columns=['Trade','Signal','Entry Date','Buy Price', 'Sell Price','Exit Date', 'P/L per token', 'P/L %'])
|
| 197 |
+
for index, row in filtdf.iterrows():
|
| 198 |
+
if row.action == 'open':
|
| 199 |
+
dca += 1
|
| 200 |
+
tnum += 1
|
| 201 |
+
sig = 'Long' if row.side == 'buy' else 'Short'
|
| 202 |
+
temp = pd.DataFrame({'Trade' :[tnum], 'Signal': [sig], 'Entry Date':[row.datetime],'Buy Price': [row.price], 'Sell Price': [np.nan],'Exit Date': [np.nan], 'P/L per token': [np.nan], 'P/L %': [np.nan], 'DCA': [dca]})
|
| 203 |
+
newdf = pd.concat([newdf,temp], ignore_index = True)
|
| 204 |
+
if row.action == 'close':
|
| 205 |
+
for j in np.arange(tnum-1, tnum-dca-1,-1):
|
| 206 |
+
newdf.loc[j,'Sell Price'] = row.price
|
| 207 |
+
newdf.loc[j,'Exit Date'] = row.datetime
|
| 208 |
+
dca = 0
|
| 209 |
+
|
| 210 |
+
newdf['Buy Price'] = pd.to_numeric(newdf['Buy Price'])
|
| 211 |
+
newdf['Sell Price'] = pd.to_numeric(newdf['Sell Price'])
|
| 212 |
+
|
| 213 |
+
newdf['P/L per token'] = newdf['Sell Price'] - newdf['Buy Price']
|
| 214 |
+
newdf['P/L %'] = 100*newdf['P/L per token']/newdf['Buy Price']
|
| 215 |
+
newdf = newdf.dropna()
|
| 216 |
+
else:
|
| 217 |
+
newdf = pd.DataFrame([], columns=['Trade','Signal','Entry Date','Buy Price', 'Sell Price','Exit Date', 'P/L per token', 'P/L %'])
|
| 218 |
+
|
| 219 |
+
if account == 'Pure Bread Test':
|
| 220 |
+
tvdata = pd.read_csv('pb-history-old.csv',header = 0).drop('Unnamed: 0', axis=1)
|
| 221 |
+
else:
|
| 222 |
+
tvdata = pd.DataFrame([])
|
| 223 |
+
if tvdata.empty:
|
| 224 |
+
df = newdf
|
| 225 |
+
else:
|
| 226 |
+
df = pd.concat([tvdata, newdf], ignore_index =True)
|
| 227 |
+
df = df.sort_values('Entry Date', ascending = True)
|
| 228 |
+
df.index = range(len(df))
|
| 229 |
+
df.Trade = df.index + 1
|
| 230 |
+
|
| 231 |
dateheader = 'Date'
|
| 232 |
theader = 'Time'
|
| 233 |
|
| 234 |
+
df[dateheader] = [tradetimes.split(" ")[0] for tradetimes in df[otimeheader].values]
|
| 235 |
+
df[theader] = [tradetimes.split(" ")[1] for tradetimes in df[otimeheader].values]
|
| 236 |
|
| 237 |
+
df[otimeheader] = pd.to_datetime(df[otimeheader])
|
| 238 |
+
df['Exit Date'] = pd.to_datetime(df['Exit Date'])
|
| 239 |
|
| 240 |
+
df[dateheader] = [dateutil.parser.parse(date).date() for date in df[dateheader]]
|
| 241 |
+
df[theader] = [dateutil.parser.parse(time).time() for time in df[theader]]
|
| 242 |
+
return df
|
|
|
|
| 243 |
|
| 244 |
def get_pl(bot_selections, df, dca1, dca2, dca3, dollar_cap, lev, principal_balance):
|
| 245 |
signal_map = {'Long': 1, 'Short':-1}
|
|
|
|
| 290 |
dollar_cap = 1000000000.00
|
| 291 |
|
| 292 |
pn_data = load_data('history.csv', 'Pumpernickel Test', 'Bybit Futures', otimeheader, fmat)
|
| 293 |
+
pb_data = load_data('history_new.csv', 'Pure Bread Test', 'Bybit Futures', otimeheader, fmat)
|
| 294 |
|
| 295 |
df = pd.concat([pn_data, pb_data])
|
| 296 |
|
|
|
|
| 446 |
line = {'smoothing': 1.0, 'color' :'green'}, name = 'DOGE Buy & Hold Return')
|
| 447 |
)
|
| 448 |
|
| 449 |
+
img_width = 2001
|
| 450 |
+
img_height = 622
|
| 451 |
fig.add_layout_image(
|
| 452 |
dict(
|
| 453 |
source=pyLogo,
|
| 454 |
xref="paper",
|
| 455 |
yref="paper",
|
| 456 |
+
x = 0.1,
|
| 457 |
+
y = 1,
|
| 458 |
+
sizex= 1,
|
| 459 |
+
sizey= 1,
|
| 460 |
+
opacity=0.5,
|
|
|
|
| 461 |
layer = "below")
|
| 462 |
)
|
| 463 |
|
| 464 |
#style layout
|
| 465 |
fig.update_layout(
|
| 466 |
+
height = 550,
|
| 467 |
xaxis=dict(
|
| 468 |
title="Exit Date",
|
| 469 |
tickmode='array',
|
| 470 |
+
showgrid=False
|
| 471 |
),
|
| 472 |
yaxis=dict(
|
| 473 |
+
title="Cumulative P/L",
|
| 474 |
+
showgrid=False
|
| 475 |
+
),
|
| 476 |
+
legend=dict(
|
| 477 |
+
x=.05,
|
| 478 |
+
y=0.95,
|
| 479 |
+
traceorder="normal"
|
| 480 |
+
),
|
| 481 |
+
plot_bgcolor = 'rgba(10, 10, 10, 1)'
|
| 482 |
+
)
|
| 483 |
|
| 484 |
+
st.plotly_chart(fig, theme=None, use_container_width=True, height=550)
|
| 485 |
|
| 486 |
df['Per Trade Return Rate'] = df['Return Per Trade']-1
|
| 487 |
|
history_new.csv
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
,id,datetime,exchange,subaccount,pair,side,action,amount,price,error
|
| 2 |
+
0,31,2024-02-18 04:25:32,Bybit Futures,test connection,BTCUSDT,sell,open,0.009,51900,Order filled
|
| 3 |
+
1,32,2024-02-18 04:25:55,Bybit Futures,test connection,BTCUSDT,buy,close,0.009,51900.1,Order filled
|
| 4 |
+
2,35,2024-02-18 07:20:54,Bitget,bitget test,XRPUSDT,long,open,340,0.55548,Order filled
|
| 5 |
+
3,36,2024-02-18 07:21:14,Bitget,bitget test,XRPUSDT,short,close,336,0.55548,Order filled
|
| 6 |
+
4,37,2024-02-18 07:21:14,Bitget,bitget test,XRPUSDT,short,open,336,0.55548,Order filled
|
| 7 |
+
5,39,2024-02-18 07:22:23,Bitget,bitget test,XRPUSDT,long,open,414,0.55548,Order filled
|
| 8 |
+
6,49,2024-02-18 10:19:47,Bitget,Pumpernickel BitGet Test,ETHUSDT,long,open,0.1,2799.87,Order filled
|
| 9 |
+
7,51,2024-02-18 12:49:06,Bitget,Pumpernickel BitGet Test,ETHUSDT,short,close,0.1,2825.93,Order filled
|
| 10 |
+
8,52,2024-02-18 12:49:06,Bitget,Pumpernickel BitGet Test,ETHUSDT,short,open,0.1,2826.68,Order filled
|
| 11 |
+
9,53,2024-02-18 16:04:36,Bitget,Pumpernickel BitGet Test,ETHUSDT,short,open,0.09,2850.78,Order filled
|
| 12 |
+
10,54,2024-02-18 16:13:16,Bitget,Pumpernickel BitGet Test,ETHUSDT,short,open,0.09,2880.15,Order filled
|
| 13 |
+
11,97,2024-02-19 04:26:02,Bybit Futures,bybit test,,,,,,No need to place order for BTCUSDT.
|
| 14 |
+
12,98,2024-02-19 04:53:02,Bybit Futures,bybit test,,,,,,"Error: Get active positions:
|
| 15 |
+
Traceback (most recent call last):
|
| 16 |
+
File ""/home/breadbytes1/mysite/bybitUniFuturesClient.py"", line 158, in get_position
|
| 17 |
+
position = self.client.get_positions(category= ""linear"", symbol= pair)['result']['list'][0]
|
| 18 |
+
File ""/home/breadbytes1/.local/lib/python3.10/site-packages/pybit/_v5_position.py"", line 22, in get_positions
|
| 19 |
+
return self._submit_request(
|
| 20 |
+
File ""/home/breadbytes1/.local/lib/python3.10/site-packages/pybit/_http_manager.py"", line 294, in _submit_request
|
| 21 |
+
"
|
pb-history-old.csv
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
,Trade,Signal,Entry Date,Buy Price,Sell Price,Exit Date,P/L per token,P/L %,DCA
|
| 2 |
+
0,1,Short,2023-07-04 12:00,0.07079,0.06795,2023-07-05 04:30,0.002840000000000009,3.86,1.0
|
| 3 |
+
1,2,Short,2023-07-15 04:00,0.07322,0.07029,2023-07-15 21:15,0.002929999999999988,3.85,1.0
|
| 4 |
+
2,3,Short,2023-07-20 06:00,0.07261,0.0697,2023-07-20 13:15,0.002909999999999996,3.86,1.0
|
| 5 |
+
3,4,Short,2023-07-25 01:00,0.07781,0.08015,2023-07-25 11:30,-0.002339999999999995,-3.16,1.0
|
| 6 |
+
4,5,Long,2023-08-17 16:30,0.05579,0.05958,2023-08-17 16:45,0.0037900000000000017,6.63,1.0
|
| 7 |
+
5,6,Long,2023-08-17 22:00,0.06006,0.06307,2023-08-18 06:30,0.003009999999999999,4.85,1.0
|
| 8 |
+
6,7,Short,2023-08-29 11:00,0.06743,0.06473,2023-08-30 09:30,0.002700000000000008,3.85,1.0
|
| 9 |
+
7,8,Long,2023-10-25 18:30,0.06834,0.07176,2023-10-25 21:45,0.0034200000000000064,4.85,1.0
|
| 10 |
+
8,9,Long,2023-11-07 03:30,0.07374,0.07743,2023-11-09 08:15,0.003689999999999999,4.85,1.0
|
| 11 |
+
9,10,Long,2023-11-13 18:00,0.07298,0.07006,2023-11-14 12:45,-0.002920000000000006,-4.14,1.0
|
| 12 |
+
10,11,Long,2023-11-16 17:15,0.07737,0.08124,2023-11-16 20:00,0.0038700000000000123,4.84,1.0
|
| 13 |
+
11,12,Short,2023-11-17 03:00,0.08685,0.08337,2023-11-17 05:15,0.003479999999999997,3.86,1.0
|
| 14 |
+
12,13,Long,2023-11-21 16:15,0.07287,0.07652,2023-11-22 15:00,0.0036500000000000005,4.85,1.0
|
| 15 |
+
13,14,Long,2023-11-27 04:30,0.07871,0.08265,2023-11-29 06:15,0.003939999999999999,4.85,1.0
|
| 16 |
+
14,15,Short,2023-12-04 00:00,0.09087,0.08723,2023-12-04 05:00,0.0036400000000000043,3.86,1.0
|
| 17 |
+
15,16,Short,2023-12-05 14:00,0.09463,0.09747,2023-12-05 22:45,-0.0028399999999999953,-3.15,1.0
|
| 18 |
+
16,17,Short,2023-12-06 01:00,0.10593,0.10169,2023-12-06 01:30,0.004239999999999994,3.85,1.0
|
| 19 |
+
17,18,Long,2023-12-06 12:15,0.09836,0.09442,2023-12-06 17:30,-0.003939999999999999,-4.15,1.0
|
| 20 |
+
18,19,Long,2023-12-07 13:30,0.09402,0.09873,2023-12-08 06:30,0.004709999999999992,4.85,1.0
|
| 21 |
+
19,20,Long,2023-12-09 17:00,0.09966,0.10465,2023-12-10 19:45,0.004990000000000008,4.85,1.0
|
| 22 |
+
20,21,Long,2023-12-11 08:45,0.09472,0.09638,2023-12-11 22:00,0.0016599999999999948,1.6,1.0
|
| 23 |
+
21,22,Short,2023-12-11 22:00,0.09638,0.09252,2023-12-12 11:00,0.0038599999999999884,3.86,1.0
|
| 24 |
+
22,23,Long,2023-12-12 11:15,0.09163,0.09622,2023-12-13 15:45,0.004589999999999997,4.85,1.0
|
| 25 |
+
23,24,Short,2023-12-13 17:00,0.09694,0.09306,2023-12-15 17:15,0.0038799999999999946,3.85,1.0
|
| 26 |
+
24,25,Long,2023-12-20 13:45,0.09162,0.09621,2023-12-21 14:00,0.004590000000000011,4.85,1.0
|
| 27 |
+
25,26,Short,2023-12-21 17:00,0.0946,0.09081,2023-12-24 16:15,0.0037900000000000017,3.86,1.0
|
| 28 |
+
26,27,Long,2024-01-03 06:00,0.08018,0.08419,2024-01-03 06:45,0.00401,4.84,1.0
|
| 29 |
+
27,28,Short,2024-01-20 17:00,0.08835,0.08481,2024-01-21 01:00,0.0035400000000000015,3.86,1.0
|
| 30 |
+
28,29,Long,2024-01-23 03:15,0.07607,0.07988,2024-01-24 00:15,0.003810000000000008,4.85,1.0
|
| 31 |
+
29,30,Short,2024-02-19 17:15,0.09039,0.08677,2024-02-20 02:00,0.0036199999999999982,3.85,1.0
|