Files
obsidian-vault/05 投资交易/自己造了个轮子.md
2026-06-23 00:24:32 +08:00

8.6 KiB
Raw Permalink Blame History

#策略研究 #量化交易 #邢不行B圈量化 #Python学习

经过较为充实的一个半月,我通过邢不行B圈量化课程学习了Python基础、pandas基础以及选股框架的使用在选股框架下跑出了一些回测甚至还跑出了不小的超额收益。但正如我在有交易框架,也要自己从头把轮子造一遍中所提到的那样:

!有交易框架,也要自己从头把轮子造一遍#^275955

我还没有入门,只是学会了某种路径依赖下的某种工具而已。起码在当时是这样的。我自己关于策略的构想,对于代码的应用在那个时候远远称不上入门,也没有实践。在随后的路上,我的主要工作还会是依赖于框架这一点我是坚信的。但是自己的基础夯实也是刻不容缓的。

因此,我坚定的朝造自己的轮子这一方向而努力。长时间的深入思考,才有可能灵光一闪中有具体阐述。经过自己创造出的脚本目前实现了从数据获取、数据整理、交易所API通信、ta指标计算、条件下单的完整小模型已实现最小化运行。甚至可以说是一个小的择时框架。

在此基础上,可以添加任意指标(现阶段已实现开高收低量计算出的一系列指标),可以加入多时间框架,下一步写通回测代码之后,还可以基于历史数据进行策略的回测。或者结合选股框架,选出符合筛选条件的投资标的后转入择时则略,通过买卖条件执行交易。

宏观的讲,选币框架有了,择时策略的框子搭出来了,下下功夫就可以写出一个可以实盘运行的策略了。基础设置的搭建算是有了方向,仍需精进努力。我的目标,是把编程和框架应用熟悉到毫不费力就能写出自己的策略的程度,现在还远远不够。

下一步一是完善这个脚本使用布林带和RSI在1倍杠杆的情况下对选定币种进行交易。需要完善移动止损、订单追踪和平仓功能。目前还是一种下单就丢的状态或者可以下止盈止损订单但是下过之后没有更改滚动的功能。二是在其中加入adx、atr等指标进行过滤减少交易风险。三是编写完成后利用纯代码而不是框架进行回测要实现基本的盈利。四是最终投入服务器实盘运行没有别的重大因素的干扰保持长期运行。五是根据系统自己下单订单进行跟踪复盘为下一步构建自己能长期稳定运行的策略打好基础。

对于多时间框架中趋势、K线形态的分析在这个脚本部署之后进行重点研究。研究完成后对现有策略进行更新使其更加结合趋势或区间进行交易。

再之后对backtrader框架进行研究读读说明文档看看社区提升自己利用框架进行交易的能力最终我想要的是一种随心所欲这是现阶段邢不行课程的选股框架给不了我的。

代码如下:

  
import time  
import pandas as pd  
import ccxt  
from datetime import timedelta  
import pandas_ta  
import talib  
  
# ====================================================================================================  
# =====格式设置  
# ====================================================================================================  
pd.set_option('display.max_rows', 1000)  
pd.set_option('expand_frame_repr', False)  # 当列太多时不换行  
# 设置命令行输出时的列对齐功能  
pd.set_option('display.unicode.ambiguous_as_wide', True)  
pd.set_option('display.unicode.east_asian_width', True)  
  
# ====================================================================================================  
# =====创建ccxt交易所  
# ====================================================================================================  
BINANCE_CONFIG = {  
                    'apiKey': '',  
                    'secret': '',  
                    'proxies': {'http': '127.0.0.1:33210', 'https': '127.0.0.1:33210'}  
                  }  
exchange = ccxt.binance(BINANCE_CONFIG)  
  
# list = ['DOGEUSDT', 'ETHUSDT', 'BTCUSDT']  
#  
# # for symbol in list:  
symbol = 'ETHUSDT'  
time_interval = '1m'  # 其他可以尝试的值:'1m', '5m', '15m', '30m', '1h', '2h', '1d', '1w', '1M', '1y',并不是每个交易所都支持  
bar_num = 1000  # 获取K线的数量  
params = {'symbol': symbol,  # 交易币对  
              'interval': time_interval,  # 时间间隔  
              'limit': bar_num}  # 数据条数  
  
