Skip to content

Commit

Permalink
add some tutorials into docs and update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
Charmve committed Jun 6, 2024
1 parent e58674e commit b5bc8eb
Show file tree
Hide file tree
Showing 3,127 changed files with 3,262,649 additions and 47 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.h5 filter=lfs diff=lfs merge=lfs -text
investool/main filter=lfs diff=lfs merge=lfs -text
investool/investool filter=lfs diff=lfs merge=lfs -text
*.parquet filter=lfs diff=lfs merge=lfs -text
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,6 @@ gui/__pycache__/
gui/csv/

pytrader/user_config.sh
*.parquet

**.DS_Store
254 changes: 212 additions & 42 deletions README.md

Large diffs are not rendered by default.

Binary file added docs/01-新手指引/images/alpha-trade.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/01-新手指引/images/bodong.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/01-新手指引/images/duokong.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/01-新手指引/images/index_stranger.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/01-新手指引/images/tieshui.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
602 changes: 602 additions & 0 deletions docs/01-新手指引/量化策略的分类和原理.md

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions docs/02-经典策略/01-股票/股票指标.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
每日股票指标数据计算17个指标如下(数据表 guess_indicators_daily):


| | 计算指标 | 说明 |
| - | ----------------- | ------------------------------------------|
| 1 | 交易量delta指标分析 | The Volume Delta (Vol ∆) |
| 2 | 计算n天差 | 可以计算,向前n天,和向后n天的差。 |
| 3 | n天涨跌百分百计算 | 可以看到,-n天数据和今天数据的百分比。 |
| 4 | CR指标 | http://wiki.mbalib.com/wiki/CR%E6%8C%87%E6%A0%87 价格动量指标 CR跌穿a、b、c、d四条线,再由低点向上爬升160时,为短线获利的一个良机,应适当卖出股票。 CR跌至40以下时,是建仓良机。而CR高于300~400时,应注意适当减仓。 |
| 5 | 最大值,最小值 | 计算区间最大值 volume max of three days ago, yesterday and two days later stock["volume_-3,2,-1_max"] volume min between 3 days ago and tomorrow stock["volume_-3~1_min"] 实际使用的时候使用 -2~2 可计算出5天的最大,最小值。 |
| 6 | KDJ指标 | http://wiki.mbalib.com/wiki/%E9%9A%8F%E6%9C%BA%E6%8C%87%E6%A0%87 随机指标(KDJ)一般是根据统计学的原理,通过一个特定的周期(常为9日、9周等)内出现过的最高价、 最低价及最后一个计算周期的收盘价及这三者之间的比例关系,来计算最后一个计算周期的未成熟随机值RSV, 然后根据平滑移动平均线的方法来计算K值、D值与J值,并绘成曲线图来研判股票走势。 (3)在使用中,常有J线的指标,即3乘以K值减2乘以D值(3K-2D=J),其目的是求出K值与D值的最大乖离程度, 以领先KD值找出底部和头部。J大于100时为超买,小于10时为超卖。 |
| 7 | SMA指标 | http://wiki.mbalib.com/wiki/Sma 简单移动平均线(Simple Moving Average,SMA) 可以动态输入参数,获得几天的移动平均。 |
| 8 | MACD指标 | http://wiki.mbalib.com/wiki/MACD 平滑异同移动平均线(Moving Average Convergence Divergence,简称MACD指标),也称移动平均聚散指标 MACD 则可发挥其应有的功能,但当市场呈牛皮盘整格局,股价不上不下时,MACD买卖讯号较不明显。 当用MACD作分析时,亦可运用其他的技术分析指标如短期 K,D图形作为辅助工具,而且也可对买卖讯号作双重的确认。 |
| 9 | BOLL指标 | http://wiki.mbalib.com/wiki/BOLL 布林线指标(Bollinger Bands) |
| 10 | RSI指标 | http://wiki.mbalib.com/wiki/RSI 相对强弱指标(Relative Strength Index,简称RSI),也称相对强弱指数、相对力度指数 2)强弱指标保持高于50表示为强势市场,反之低于50表示为弱势市场。 (3)强弱指标多在70与30之间波动。当六日指标上升到达80时,表示股市已有超买现象,如果一旦继续上升,超过90以上时,则表示已到严重超买的警戒区,股价已形成头部,极可能在短期内反转回转。 |
| 11 | W%R指标 | http://wiki.mbalib.com/wiki/%E5%A8%81%E5%BB%89%E6%8C%87%E6%A0%87 威廉指数(Williams%Rate)该指数是利用摆动点来度量市场的超买超卖现象。 |
| 12 | CCI指标 | http://wiki.mbalib.com/wiki/%E9%A1%BA%E5%8A%BF%E6%8C%87%E6%A0%87 顺势指标又叫CCI指标,其英文全称为“Commodity Channel Index”, 是由美国股市分析家唐纳德·蓝伯特(Donald Lambert)所创造的,是一种重点研判股价偏离度的股市分析工具。 1、当CCI指标从下向上突破﹢100线而进入非常态区间时,表明股价脱离常态而进入异常波动阶段, 中短线应及时买入,如果有比较大的成交量配合,买入信号则更为可靠。 2、当CCI指标从上向下突破﹣100线而进入另一个非常态区间时,表明股价的盘整阶段已经结束, 将进入一个比较长的寻底过程,投资者应以持币观望为主。 CCI, default to 14 days |
| 13 | TR、ATR指标 | http://wiki.mbalib.com/wiki/%E5%9D%87%E5%B9%85%E6%8C%87%E6%A0%87 均幅指标(Average True Ranger,ATR)均幅指标(ATR)是取一定时间周期内的股价波动幅度的移动平均值,主要用于研判买卖时机。 |
| 14 | DMA指标 | http://wiki.mbalib.com/wiki/DMA DMA指标(Different of Moving Average)又叫平行线差指标,是目前股市分析技术指标中的一种中短期指标,它常用于大盘指数和个股的研判。 DMA, difference of 10 and 50 moving average stock[‘dma’] |
| 15 | DMI,+DI,-DI,DX,ADX,ADXR指标 | http://wiki.mbalib.com/wiki/DMI 动向指数Directional Movement Index,DMI) http://wiki.mbalib.com/wiki/ADX 平均趋向指标(Average Directional Indicator,简称ADX) http://wiki.mbalib.com/wiki/%E5%B9%B3%E5%9D%87%E6%96%B9%E5%90%91%E6%8C%87%E6%95%B0%E8%AF%84%E4%BC%B0 平均方向指数评估(ADXR)实际是今日ADX与前面某一日的ADX的平均值。ADXR在高位与ADX同步下滑,可以增加对ADX已经调头的尽早确认。 ADXR是ADX的附属产品,只能发出一种辅助和肯定的讯号,并非入市的指标,而只需同时配合动向指标(DMI)的趋势才可作出买卖策略。 在应用时,应以ADX为主,ADXR为辅。 |
| 16 | TRIX,MATRIX指标 | http://wiki.mbalib.com/wiki/TRIX TRIX指标又叫三重指数平滑移动平均指标(Triple Exponentially Smoothed Average) |
| 17 | VR,MAVR指标 | http://wiki.mbalib.com/wiki/%E6%88%90%E4%BA%A4%E9%87%8F%E6%AF%94%E7%8E%87 成交量比率(Volumn Ratio,VR)(简称VR),是一项通过分析股价上升日成交额(或成交量,下同)与股价下降日成交额比值, 从而掌握市场买卖气势的中期技术指标。 |
187 changes: 187 additions & 0 deletions docs/02-经典策略/01-股票/量化一-均值策略.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
昨日2020年03月12日时美股历史的第三次熔断,距离上一次熔断03月09号仅3天时间,受全球疫情的影响,股市出现恐慌性抛盘,导致A股也出现较为明显的震荡,A股能否走出独立行情还是不得而知了。

