Skip to content

Commit 75ecab9

Browse files
committed
init
0 parents  commit 75ecab9

32 files changed

+536967
-0
lines changed

.gitignore

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# rope configuration
2+
.cache/
3+
.DS_Store
4+
*.log
5+
__pycache__
6+
.pytest_cache
7+
8+
# Python
9+
*.py[co]
10+
11+
## Packages
12+
*.egg
13+
*.egg-info
14+
dist
15+
venv
16+
log
17+
docs/_build
18+
docs/api
19+
20+
21+
## paver generated files
22+
paver-minilib.zip
23+
24+
config.json
25+
.env

.vscode/settings.json

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"python.defaultInterpreterPath": "venv/bin/python",
3+
"python.formatting.provider": "yapf",
4+
"python.formatting.yapfArgs": [
5+
"--style",
6+
"{column_limit:160,space_inside_brackets:false,arithmetic_precedence_indication:true,blank_line_before_nested_class_or_def:true,spaces_around_dict_delimiters:true}"
7+
]
8+
}

BOLL+KDJ.txt

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
空仓
2+
买入: 由boll触发主判断,如果close大于上轨并且kdj最后一次是买入信号则开多
3+
卖出: 由boll触发主判断,如果close小于下轨并且kdj最后一次是卖出信号则开空
4+
5+
持仓
6+
空仓: 由kdj触发主判断,如果kdj信号为买入信号并且close大于下轨则平仓
7+
多仓: 由kdj触发主判断,如果kdj信号为卖出信号并且close小于上轨则平仓

binance_data.py

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from datetime import datetime
2+
import backtrader as bt
3+
4+
from data.dataset import CustomDataset
5+
from strategies.abbration import Abbration
6+
from strategies.bollkdj import BOLLKDJ
7+
from strategies.bollema import BollEMA
8+
from strategies.boll import Boll
9+
10+
11+
class PrintClose(bt.Strategy):
12+
13+
def log(self, txt, dt=None):
14+
dt = dt or self.datas[0].datetime.datetime(0)
15+
print(f'{dt} {txt}') # Print date and close
16+
17+
def next(self):
18+
self.log('Close: %.3f' % self.data0.close[0])
19+
20+
21+
if __name__ == '__main__':
22+
cerebro = bt.Cerebro(maxcpus=1)
23+
# cerebro.addstrategy(PrintClose)
24+
cerebro.addstrategy(Boll, period_boll=275, boll_diff=40)
25+
# cerebro.addstrategy(BollEMA)
26+
# cerebro.addstrategy(Abbration, boll_period=200)
27+
# cerebro.addstrategy(BOLLKDJ, boll_period=200, kdj_period=72, kdj_ma1=24, kdj_ma2=24)
28+
29+
# cerebro.optstrategy(Boll, period_boll=range(250, 300,5), debug=False)
30+
31+
# 加载数据
32+
data = CustomDataset(name="ETH",
33+
dataname="data/ETHUSDT-1m-2022-07.csv",
34+
dtformat=lambda x: datetime.utcfromtimestamp(int(x) / 1000),
35+
timeframe=bt.TimeFrame.Minutes,
36+
fromdate=datetime(2022, 5, 1),
37+
todate=datetime(2022, 11, 1),
38+
nullvalue=0.0)
39+
cerebro.resampledata(data, timeframe=bt.TimeFrame.Minutes, compression=5)
40+
41+
cerebro.broker.setcash(100.0)
42+
43+
# 配置滑点费用,2跳
44+
# cerebro.broker.set_slippage_fixed(slippage*1)
45+
46+
cerebro.broker.setcommission(commission=0.0004, margin=0.1, mult=1.0)
47+
# cerebro.broker.setcommission(commission=0.00075)
48+
49+
cerebro.addsizer(bt.sizers.FixedSize, stake=1)
50+
51+
cerebro.run()
52+
53+
cerebro.plot()