# ====================================================================================================  
# =====获取K线数据  
# ====================================================================================================  
response = exchange.fapiPublicGetKlines(params=params)  
k_lines = pd.DataFrame(response)  
# print(k_lines)  
  
# =====整理K线数据  
df = pd.DataFrame(response, dtype=float)  # 将数据转换为dataframe  
df.rename(columns={0: 'MTS', 1: 'Open', 2: 'High',  
                   3: 'Low', 4: 'Close', 5: 'Volume'}, inplace=True)  # 重命名  
df['candle_begin_time'] = pd.to_datetime(df['MTS'], unit='ms')  # 整理时间  
df['candle_begin_time_GMT8'] = df['candle_begin_time'] + timedelta(hours=8)  # 北京时间  
df = df[['candle_begin_time_GMT8', 'Open', 'High', 'Low', 'Close', 'Volume']]  # 整理列的顺序  
  
  
# ====================================================================================================  
# =====获取币对的最新价格  
# ====================================================================================================  
data = exchange.fapiPublicGetTickerPrice(params={'symbol': "ETHUSDT"})  
price_ETH = data['price']  
  
# ====================================================================================================  
# =====通过pandas-ta计算指标并加入相关指标计算列  
# ====================================================================================================  
df.ta.sma(length=5, append=True, col_names="SMA_5") # 计算SM5指标  
# 计算14日相对强弱指数RSI  
df.ta.rsi(length=14, append=True, col_names="RSI_14")  # [4,5](@ref)  
# 计算MACD12/26/9周期  
df.ta.macd(fast=12, slow=26, signal=9, append=True)  # 默认列名MACD_12_26_9, MACDs_12_26_9, MACDh_12_26_9 [2,7](@ref)  
# 计算布林带20日2倍标准差  
df.ta.bbands(length=20, std=2, append=True)  # 默认列名BBL_20_2.0, BBM_20_2.0, BBU_20_2.0 [5,8](@ref)  
  
  
# ====================================================================================================  
# =====设置下单条件并执行  
# ====================================================================================================  
# if float(price_ETH) > float(df['Close'].iloc[-2]):  
#     print('价格上升')  
# else:  
#     print('价格下降')  
#  
# print(price_ETH)  
# print(df['Close'].iloc[-2])  
# print(df['RSI_14'].iloc[-2] > 30)  
  
# 以上为dataframe取数格式的测试目前使用还不太熟练  
  
## 调整杠杆倍率  
params = {'symbol': 'ETHUSDT',  # 交易币对  
          'leverage': 1,  
          'timestamp': int(time.time() * 1000)}  
leverage = exchange.fapiPrivatePostLeverage(params=params)  
print('调整开仓杠杆\n', leverage, '\n')  
  
  
  
## 下单操作  
num = 0  
max_num = 2  
# 使用变量来控制下单次数  
  
params = {'side': 'BUY',  
          'symbol': 'ETHUSDT',  # 交易币对  
          'type': 'LIMIT',  
          'price': price_ETH,  
          # 下单价格,在限价单的时候启用将type换成LIMIT  
          # 此处用变量取代了课程中的数值。以后下单的价格可能需要复杂计算再储存在变量中,做测试。  
          'quantity': 0.01,  # 下单数量  
          'timestamp': int(time.time() * 1000),  
          'timeInForce': 'GTC'} # https://academy.binance.com/zh/articles/understanding-the-different-order-types  
  
while True:  
    if df['RSI_14'].iloc[-2] > 30 and df['RSI_14'].iloc[-1] < 30:  
        print('向下穿越rsi30执行买入')  
        response = exchange.fapiPrivatePostOrder(params=params)  
        order_info = pd.DataFrame(response, index=['symbol'])  
        order_id = order_info['orderId'].iloc[0]  
        print('下单\n', order_info, '\n')  
        num += 1  
        # 此后这里还可以多个条件,组合多个指标的值  
        # RSI的使用作为一个参考  
        # 通过现有数据(开高收低量),已经可以计算出不少指标了。  
  
    else:  
        print('不符合交易条件,监控中')  
        time.sleep(5)  
  
    if num >= max_num:  
        break