
等级: 新手上路
- 注册:
- 2022-11-12
- 曾用名:
|
完整策略代码:
# 凡是不涉及数据重复获取调用的功能,都考虑用函数封装。
from PythonApi import *
import pandas as pd
import numpy as np
import sqlite3
import talib
import datetime
import easygui as eg
###########################################################################
# 参数定义区
def parameter():
input_par("BS", 1, -1, 1, 2) # 买卖方向(1=多, -1=空)
input_par("Rmax", 5000, 1000, 50000, 1000) # 单笔最大风险
input_par("BuyPrice", 0, 0, 500000, 10) # 指定入场价
input_par("SellPrice", 500000, 100, 100, -10) # 指定入场价
input_par("Pmaxloss", 0, 0, 1000, 10) # 单笔最大风险
input_par("Pexitpower", 0, 0, 10, 1) # 单笔最大风险
# 全局变量定义
def init(context):
# 数据库连接
context.conn = sqlite3.connect(r'e:\db\invest.db')
context.s1 = context.run_info.base_book_id
context.AllowBuy = 1
context.AllowSell = 1
context.buy_count = 0
context.sell_count = 0
context.buy_vol = 0
context.sell_vol = 0
context.max_high = 0
context.min_low = float('inf')
# 策略状态变量
context.position = 0 # 当前持仓量
context.entry_price = 0 # 开仓价格
context.entry_time = None # 开仓时间
context.max_high = 0 # 多头最高点
context.min_low = float('inf')# 空头最低点,设为无穷大,确保任何实际价格都会更新这个值。
context.trade_count = 0 # 交易计数
context.last_asn = 0 # 上次ASN值
context.add_times = 0 # 加仓次数
context.open_contracts = 0 # 开仓合约数
# 加载合约信息
context.contract = context.run_info.base_book_id # 基准合约
context.multiplier = get_instruments (context.contract).multipliter
context.margin_ratio = get_instruments (context.contract).buy_margin_rate / 100
# 初始化账户信息
context.total_funds = get_account(6) # 动态权益
context.available_funds = get_account(19) # 可用资金
# 设置定时任务
# settimer(check_market_data, 60000) # 每分钟检查一次
# settimer(update_account_info, 60000) # 每分钟更新账户信息
context.mulBoxWave = 4
# 日志初始化
# log_debug_info('strategy_init.txt', f"策略初始化完成: {datetime.datetime.now()}")
print("现在开始本轮交易!")
# 订单状态回调
def order_status(context, order):
if order.status == 'filled':
log_debug_info('order_status.txt', f"订单成交: {order.order_id}, 价格: {order.trade_price}, 数量: {order.filled_quantity}")
print('order_status.txt', f"订单成交: {order.order_id}, 价格: {order.trade_price}, 数量: {order.filled_quantity}")
# 更新账户信息
context.total_funds = get_account(6)
context.available_funds = get_account(19)
# 主处理函数
def handle_bar(context):
##################################################################
# P1: 基本数据准备
open = history_bars(context.s1, 500, 'self', 'open',True)
high = history_bars(context.s1, 500, 'self', 'high',True)
low = history_bars(context.s1, 500, 'self', 'low',True)
close = history_bars(context.s1, 500, 'self', 'close',True)
BKprice =0
SKprice =0
# 更新最高点/最低点
if context.BS == 1 and high[-1] > context.max_high:
context.max_high = high[-1]
elif context.BS == -1 and low[-1] < context.min_low:
context.min_low = low[-1]
# P2: 计算仓位//移到init?
tr = talib.TRANGE(high,low,close)
atr = talib.SMA(tr[1:],20)
if context.Pmaxloss == 0:
trueMaxloss = atr[-2]
else:
trueMaxloss = context.Pmaxloss
Ulot = int(context.Rmax / (trueMaxloss * get_dynainf(context.s1,209)))
# P3: 计算交易信号
if context.BS == 1:
# 多头开仓信号
if context.BuyPrice ==0 and Ulot > 0 and context.buy_count == 0:
context.buy_vol = Ulot
strResult = buy_open(context.s1, "Market", 0, Ulot,serial_id = 1)
context.buy_count = 1
BKprice = close[-1]
print("当前合约:" + context.s1 + ";操作:" + "市价开仓" + ";开仓价:"+str(close[-1]) + ";仓量:" + str(Ulot) )
if context.BuyPrice > 0 and context.BuyPrice < close[-1] and Ulot > 0 and context.buy_count == 0:
context.buy_vol = Ulot
strResult = buy_open(context.s1, "Limit", context.BuyPrice, Ulot,serial_id = 2)
context.buy_count = 1
BKprice = context.BuyPrice
print("当前合约:" + context.s1 + ";操作:" + "限价开仓" + ";开仓价:"+str(close[-1]) + ";仓量:" + str(Ulot) )
# 多头加仓信号
if context.buy_count == 1 and close[-1] > BKprice + trueMaxloss:
context.buy_vol = context.buy_vol + int(Ulot/2)
strResult = buy_open(context.s1, "Market", 0, int(Ulot/2),serial_id = 3)
context.buy_count = 2
print("当前合约:" + context.s1 + ";操作:" + "加仓1次" + ";开仓价:"+str(close[-1]) + ";仓量:" + str(int(Ulot/2)) )
if context.buy_count == 2 and close[-1] > BKprice + trueMaxloss*2:
context.buy_vol = context.buy_vol + int(Ulot/2)
strResult = buy_open(context.s1, "Market", 0, int(Ulot/2),serial_id = 4)
context.buy_count = 3
print("当前合约:" + context.s1 + ";操作:" + "加仓2次" + ";开仓价:"+str(close[-1]) + ";仓量:" + str(int(Ulot/2)) )
if context.BS == 1 and context.buy_count >= 1:
# 多头平仓信号1:价格达到平仓价
if (context.Pexitpower >0 and close[-1] >= BKprice + context.Pexitpower * trueMaxloss):
buy_close(context.s1, "Market", 0, context.buy_vol,serial_id = 5)
context.buy_count = 0
print("当前合约:" + context.s1 + ";操作:" + "市价平仓" + ";平仓价:"+str(close[-1]) + ";仓量:" + str(context.buy_vol) )
# 多头平仓信号2:价格回撤
if (context.max_high - close[-1] >= trueMaxloss):
buy_close(context.s1, "Market", 0, context.buy_vol,serial_id = 6)
context.buy_count = 0
print("当前合约:" + context.s1 + ";操作:" + "回撤平仓" + ";平仓价:"+str(close[-1]) + ";仓量:" + str(context.buy_vol) )
# 多头平仓信号3:持仓时间和盈利条件
if context.entry_time:
holding_days = (context.now - context.entry_time).days
if (holding_days >= 20 and close[-1] > BKprice) or holding_days >= 30: # close[-1] > BKprice 并不能保证盈利,后改!
buy_close(context.s1, "Market", 0, context.buy_vol,serial_id = 7)
context.buy_count = 0
print("当前合约:" + context.s1 + ";操作:" + "时间平仓" + ";平仓价:"+str(close[-1]) + ";仓量:" + str(context.buy_vol) )
if context.BS == -1:
# 空头开仓信号
if context.SellPrice == 500000 and Ulot > 0 and context.sell_count == 0:
context.sell_vol = Ulot
sell_open(context.s1, "Market", 0, Ulot,serial_id = 8)
context.sell_count = 1
SKprice = close[-1]
print("当前合约:" + context.s1 + ";操作:" + "市价开仓" + ";开仓价:"+str(close[-1]) + ";仓量:" + str(Ulot) )
if context.SellPrice <500000 and context.SellPrice > close[-1] and Ulot > 0 and context.sell_count == 0:
context.sell_vol = Ulot
sell_open(context.s1, "Limit", context.SellPrice, Ulot,serial_id = 9)
context.sell_count = 1
SKprice = context.SellPrice
print("当前合约:" + context.s1 + ";操作:" + "限价开仓" + ";开仓价:"+str(close[-1]) + ";仓量:" + str(Ulot) )
# 空头加仓信号
if context.sell_count == 1 and close[-1] < SKprice - trueMaxloss:
context.sell_vol = context.sell_vol + int(Ulot/2)
sell_open(context.s1, "Market", 0, int(Ulot/2),serial_id = 10)
context.sell_count = 2
print("当前合约:" + context.s1 + ";操作:" + "加仓1次" + ";开仓价:"+str(close[-1]) + ";仓量:" + str(int(Ulot/2)) )
if context.sell_count == 2 and close[-1] < SKprice - trueMaxloss*2:
context.sell_vol = context.sell_vol + int(Ulot/2)
sell_open(context.s1, "Market", 0, int(Ulot/2),serial_id = 11)
context.sell_count = 3
print("当前合约:" + context.s1 + ";操作:" + "加仓2次" + ";开仓价:"+str(close[-1]) + ";仓量:" + str(int(Ulot/2)) )
if context.BS == -1 and context.sell_count >= 1:
# 空头平仓信号1:价格达到平仓价
print("context.Pexitpower:"+context.Pexitpower+";close[-1]:"+close[-1]+";SKprice:"+SKprice+";context.Pexitpower:"+context.Pexitpower+";trueMaxloss:"+trueMaxloss)
if (context.Pexitpower >0 and close[-1] <= (SKprice - context.Pexitpower * trueMaxloss)):
sell_close(context.s1, "Market", 0, context.sell_vol,serial_id = 12)
context.sell_count = 0
print("当前合约:" + context.s1 + ";操作:" + "市价平仓" + ";平仓价:"+str(close[-1]) + ";仓量:" + str(context.sell_vol) )
# 空头平仓信号2:价格回撤
if (close[-1] - context.Min_low >= trueMaxloss):
sell_close(context.s1, "Market", 0, context.sell_vol,serial_id = 13)
context.sell_count = 0
print("当前合约:" + context.s1 + ";操作:" + "回撤平仓" + ";平仓价:"+str(close[-1]) + ";仓量:" + str(context.sell_vol) )
# 空头平仓信号3:持仓时间和盈利条件
if context.entry_time:
holding_days = (context.now - context.entry_time).days
if (holding_days >= 20 and close[-1] < SKprice) or holding_days >= 30:
sell_close(context.s1, "Market", 0, context.sell_vol,serial_id = 14)
context.sell_count = 0
print("当前合约:" + context.s1 + ";操作:" + "时间平仓" + ";平仓价:"+str(close[-1]) + ";仓量:" + str(context.sell_vol) )
portfolio = get_portfolio(context.s1,0)
buy_vol=portfolio.buy_quantity
sell_vol=portfolio.sell_quantity
# 策略退出处理
def exit(context):
# 撤销所有未成交订单
orders = get_orders('pending', 0)
for order in orders:
cancel_order(order.order_id)
# 关闭数据库连接
context.conn.close()
killtimer(check_market_data)
killtimer(update_account_info)
log_debug_info('strategy_exit.txt', f"策略退出: {datetime.datetime.now()}") |
|