binance_live.py

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
from ccxtbt import CCXTStore
2+
import backtrader as bt
3+
from datetime import datetime, timedelta
4+
from strategies.bollema import BollEMA
5+
from strategies.boll import Boll
6+
from utils.helper import init_env, get_env
7+
8+
9+
class TestStrategy(bt.Strategy):
10+
11+
def __init__(self):
12+
13+
self.sma = bt.indicators.SMA(self.data, period=21)
14+
15+
def next(self):
16+
17+
# Get cash and balance
18+
# New broker method that will let you get the cash and balance for
19+
# any wallet. It also means we can disable the getcash() and getvalue()
20+
# rest calls before and after next which slows things down.
21+
22+
# NOTE: If you try to get the wallet balance from a wallet you have
23+
# never funded, a KeyError will be raised! Change LTC below as approriate
24+
if self.live_data:
25+
cash, value = self.broker.get_wallet_balance('USDT')
26+
else:
27+
# Avoid checking the balance during a backfill. Otherwise, it will
28+
# Slow things down.
29+
cash = 'NA'
30+
# return # 仍然处于历史数据回填阶段,不执行逻辑,返回
31+
32+
for data in self.datas:
33+
34+
print('{} - {} | Cash {} | O: {} H: {} L: {} C: {} V:{} SMA:{}'.format(data.datetime.datetime(), data._name, cash, data.open[0], data.high[0],
35+
data.low[0], data.close[0], data.volume[0], self.sma[0]))
36+
37+
def notify_data(self, data, status, *args, **kwargs):
38+
dn = data._name
39+
dt = datetime.utcnow()
40+
msg = 'Data Status: {}'.format(data._getstatusname(status))
41+
print(dt, dn, msg)
42+
if data._getstatusname(status) == 'LIVE':
43+
self.live_data = True
44+
else:
45+
self.live_data = False
46+
47+
48+
if __name__ == '__main__':
49+
init_env()
50+
cerebro = bt.Cerebro(quicknotify=True)
51+
52+
# Add the strategy
53+
# cerebro.addstrategy(TestStrategy)
54+
# cerebro.addstrategy(BollEMA, period_boll=200, period_ema=99, production=True)
55+
cerebro.addstrategy(Boll)
56+
57+
# Create our store
58+
config = { 'apiKey': get_env('B_APIKEY'), 'secret': get_env('B_SECRET'), 'enableRateLimit': True }
59+
if get_env("PROXY") == '1':
60+
config['proxies'] = { 'https': "http://127.0.0.1:8001", 'http': "http://127.0.0.1:8001"}
61+
62+
# IMPORTANT NOTE - Kraken (and some other exchanges) will not return any values
63+
# for get cash or value if You have never held any BNB coins in your account.
64+
# So switch BNB to a coin you have funded previously if you get errors
65+
store = CCXTStore(exchange='binanceusdm', currency='USDT', config=config, retries=5, debug=False)
66+
67+
# Get the broker and pass any kwargs if needed.
68+
# ----------------------------------------------
69+
# Broker mappings have been added since some exchanges expect different values
70+
# to the defaults. Case in point, Kraken vs Bitmex. NOTE: Broker mappings are not
71+
# required if the broker uses the same values as the defaults in CCXTBroker.
72+
broker_mapping = {
73+
'order_types': {
74+
bt.Order.Market: 'market',
75+
bt.Order.Limit: 'limit',
76+
bt.Order.Stop: 'stop-loss', #stop-loss for kraken, stop for bitmex
77+
bt.Order.StopLimit: 'stop limit'
78+
},
79+
'mappings': {
80+
'closed_order': {
81+
'key': 'status',
82+
'value': 'closed'
83+
},
84+
'canceled_order': {
85+
'key': 'status',
86+
'value': 'canceled'
87+
}
88+
}
89+
}
90+
91+
broker = store.getbroker(broker_mapping=broker_mapping)
92+
cerebro.setbroker(broker)
93+
94+
# Get our data
95+
# Drop newest will prevent us from loading partial data from incomplete candles
96+
hist_start_date = datetime.utcnow() - timedelta(minutes=1600)
97+
data = store.getdata(
98+
dataname='ETH/USDT',
99+
name="ETHUSDT",
100+
timeframe=bt.TimeFrame.Minutes,
101+
fromdate=hist_start_date,
102+
compression=5,
103+
ohlcv_limit=99999,
104+
drop_newest=True,
105+
# historical=True
106+
)
107+
108+
# Add the feed
109+
cerebro.adddata(data)
110+
111+
cerebro.broker.setcommission(commission=0.0004, margin=0.1, mult=1.0)
112+
cerebro.addsizer(bt.sizers.FixedSize, stake=1)
113+
114+
# Run the strategy
115+
cerebro.run()

custom_data.py

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from datetime import datetime
2+
import backtrader as bt
3+
import pandas as pd
4+
5+
6+
class PrintClose(bt.Strategy):
7+
8+
def log(self, txt, dt=None):
9+
dt = dt or self.datas[0].datetime.datetime(0)
10+
print(f'{dt} {txt}') # Print date and close
11+
12+
def next(self):
13+
self.log('Close: %.3f' % self.data0.close[0])
14+
self.log('turnover: %.8f' % self.data0.turnover[0])
15+
16+
17+
class CustomData(bt.feeds.PandasData):
18+
# class CustomData(bt.feeds.GenericCSVData):
19+
lines = ("turnover", )
20+
params = (("turnover", -1), )
21+
22+
23+
if __name__ == '__main__':
24+
cerebro = bt.Cerebro()
25+
cerebro.addstrategy(PrintClose)
26+
datapath = './data/t.csv'
27+
28+
# 加载数据
29+
stock_hfq_df = pd.read_csv(datapath, index_col="date", parse_dates=True, usecols=["date", "open", "high", "low", "close", "volume", "turnover"])
30+
start_date = datetime(2016, 7, 4) # 回测开始时间
31+
end_date = datetime(2021, 12, 4) # 回测结束时间
32+
data = CustomData(dataname=stock_hfq_df, fromdate=start_date, todate=end_date)
33+
34+
# 加载数据
35+
# data = CustomData(dataname=datapath, dtformat=('%Y-%m-%d %H:%M:%S%z'), datetime=0, open=1, high=2, low=3, close=4, volume=5, turnover=6, openinterest=-1)
36+
37+
cerebro.adddata(data)
38+
cerebro.run()

0 commit comments

Comments
 (0)