所以我最近学习了一下量化投资的东西,

量化平台Backtrader用起来还不错,A股历史行情数据可从Tushare中获取:

https://www.backtrader.com/www.backtrader.com

```python
# Create a subclass of Strategy to define the indicators and logic
class SmaCross(bt.Strategy):
# list of parameters which are configurable for the strategy
params = dict(
pfast=10, # period for the fast moving average
pslow=30 # period for the slow moving average
)
def __init__(self):
super().__init__()
sma1 = bt.ind.SMA(period=self.p.pfast) # fast moving average
sma2 = bt.ind.SMA(period=self.p.pslow) # slow moving average
self.crossover = bt.ind.CrossOver(sma1, sma2) # crossover signal
def next(self):
if not self.position: # not in the market
if self.crossover > 0: # if fast crosses slow to the upside
self.order_target_size(target=1) # enter long
# self.buy()
elif self.crossover < 0: # in the market & cross to the downside
self.order_target_size(target=0) # close long position
# self.close()

```

这是一个简单的均值策略,当10日均线超过30日均线时买入,30日均线超过10日均线卖出。

```python
data_path = './data/'
if not os.path.exists(data_path):
os.makedirs(data_path)
mytoken='your_token'
class Strategy_runner:
def __init__(self, strategy, ts_code, start_date, end_date, data_path=data_path, pro=False, token=mytoken):
self.ts_code = ts_code
self.start_date = start_date
self.end_date = end_date
# convert to datetime
self.start_datetime = datetime.strptime(start_date,'%Y%m%d')
self.end_datetime = datetime.strptime(end_date,'%Y%m%d')
if pro:
csv_name = f'pro_day_{str(ts_code)}-{str(start_date)}-{str(end_date)}.csv'
else:
csv_name = f'day_{str(ts_code)}-{str(start_date)}-{str(end_date)}.csv'
csv_path = os.path.join(data_path,csv_name)
if os.path.exists(csv_path):
if pro:
self.df = pd.read_csv(csv_path)
else:
self.df = pd.read_csv(csv_path,index_col=0)
else:
if pro:
ts.set_token(mytoken)
self.pro = ts.pro_api()
self.df = self.pro.daily(ts_code=self.ts_code, start_date=self.start_date, end_date=self.end_date)
if not self.df.empty:
self.df.to_csv(csv_path, index=False)
else:
self.df = ts.get_hist_data(self.ts_code, str(self.start_datetime), str(self.end_datetime))
if not self.df.empty:
self.df.to_csv(csv_path, index=True)

self.df_bt = self.preprocess(self.df, pro)
print(self.df_bt)
self.strategy = strategy
self.cerebro = bt.Cerebro()


def preprocess(self, df, pro=False):
if pro:
features=['open','high','low','close','vol','trade_date']
# convert_datetime = lambda x:datetime.strptime(x,'%Y%m%d')
convert_datetime = lambda x: pd.to_datetime(str(x))
df['trade_date'] = df['trade_date'].apply(convert_datetime)
print(df)
bt_col_dict = {'vol':'volume','trade_date':'datetime'}
df = df.rename(columns=bt_col_dict)
df = df.set_index('datetime')
# df.index = pd.DatetimeIndex(df.index)
else:
features=['open','high','low','close','volume']
df = df[features]
df['openinterest'] = 0
df.index = pd.DatetimeIndex(df.index)

df = df[::-1]
return df

def run(self):
data = bt.feeds.PandasData(dataname=self.df_bt,
fromdate=self.start_datetime,
todate=self.end_datetime)
self.cerebro.adddata(data) # Add the data feed
self.cerebro.addstrategy(self.strategy) # Add the trading strategy
self.cerebro.broker.setcash(100000.0)
# self.cerebro.addsizer(bt.sizers.FixedSize, stake=10)
# self.cerebro.broker.setcommission(commission=0.0)
self.cerebro.addanalyzer(bt.analyzers.SharpeRatio,_name = 'SharpeRatio')
self.cerebro.addanalyzer(bt.analyzers.DrawDown, _name='DW')
self.results = self.cerebro.run()
strat = self.results[0]
print('Final Portfolio Value: %.2f' % self.cerebro.broker.getvalue())
print('SR:', strat.analyzers.SharpeRatio.get_analysis())
print('DW:', strat.analyzers.DW.get_analysis())
return self.results

def plot(self, iplot=False):
self.cerebro.plot(iplot=iplot)
```

