Skip to content

Instantly share code, notes, and snippets.

@sharavsambuu
Last active June 19, 2023 03:57
Show Gist options
  • Select an option

  • Save sharavsambuu/c1b739e80e51f66e78319ef739d4f599 to your computer and use it in GitHub Desktop.

Select an option

Save sharavsambuu/c1b739e80e51f66e78319ef739d4f599 to your computer and use it in GitHub Desktop.
Backtesting BTC using Binance taker fee, x20 leverage and backtesting.py library. Size must be between 0.0 and 1.0
#%%
import warnings
warnings.filterwarnings("ignore")
def action_with_warnings():
warnings.warn("should not appear")
with warnings.catch_warnings(record=True):
action_with_warnings()
import sys
sys.path.insert(0, '.')
import os
import csv
import time
import math
import requests
import glob
import zipfile
import talib
import pandas as pd
import numpy as np
import mplfinance as mpf
import matplotlib.pyplot as plt
import pyfolio as pf
from scipy.stats import norm
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
from pyfolio.plotting import plot_rolling_sharpe
#%%
# signal extraction business goes here...
# ...
#%%
#%%
#%%
# Resources :
# - Buy asset for a fixed amount of cash
# https://github.com/kernc/backtesting.py/issues/97
#
def calculate_dollar_risk(
equity ,
price ,
sl_price ,
risk_pct=0.02,
leverage=20.0
):
sl_price_pips = abs(float(price)-float(sl_price))
risk_by_dollar = (equity*leverage)*risk_pct/100.0
dollar_risk_with_sl = price*risk_by_dollar/sl_price_pips
return dollar_risk_with_sl
equity = 5000 # by USD
leverage = 20 # x20 leverage
position_risk = 0.015 # % per trade
commission = 0.0004 # binance taker fee
class PriceActionStrategy(Strategy):
def init(self):
super().init()
def next(self):
super().next()
available_to_trade = True
if len(self.trades)>=1:
available_to_trade = False
if not available_to_trade:
return
timestamp = self.data.index [-1]
price = self.data.Close [-1]
long_tp = self.data.long_tp [-1]
long_sl = self.data.long_sl [-1]
short_sl = self.data.short_sl[-1]
short_tp = self.data.short_tp[-1]
# Long case
if self.data.long_position[-1]==True:
if not (long_tp>price and long_sl<price):
return
#print(f"BUY at {timestamp} TP={long_tp} SL={long_sl}")
dollar_risk = calculate_dollar_risk(self.equity, price, long_sl, risk_pct=position_risk, leverage=leverage)
scaled_position_size = dollar_risk/price
print(f"Long => dollar risk : {dollar_risk}, scaled position size : {scaled_position_size}")
self.buy(size=scaled_position_size, sl=long_sl, tp=long_tp)
pass
# Short case
if self.data.short_position[-1]==True:
if not (short_tp<price and short_sl>price):
return
#print(f"SELL at {timestamp} TP={short_tp} SL={short_sl}")
dollar_risk = calculate_dollar_risk(self.equity, price, short_sl, risk_pct=position_risk, leverage=leverage)
scaled_position_size = dollar_risk/price
print(f"Short => dollar risk : {dollar_risk}, scaled position size : {scaled_position_size}")
self.sell(size=scaled_position_size, sl=short_sl, tp=short_tp)
pass
bt = Backtest(
df_eval,
PriceActionStrategy,
cash = equity,
commission = commission,
margin = 1/leverage, # x20 leverage
exclusive_orders = True
)
stats = bt.run()
print(stats)
#%%
eval_df = stats['_trades'][['ReturnPct', 'EntryTime']]
eval_df = eval_df.set_index('EntryTime')
pf.create_simple_tear_sheet(eval_df['ReturnPct'])
#%%
#%%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment