forked from fmzquant/strategies
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Zero
committed
Jan 2, 2020
1 parent
0b6c45e
commit 276639d
Showing
93 changed files
with
9,152 additions
and
1,563 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ | |
|
||
> 策略作者 | ||
botvsing | ||
小草 | ||
|
||
> 策略描述 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
|
||
> 策略名称 | ||
8.10 经典恒温器策略 | ||
|
||
> 策略作者 | ||
Hukybo | ||
|
||
> 策略描述 | ||
#### 摘要 | ||
趋势行情不会永远持续下去,事实上市场大部分时间都处于震荡行情,所以才会有人希望能得到一种交易策略,既可以用在趋势行情,也可以用在震荡行情。那么今天我们就用发明者量化交易平台,构建一个趋势和震荡行情通用的经典恒温器策略。 | ||
[点击阅读更多](https://www.fmz.com/bbs-topic/4827) | ||
|
||
|
||
|
||
> 源码 (python) | ||
``` python | ||
'''backtest | ||
start: 2015-02-22 00:00:00 | ||
end: 2019-12-20 00:00:00 | ||
period: 1h | ||
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] | ||
''' | ||
|
||
mp = 0 # 定义一个全局变量,用于控制虚拟持仓 | ||
|
||
# 策略主函数 | ||
def onTick(): | ||
exchange.SetContractType("rb000") # 订阅期货品种 | ||
bar_arr = exchange.GetRecords() # 获取K线数组 | ||
if len(bar_arr) < 100: # 如果K线少于100根 | ||
return # 直接返回 | ||
close0 = bar_arr[-1]['Close'] # 获取最新价格(卖价),用于开平仓 | ||
bar_arr.pop() # 删除K线数组最后一个元素,策略采用开平仓条件成立,下根K线交易模式 | ||
|
||
# 计算CMI指标用以区分震荡市与趋势市 | ||
close1 = bar_arr[-1]['Close'] # 最新收盘价 | ||
close30 = bar_arr[-30]['Close'] # 前30根K线的收盘价 | ||
hh30 = TA.Highest(bar_arr, 30, 'High') # 最近30根K线的最高价 | ||
ll30 = TA.Lowest(bar_arr, 30, 'Low') # 最近30根K线的最低价 | ||
cmi = abs((close1 - close30) / (hh30 - ll30)) * 100 # 计算市场波动指数 | ||
|
||
# 震荡市中收盘价大于关键价格为宜卖市,否则为宜买市 | ||
high1 = bar_arr[-1]['High'] # 最新最高价 | ||
low1 = bar_arr[-1]['Low'] # 最新最低价 | ||
kod = (close1 + high1 + low1) / 3 # 计算关键价格 | ||
if close1 > kod: | ||
be = 1 | ||
se = 0 | ||
else: | ||
be = 0 | ||
se = 1 | ||
|
||
# 计算10根K线ATR指标 | ||
atr10 = TA.ATR(bar_arr, 10)[-1] | ||
|
||
# 定义最高价与最低价3日均线 | ||
high2 = bar_arr[-2]['High'] # 上根K线最高价 | ||
high3 = bar_arr[-3]['High'] # 前根K线最高价 | ||
low2 = bar_arr[-2]['Low'] # 上根K线最低价 | ||
low3 = bar_arr[-3]['Low'] # 前根K线最低价 | ||
avg3high = (high1 + high2 + high3) / 3 # 最近3根K线最高价的均值 | ||
avg3low = (low1 + low2 + low3) / 3 # 最近3根K线最低价的均值 | ||
|
||
# 计算震荡行情的进场价格 | ||
open1 = bar_arr[-1]['Open'] # 最新开盘价 | ||
if close1 > kod: # 如果收盘价大于关键价格 | ||
lep = open1 + atr10 * 3 | ||
sep = open1 - atr10 * 2 | ||
else: | ||
lep = open1 + atr10 * 2 | ||
sep = open1 - atr10 * 3 | ||
lep1 = max(lep, avg3high) # 计算震荡市多头进场价格 | ||
sep1 = min(sep, avg3low) # 计算震荡市空头进场价格 | ||
|
||
# 计算趋势行情的进场价格 | ||
boll = TA.BOLL(bar_arr, 50, 2) | ||
up_line = boll[0][-1] | ||
mid_line = boll[1][-1] | ||
down_line = boll[2][-1] | ||
|
||
global mp # 引入全局变量 | ||
if cmi < 20: # 如果是震荡行情 | ||
if mp == 0 and close1 >= lep1 and se: | ||
exchange.SetDirection("buy") # 设置交易方向和类型 | ||
exchange.Buy(close0, 1) # 开多单 | ||
mp = 1 # 设置虚拟持仓的值,即有多单 | ||
if mp == 0 and close1 <= sep1 and be: | ||
exchange.SetDirection("sell") # 设置交易方向和类型 | ||
exchange.Sell(close0 - 1, 1) # 开空单 | ||
mp = -1 # 设置虚拟持仓的值,即有空单 | ||
if mp == 1 and (close1 >= avg3high or be): | ||
exchange.SetDirection("closebuy") # 设置交易方向和类型 | ||
exchange.Sell(close0 - 1, 1) # 平多单 | ||
mp = 0 # 设置虚拟持仓的值,即空仓 | ||
if mp == -1 and (close1 <= avg3low or se): | ||
exchange.SetDirection("closesell") # 设置交易方向和类型 | ||
exchange.Buy(close0, 1) # 平空单 | ||
mp = 0 # 设置虚拟持仓的值,即空仓 | ||
else: # 如果是趋势行情 | ||
if mp == 0 and close1 >= up_line: | ||
exchange.SetDirection("buy") # 设置交易方向和类型 | ||
exchange.Buy(close0, 1) # 开多单 | ||
mp = 1 # 设置虚拟持仓的值,即有多单 | ||
if mp == 0 and close1 <= down_line: | ||
exchange.SetDirection("sell") # 设置交易方向和类型 | ||
exchange.Sell(close0 - 1, 1) # 开空单 | ||
mp = -1 # 设置虚拟持仓的值,即有空单 | ||
if mp == 1 and close1 <= mid_line: | ||
exchange.SetDirection("closebuy") # 设置交易方向和类型 | ||
exchange.Sell(close0 - 1, 1) # 平多单 | ||
mp = 0 # 设置虚拟持仓的值,即空仓 | ||
if mp == -1 and close1 >= mid_line: | ||
exchange.SetDirection("closesell") # 设置交易方向和类型 | ||
exchange.Buy(close0, 1) # 平空单 | ||
mp = 0 # 设置虚拟持仓的值,即空仓 | ||
|
||
|
||
# 程序入口 | ||
def main(): | ||
while True: # 进入无限循环模式 | ||
onTick() # 执行策略主函数 | ||
Sleep(1000) # 休眠1秒 | ||
|
||
|
||
``` | ||
|
||
> 策略出处 | ||
https://www.fmz.com/strategy/179014 | ||
|
||
> 更新时间 | ||
2019-12-21 17:59:05 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
|
||
> 策略名称 | ||
8.11 菲阿里四价策略 | ||
|
||
> 策略作者 | ||
Hukybo | ||
|
||
> 策略描述 | ||
#### 摘要 | ||
在期货市场,价格呈现一切。几乎所有的技术分析,如均线、布林线、MACD、KDJ等等,这些都是以价格为基础,通过特定的方法计算。包括基本面分析也是如此,通过分析近期和远期价差、期货和现货升贴水、上下游库存等等数据,计算当前价格是否合理,并预估未来的价格。既然如此,为什么不直接研究价格呢?今天我们讲的菲阿里四价策略就是完全根据价格来做出卖决定。 | ||
|
||
[点击阅读更多内容](https://www.fmz.com/bbs-topic/4857) | ||
|
||
|
||
|
||
> 源码 (python) | ||
``` python | ||
# 回测配置 | ||
'''backtest | ||
start: 2015-02-22 00:00:00 | ||
end: 2019-12-26 00:00:00 | ||
period: 5m | ||
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] | ||
''' | ||
|
||
|
||
# 导入库 | ||
import time # 用于转换时间格式 | ||
|
||
|
||
# 策略主函数 | ||
def onTick(): | ||
exchange.SetContractType("rb888") # 订阅期货品种 | ||
bar_arr = _C(exchange.GetRecords, PERIOD_D1) # 获取日线数组 | ||
if len(bar_arr) < 2: # 如果小于2根K线 | ||
return # 返回继续等待数据 | ||
yesterday_high = bar_arr[-2]['High'] # 昨日最高价 | ||
yesterday_low = bar_arr[-2]['Low'] # 昨日最低价 | ||
yesterday_close = bar_arr[-2]['Close'] # 昨日收盘价 | ||
today_open = bar_arr[-1]['Open'] # 当日开盘价 | ||
|
||
bar_arr = _C(exchange.GetRecords) # 获取当前设置周期K线数组 | ||
current_time = bar_arr[-1]['Time'] # 获取当前K线时间戳 | ||
time_local = time.localtime(current_time / 1000) # 处理时间戳 | ||
hour = int(time.strftime("%H", time_local)) # 格式化时间戳,并获取小时 | ||
minute = int(time.strftime("%M", time_local)) # 格式化时间戳,并获取分钟 | ||
current_close = bar_arr[-1]['Close'] # 获取最新价格 | ||
|
||
# 处理时间函数 | ||
def trade_time(hour, minute): | ||
hour = str(hour) | ||
minute = str(minute) | ||
if len(minute) == 1: | ||
minute = "0" + minute | ||
return int(hour + minute) | ||
|
||
# 获取持仓 | ||
real_position = _C(exchange.GetPosition) # 获取持仓数组 | ||
if len(real_position) > 0: # 如果持仓数组长度大于0 | ||
real_position = real_position[0] | ||
if real_position['ContractType'] == 'rb888': # 如果持仓品种等于订阅品种 | ||
if real_position['Type'] == 0 or real_position['Type'] == 2: # 如果是多单 | ||
mp = real_position['Amount'] # 赋值持仓为正数 | ||
elif real_position['Type'] == 1 or real_position['Type'] == 3: | ||
mp = -real_position['Amount'] # 赋值持仓为负数 | ||
else: | ||
mp = 0 # 赋值持仓为0 | ||
|
||
# 设置多头止损 | ||
if today_open / yesterday_high > 1.005: # 如果当天开盘价大于昨天最高价 | ||
long_stop_loss = yesterday_high # 设置多头止损价为昨天最高价 | ||
elif today_open / yesterday_high < 0.995: # 如果当天开盘价小于昨天最高价 | ||
long_stop_loss = today_open # 设置多头止损价为当天开盘价 | ||
else: # 如果当天开盘价接近于昨天最高价 | ||
long_stop_loss = (yesterday_high + yesterday_low) / 2 # 设置多头止损为昨天中间价 | ||
|
||
# 设置空头止损 | ||
if today_open / yesterday_low < 0.995: # 如果当天开盘价小于昨天最低价 | ||
short_stop_loss = yesterday_low # 设置空头止损价为昨天最低价 | ||
elif today_open / yesterday_low > 1.005: # 如果当天开盘价大于昨天最低价 | ||
short_stop_loss = today_open # 设置空头止损价为当天开盘价 | ||
else: # 如果当天开盘价接近于昨天最低价 | ||
short_stop_loss = (yesterday_high + yesterday_low) / 2 # 设置多头止损为昨天中间价 | ||
|
||
# 下单交易 | ||
if mp > 0: # 如果当前持有多单 | ||
if current_close < long_stop_loss or trade_time(hour, minute) > 1450: # 如果当前价格小于多头止损线,或者超过规定的交易时间 | ||
exchange.SetDirection("closebuy") # 设置交易方向和类型 | ||
exchange.Sell(current_close - 1, 1) # 平多单 | ||
if mp < 0: # 如果当前持有空单 | ||
if current_close > short_stop_loss or trade_time(hour, minute) > 1450: # 如果当前价格大于空头止损线,或者超过规定的交易时间 | ||
exchange.SetDirection("closesell") # 设置交易方向和类型 | ||
exchange.Buy(current_close + 1, 1) # 平空单 | ||
if mp == 0 and 930 < trade_time(hour, minute) < 1450: # 如果当前无持仓,并且在规定的交易时间内 | ||
if current_close > yesterday_high: # 如果当前价格大于昨天最高价 | ||
exchange.SetDirection("buy") # 设置交易方向和类型 | ||
exchange.Buy(current_close + 1, 1) # 开多单 | ||
elif current_close < yesterday_low: # 如果价格小于昨天最低价 | ||
exchange.SetDirection("sell") # 设置交易方向和类型 | ||
exchange.Sell(current_close - 1, 1) # 开空单 | ||
|
||
|
||
# 程序入口 | ||
def main(): | ||
while True: # 无限循环 | ||
onTick() # 执行策略主函数 | ||
Sleep(1000) #休眠1秒 | ||
|
||
``` | ||
|
||
> 策略出处 | ||
https://www.fmz.com/strategy/179505 | ||
|
||
> 更新时间 | ||
2019-12-28 15:08:11 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
|
||
> 策略名称 | ||
8.2 自适应动态双均线策略Python版 | ||
|
||
> 策略作者 | ||
Hukybo | ||
|
||
|
||
|
||
> 策略参数 | ||
|
||
|
||
|参数|默认值|描述| | ||
|----|----|----| | ||
|ama_short|50|ama_short| | ||
|ama_long|100|ama_long| | ||
|
||
|
||
> 源码 (python) | ||
``` python | ||
# 回测配置 | ||
'''backtest | ||
start: 2015-02-22 00:00:00 | ||
end: 2019-10-17 00:00:00 | ||
period: 1h | ||
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] | ||
''' | ||
|
||
|
||
# 导入库 | ||
import talib | ||
import numpy as np | ||
|
||
|
||
mp = 0 # 定义一个全局变量,用于控制虚拟持仓 | ||
|
||
|
||
# 把K线数组转换成收盘价数组,用于计算AMA的值 | ||
def get_close(r): | ||
arr = [] | ||
for i in r: | ||
arr.append(i['Close']) | ||
return arr | ||
|
||
|
||
# 判断AMA是否上升 | ||
def is_up(arr): | ||
arr_len = len(arr) | ||
if arr[arr_len - 1] > arr[arr_len - 2] and arr[arr_len - 2] > arr[arr_len - 3]: | ||
return True | ||
|
||
|
||
# 判断AMA是否下降 | ||
def is_down(arr): | ||
arr_len = len(arr) | ||
if arr[arr_len - 1] < arr[arr_len - 2] and arr[arr_len - 2] < arr[arr_len - 3]: | ||
return True | ||
|
||
|
||
# 判断两根AMA是否金叉 | ||
def is_up_cross(arr1, arr2): | ||
if arr1[len(arr1) - 2] < arr2[len(arr2) - 2] and arr1[len(arr1) - 1] > arr2[len(arr2) - 1]: | ||
return True | ||
|
||
# 判断两根AMA是否死叉 | ||
def is_down_cross(arr1, arr2): | ||
if arr1[len(arr1) - 2] > arr2[len(arr2) - 2] and arr1[len(arr1) - 1] < arr2[len(arr2) - 1]: | ||
return True | ||
|
||
|
||
# 程序主函数 | ||
def onTick(): | ||
exchange.SetContractType("rb000") # 订阅期货品种 | ||
bar_arr = exchange.GetRecords() # 获取K线数组 | ||
if len(bar_arr) < ama_long: # 判断K线数组的长度,如果小于参数ama_long就不能计算AMA,所以直接返回跳过 | ||
return | ||
close_arr = get_close(bar_arr) # 把K线数组转换成收盘价数组,用于计算AMA的值 | ||
np_close_arr = np.array(close_arr) # 把列表转换为numpy.array,用于计算AMA的值 | ||
ama1 = talib.KAMA(np_close_arr, ama_short).tolist() # 计算短期AMA | ||
ama2 = talib.KAMA(np_close_arr, ama_long).tolist() # 计算长期AMA | ||
last_close = close_arr[len(close_arr) - 1] # 获取最新价格(卖价),用于开平仓 | ||
global mp # 全局变量,用于控制虚拟持仓 | ||
|
||
# 开多单 | ||
if mp == 0 and is_up_cross(ama1, ama2) and is_up(ama1): | ||
exchange.SetDirection("buy") # 设置交易方向和类型 | ||
exchange.Buy(last_close, 1) # 开多单 | ||
mp = 1 # 设置虚拟持仓的值,即有多单 | ||
|
||
# 开空单 | ||
if mp == 0 and is_down_cross(ama1, ama2) and is_down(ama1): | ||
exchange.SetDirection("sell") # 设置交易方向和类型 | ||
exchange.Sell(last_close - 1, 1) # 开空单 | ||
mp = -1 # 设置虚拟持仓的值,即有空单 | ||
|
||
# 平多单 | ||
if mp == 1 and (is_down_cross(ama1, ama2) or is_down(ama1)): | ||
exchange.SetDirection("closebuy") # 设置交易方向和类型 | ||
exchange.Sell(last_close - 1, 1) # 平多单 | ||
mp = 0 # 设置虚拟持仓的值,即空仓 | ||
|
||
# 平空单 | ||
if mp == -1 and (is_up_cross(ama1, ama2) or is_up(ama1)): | ||
exchange.SetDirection("closesell") # 设置交易方向和类型 | ||
exchange.Buy(last_close, 1) # 平空单 | ||
mp = 0 # 设置虚拟持仓的值,即空仓 | ||
|
||
|
||
def main(): | ||
while True: | ||
onTick() | ||
Sleep(1000) | ||
|
||
``` | ||
|
||
> 策略出处 | ||
https://www.fmz.com/strategy/170551 | ||
|
||
> 更新时间 | ||
2019-12-28 17:11:31 |
Oops, something went wrong.