Tushare有pro版本和普通行情,由于最开始我使用了pro版本但是后面出现了一些连接问题,所以我又写了普通的版本,目前都可以用。

pro:

```python
ts.set_token(mytoken)
self.pro = ts.pro_api()
self.df = self.pro.daily(ts_code=self.ts_code, start_date=self.start_date, end_date=self.end_date)
```

pro版本需要获取token,这个需要你去官网注册之后可以看到的,之后使用daily即可获取日级历史行情。

```python
ts_code='600515.SH'
start_date='20190101'
end_date='20191231'
strategy_runner = Strategy_runner(strategy=SmaCross, ts_code=ts_code, start_date=start_date, end_date=end_date, pro=True)
results = strategy_runner.run()
strategy_runner.plot()
```

以去年为例,传入pro=True,即可使用pro接口,然后获取行情,用均值策略分析

添加策略:

```python
self.cerebro.addstrategy(self.strategy)
```

设置初始资金:

```python
self.cerebro.broker.setcash(100000.0)
```

加入analyzer为获取夏普率和回撤率:

```python
self.cerebro.addanalyzer(bt.analyzers.SharpeRatio,_name = 'SharpeRatio')
self.cerebro.addanalyzer(bt.analyzers.DrawDown, _name='DW')
```
运行模拟策略一遍:

```python
self.cerebro.run()
```

得到分析结果:

```shell
Final Portfolio Value: 100000.29
SR: OrderedDict([('sharperatio', None)])
DW: AutoOrderedDict([('len', 178), ('drawdown', 0.0014899734784627702), ('moneydown', 1.4899999999906868), ('max', AutoOrderedDict([('len', 178), ('drawdown', 0.0019099660025940943), ('moneydown', 1.9099999999889405)]))])
```

因为夏普率默认需要年化的,这里不到一年的数据所以是None。

![image-20200313170814781](C:\Users\todd\AppData\Roaming\Typora\typora-user-images\image-20200313170814781.png)

如果没有token可以直接使用普通接口:

```python
ts_code='600515'
start_date='20190101'
end_date='20191231'
strategy_runner = Strategy_runner(strategy=SmaCross, ts_code=ts_code, start_date=start_date, end_date=end_date, pro=False)
results = strategy_runner.run()
```

如果使用日级行情,其实两者并没有太大的差别,只是表格的列名有点差别。我这里如果第一次获取之后我会在本地存下该表格,后面就不需要网络获取了。
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit b5bc8eb

Please sign in to comment.