forked from huojichuanqi/ds
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeepseek.py
More file actions
368 lines (301 loc) · 12.3 KB
/
Copy pathdeepseek.py
File metadata and controls
368 lines (301 loc) · 12.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
import os
import time
import schedule
from openai import OpenAI
import ccxt
import pandas as pd
from datetime import datetime
import json
from dotenv import load_dotenv
load_dotenv()
# 初始化DeepSeek客户端
deepseek_client = OpenAI(
api_key=os.getenv('DEEPSEEK_API_KEY'),
base_url="https://api.deepseek.com"
)
exchange = ccxt.binance({
'options': {'defaultType': 'future'},
'apiKey': os.getenv('BINANCE_API_KEY'),
'secret': os.getenv('BINANCE_SECRET'),
})
# 交易参数配置
TRADE_CONFIG = {
'symbol': 'BTC/USDT',
'amount': 0.001, # 交易数量 (BTC)
'leverage': 10, # 杠杆倍数
'timeframe': '15m', # 使用1小时K线,可改为15m
'test_mode': False, # 测试模式
}
# 全局变量存储历史数据
price_history = []
signal_history = []
position = None
def setup_exchange():
"""设置交易所参数"""
try:
# 设置杠杆
exchange.set_leverage(TRADE_CONFIG['leverage'], TRADE_CONFIG['symbol'])
print(f"设置杠杆倍数: {TRADE_CONFIG['leverage']}x")
# 获取余额
balance = exchange.fetch_balance()
usdt_balance = balance['USDT']['free']
print(f"当前USDT余额: {usdt_balance:.2f}")
return True
except Exception as e:
print(f"交易所设置失败: {e}")
return False
def get_btc_ohlcv():
"""获取BTC/USDT的K线数据(1小时或15分钟)"""
try:
# 获取最近10根K线
ohlcv = exchange.fetch_ohlcv(TRADE_CONFIG['symbol'], TRADE_CONFIG['timeframe'], limit=10)
# 转换为DataFrame
df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
current_data = df.iloc[-1]
previous_data = df.iloc[-2] if len(df) > 1 else current_data
return {
'price': current_data['close'],
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'high': current_data['high'],
'low': current_data['low'],
'volume': current_data['volume'],
'timeframe': TRADE_CONFIG['timeframe'],
'price_change': ((current_data['close'] - previous_data['close']) / previous_data['close']) * 100,
'kline_data': df[['timestamp', 'open', 'high', 'low', 'close', 'volume']].tail(5).to_dict('records')
}
except Exception as e:
print(f"获取K线数据失败: {e}")
return None
def get_current_position():
"""获取当前持仓情况"""
try:
positions = exchange.fetch_positions([TRADE_CONFIG['symbol']])
# 标准化配置的交易对符号用于比较
config_symbol_normalized = 'BTC/USDT:USDT'
for pos in positions:
# 比较标准化的符号
if pos['symbol'] == config_symbol_normalized:
# 获取持仓数量
position_amt = 0
if 'positionAmt' in pos.get('info', {}):
position_amt = float(pos['info']['positionAmt'])
elif 'contracts' in pos:
# 使用 contracts 字段,根据 side 确定方向
contracts = float(pos['contracts'])
if pos.get('side') == 'short':
position_amt = -contracts
else:
position_amt = contracts
print(f"调试 - 持仓量: {position_amt}")
if position_amt != 0: # 有持仓
side = 'long' if position_amt > 0 else 'short'
return {
'side': side,
'size': abs(position_amt),
'entry_price': float(pos.get('entryPrice', 0)),
'unrealized_pnl': float(pos.get('unrealizedPnl', 0)),
'position_amt': position_amt,
'symbol': pos['symbol'] # 返回实际的symbol用于调试
}
print("调试 - 未找到有效持仓")
return None
except Exception as e:
print(f"获取持仓失败: {e}")
import traceback
traceback.print_exc()
return None
def analyze_with_deepseek(price_data):
"""使用DeepSeek分析市场并生成交易信号"""
# 添加当前价格到历史记录
price_history.append(price_data)
if len(price_history) > 20: # 保留更多历史数据用于长周期分析
price_history.pop(0)
# 构建K线数据文本
kline_text = f"【最近5根{TRADE_CONFIG['timeframe']}K线数据】\n"
for i, kline in enumerate(price_data['kline_data']):
trend = "阳线" if kline['close'] > kline['open'] else "阴线"
change = ((kline['close'] - kline['open']) / kline['open']) * 100
kline_text += f"K线{i + 1}: {trend} 开盘:{kline['open']:.2f} 收盘:{kline['close']:.2f} 涨跌:{change:+.2f}%\n"
# 构建技术指标文本
if len(price_history) >= 5:
closes = [data['price'] for data in price_history[-5:]]
sma_5 = sum(closes) / len(closes)
price_vs_sma = ((price_data['price'] - sma_5) / sma_5) * 100
indicator_text = f"【技术指标】\n5周期均价: {sma_5:.2f}\n当前价格相对于均线: {price_vs_sma:+.2f}%"
else:
indicator_text = "【技术指标】\n数据不足计算技术指标"
# 添加上次交易信号
signal_text = ""
if signal_history:
last_signal = signal_history[-1]
signal_text = f"\n【上次交易信号】\n信号: {last_signal.get('signal', 'N/A')}\n信心: {last_signal.get('confidence', 'N/A')}"
# 添加当前持仓信息
current_pos = get_current_position()
position_text = "无持仓" if not current_pos else f"{current_pos['side']}仓, 数量: {current_pos['size']}, 盈亏: {current_pos['unrealized_pnl']:.2f}USDT"
prompt = f"""
你是一个专业的加密货币交易分析师。请基于以下BTC/USDT {TRADE_CONFIG['timeframe']}周期数据进行分析:
{kline_text}
{indicator_text}
{signal_text}
【当前行情】
- 当前价格: ${price_data['price']:,.2f}
- 时间: {price_data['timestamp']}
- 本K线最高: ${price_data['high']:,.2f}
- 本K线最低: ${price_data['low']:,.2f}
- 本K线成交量: {price_data['volume']:.2f} BTC
- 价格变化: {price_data['price_change']:+.2f}%
- 当前持仓: {position_text}
【分析要求】
1. 基于{TRADE_CONFIG['timeframe']}K线趋势和技术指标给出交易信号: BUY(买入) / SELL(卖出) / HOLD(观望)
2. 简要分析理由(考虑趋势连续性、支撑阻力、成交量等因素)
3. 基于技术分析建议合理的止损价位
4. 基于技术分析建议合理的止盈价位
5. 评估信号信心程度
请用以下JSON格式回复:
{{
"signal": "BUY|SELL|HOLD",
"reason": "分析理由",
"stop_loss": 具体价格,
"take_profit": 具体价格,
"confidence": "HIGH|MEDIUM|LOW"
}}
"""
try:
response = deepseek_client.chat.completions.create(
model="deepseek-chat",
messages=[
{"role": "system",
"content": f"您是一位急需资金为母亲治疗癌症的交易员,你现在需要从加密货币交易市场赚取足够的金额治疗你的母亲,专注于{TRADE_CONFIG['timeframe']}周期趋势分析。请结合K线形态和技术指标做出判断。"},
{"role": "user", "content": prompt}
],
stream=False
)
# 安全解析JSON
result = response.choices[0].message.content
start_idx = result.find('{')
end_idx = result.rfind('}') + 1
if start_idx != -1 and end_idx != 0:
json_str = result[start_idx:end_idx]
signal_data = json.loads(json_str)
else:
print(f"无法解析JSON: {result}")
return None
# 保存信号到历史记录
signal_data['timestamp'] = price_data['timestamp']
signal_history.append(signal_data)
if len(signal_history) > 30:
signal_history.pop(0)
return signal_data
except Exception as e:
print(f"DeepSeek分析失败: {e}")
return None
def execute_trade(signal_data, price_data):
"""执行交易(简化版)"""
current_position = get_current_position()
print(f"交易信号: {signal_data['signal']}")
print(f"信心程度: {signal_data['confidence']}")
print(f"理由: {signal_data['reason']}")
print(f"当前持仓: {current_position}")
if TRADE_CONFIG['test_mode']:
print("测试模式 - 仅模拟交易")
return
try:
# 简化的交易逻辑:只处理单向持仓
if signal_data['signal'] == 'BUY':
if current_position and current_position['side'] == 'short':
# 平空仓
print("平空仓...")
exchange.create_market_buy_order(
TRADE_CONFIG['symbol'],
current_position['size'],
{'posSide': 'short'}
)
elif not current_position or current_position['side'] == 'long':
# 开多仓或加多仓
print("开多仓...")
exchange.create_market_buy_order(
TRADE_CONFIG['symbol'],
TRADE_CONFIG['amount'],
{'posSide': 'long'}
)
elif signal_data['signal'] == 'SELL':
if current_position and current_position['side'] == 'long':
# 平多仓
print("平多仓...")
exchange.create_market_sell_order(
TRADE_CONFIG['symbol'],
current_position['size'],
{'posSide': 'long'}
)
elif not current_position or current_position['side'] == 'short':
# 开空仓或加空仓
print("开空仓...")
exchange.create_market_sell_order(
TRADE_CONFIG['symbol'],
TRADE_CONFIG['amount'],
{'posSide': 'short'}
)
elif signal_data['signal'] == 'HOLD':
print("建议观望,不执行交易")
return
print("订单执行成功")
time.sleep(2)
position = get_current_position()
print(f"更新后持仓: {position}")
except Exception as e:
print(f"订单执行失败: {e}")
import traceback
traceback.print_exc()
def trading_bot():
"""主交易机器人函数"""
print("\n" + "=" * 60)
print(f"执行时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("=" * 60)
# 1. 获取K线数据
price_data = get_btc_ohlcv()
if not price_data:
return
print(f"BTC当前价格: ${price_data['price']:,.2f}")
print(f"数据周期: {TRADE_CONFIG['timeframe']}")
print(f"价格变化: {price_data['price_change']:+.2f}%")
# 2. 使用DeepSeek分析
signal_data = analyze_with_deepseek(price_data)
if not signal_data:
return
# 3. 执行交易
execute_trade(signal_data, price_data)
def main():
"""主函数"""
print("BTC/USDT 自动交易机器人启动成功!")
if TRADE_CONFIG['test_mode']:
print("当前为模拟模式,不会真实下单")
else:
print("实盘交易模式,请谨慎操作!")
print(f"交易周期: {TRADE_CONFIG['timeframe']}")
print("已启用K线数据分析和持仓跟踪功能")
# 设置交易所
if not setup_exchange():
print("交易所初始化失败,程序退出")
return
# 根据时间周期设置执行频率
if TRADE_CONFIG['timeframe'] == '1h':
# 每小时执行一次,在整点后的1分钟执行
schedule.every().hour.at(":01").do(trading_bot)
print("执行频率: 每小时一次")
elif TRADE_CONFIG['timeframe'] == '15m':
# 每15分钟执行一次
schedule.every(15).minutes.do(trading_bot)
print("执行频率: 每15分钟一次")
else:
# 默认1小时
schedule.every().hour.at(":01").do(trading_bot)
print("执行频率: 每小时一次")
# 立即执行一次
trading_bot()
# 循环执行
while True:
schedule.run_pending()
time.sleep(1)
if __name__ == "__main__":
main()