def __init__(self, instrument_id, time_frame, start_asset): # 策略初始化时需传入合约id、k线周期、初始资金参数 print("{} {} 海龟交易策略已启动!".format(get_localtime(), instrument_id)) # 程序启动时打印提示信息 config.loads("config.json") # 载入配置文件 self.instrument_id = instrument_id # 合约id self.time_frame = time_frame # k线周期 self.exchange = OKEXFUTURES(config.access_key, config.secret_key, config.passphrase, self.instrument_id, leverage=20) # 初始化交易所 self.market = MARKET(self.exchange, self.instrument_id, self.time_frame) # 初始化market self.position = POSITION(self.exchange, self.instrument_id, self.time_frame) # 初始化position self.indicators = INDICATORS(self.exchange, self.instrument_id, self.time_frame) # 初始化indicators self.database = "回测" # 如从purequant服务器的数据库上获取历史k线数据进行回测,必须为"回测" self.datasheet = self.instrument_id.split("-")[0].lower() + "_" + time_frame # 数据表 if config.first_run == "true": # 程序第一次启动时保存数据,实盘时如策略中止再重启时,可以将配置文件中的first_run改成"false",程序再次启动会直接读取数据库中保存的数据 storage.mysql_save_strategy_run_info(self.database, self.datasheet, get_localtime(), "none", 0, 0, 0, 0, "none", 0, 0, 0, start_asset) # 读取数据库中保存的总资金、总盈亏数据 self.total_asset = storage.read_mysql_datas(0, self.database, self.datasheet, "总资金", ">")[-1][-1] self.total_profit = storage.read_mysql_datas(0, self.database, self.datasheet, "总资金", ">")[-1][-2] # 策略总盈亏 # 一些策略参数 self.contract_value = self.market.contract_value() # 合约面值 self.ATRLength = 20 # 平均波动周期 self.boLength = 20 # 短周期 BreakOut Length self.fsLength = 55 # 长周期 FailSafe Length self.teLength = 10 # 离市周期 Trailing Exit Length self.LastProfitableTradeFilter = 1 # 使用入市过滤条件 self.PreBreakoutFailure = False # 前一次是否突破失败 self.CurrentEntries = 0 # 当前持仓的开仓次数 self.counter = 0 # 计数器,用以控制单根bar最大交易次数
def __init__(self, instrument_id, time_frame, fast_length, slow_length, long_stop, short_stop, start_asset): try: print("{} {} 双均线多空策略已启动!".format(get_localtime(), instrument_id)) # 程序启动时打印提示信息 config.loads('config.json') # 载入配置文件 self.instrument_id = instrument_id # 合约ID self.time_frame = time_frame # k线周期 self.exchange = OKEXFUTURES(config.access_key, config.secret_key, config.passphrase, self.instrument_id) # 初始化交易所 self.position = POSITION(self.exchange, self.instrument_id, self.time_frame) # 初始化potion self.market = MARKET(self.exchange, self.instrument_id, self.time_frame) # 初始化market self.indicators = INDICATORS(self.exchange, self.instrument_id, self.time_frame) # 初始化indicators # 在第一次运行程序时,将初始资金数据保存至数据库中 self.database = "回测" # 回测时必须为"回测" self.datasheet = self.instrument_id.split("-")[0].lower() + "_" + time_frame if config.first_run == "true": storage.mysql_save_strategy_run_info(self.database, self.datasheet, get_localtime(), "none", 0, 0, 0, 0, "none", 0, 0, 0, start_asset) # 读取数据库中保存的总资金数据 self.total_asset = storage.read_mysql_datas(0, self.database, self.datasheet, "总资金", ">")[-1][-1] self.total_profit = storage.read_mysql_datas(0, self.database, self.datasheet, "总资金", ">")[-1][-2] # 策略总盈亏 self.counter = 0 # 计数器 self.fast_length = fast_length # 短周期均线长度 self.slow_length = slow_length # 长周期均线长度 self.long_stop = long_stop # 多单止损幅度 self.short_stop = short_stop # 空单止损幅度 self.contract_value = self.market.contract_value() # 合约面值,每次获取需发起网络请求,故于此处声明变量,优化性能 except: logger.warning()
def __init__(self, instrument_id, time_frame, fast_length, slow_length, long_stop, short_stop, start_asset): config.loads('config.json') # 载入配置文件 self.instrument_id = instrument_id # 合约ID self.time_frame = time_frame # k线周期 self.exchange = OKEXFUTURES(config.access_key, config.secret_key, config.passphrase, self.instrument_id) # 初始化交易所 self.position = POSITION(self.exchange, self.instrument_id, self.time_frame) # 初始化potion self.market = MARKET(self.exchange, self.instrument_id, self.time_frame) # 初始化market self.indicators = INDICATORS(self.exchange, self.instrument_id, self.time_frame) # 初始化indicators # 在第一次运行程序时,将初始资金数据保存至数据库中 self.database = "回测" # 无论实盘或回测,此处database名称可以任意命名 self.datasheet = self.instrument_id.split("-")[0].lower() + "_" + time_frame if config.first_run: storage.mysql_save_strategy_run_info(self.database, self.datasheet, "策略参数为" + str(fast_length) + "&" + str(slow_length), "none", 0, 0, 0, 0, "none", 0, 0, 0, start_asset) # 读取数据库中保存的总资金数据 self.total_asset = storage.read_mysql_datas(0, self.database, self.datasheet, "总资金", ">")[-1][-1] self.counter = 0 # 计数器 self.fast_length = fast_length # 短周期均线长度 self.slow_length = slow_length # 长周期均线长度 self.long_stop = long_stop # 多单止损幅度 self.short_stop = short_stop # 空单止损幅度 self.total_profit = 0 self.contract_value = self.market.contract_value() # 合约面值,每次获取需发起网络请求,故于此处声明变量,优化性能 # 声明持仓方向、数量与价格变量,每次开平仓后手动重新赋值 self.hold_direction = "none" self.hold_amount = 0 self.hold_price = 0 print("{} {} 双均线多空策略已启动!".format(get_localtime(), instrument_id)) # 程序启动时打印提示信息
def direction(self): """获取当前持仓方向""" if config.backtest is False: # 实盘模式下实时获取账户实际持仓方向,仅支持单向持仓模式下的查询 result = self.__platform.get_position()['direction'] return result else: # 回测模式下从数据库中读取持仓方向 result = storage.read_mysql_datas(0, "回测", self.__instrument_id.split("-")[0].lower() + "_" + self.__time_frame, "总资金", ">")[-1][6] return result
def __init__(self, instrument_id, time_frame, bollinger_lengths, filter_length, start_asset): try: # 策略启动时控制台输出提示信息 print("{} {} 布林强盗突破策略已启动!".format(get_localtime(), instrument_id)) # 程序启动时打印提示信息 config.loads("config.json") # 载入配置文件 # 初始化 self.instrument_id = instrument_id # 合约ID self.time_frame = time_frame # k线周期 self.exchange = OKEXFUTURES(config.access_key, config.secret_key, config.passphrase, self.instrument_id) # 交易所 self.market = MARKET(self.exchange, self.instrument_id, self.time_frame) # 行情 self.position = POSITION(self.exchange, self.instrument_id, self.time_frame) # 持仓 self.indicators = INDICATORS(self.exchange, self.instrument_id, self.time_frame) # 指标 # 在第一次运行程序时,将初始资金、总盈亏等数据保存至数据库中 self.database = "回测" # 数据库,回测时必须为"回测" self.datasheet = self.instrument_id.split( "-")[0].lower() + "_" + time_frame # 数据表 if config.first_run == "true": storage.mysql_save_strategy_run_info(self.database, self.datasheet, get_localtime(), "none", 0, 0, 0, 0, "none", 0, 0, 0, start_asset) # 读取数据库中保存的总资金数据 self.total_asset = storage.read_mysql_datas( 0, self.database, self.datasheet, "总资金", ">")[-1][-1] self.total_profit = storage.read_mysql_datas( 0, self.database, self.datasheet, "总资金", ">")[-1][-2] # 策略总盈亏 # 策略参数 self.contract_value = self.market.contract_value() # 合约面值 self.counter = 0 # 计数器 self.bollinger_lengths = bollinger_lengths # 布林通道参数 self.filter_length = filter_length # 过滤器参数 self.out_day = 50 # 自适应出场ma的初始值为50,开仓后赋值为布林通道参数的值 except: logger.warning()
def __init__(self, instrument_id, time_frame, fast_length, slow_length, long_stop, short_stop, start_asset, precision): try: print("{} {} 双均线多空策略已启动!".format(get_localtime(), instrument_id)) # 程序启动时打印提示信息 config.loads('config.json') # 载入配置文件 self.instrument_id = instrument_id # 合约ID self.time_frame = time_frame # k线周期 self.precision = precision # 精度,即币对的最小交易数量 self.exchange = OKEXSPOT(config.access_key, config.secret_key, config.passphrase, self.instrument_id) # 初始化交易所 self.position = POSITION(self.exchange, self.instrument_id, self.time_frame) # 初始化potion self.market = MARKET(self.exchange, self.instrument_id, self.time_frame) # 初始化market self.indicators = INDICATORS(self.exchange, self.instrument_id, self.time_frame) # 初始化indicators # 在第一次运行程序时,将初始资金数据保存至数据库中 self.database = "回测" # 回测时必须为"回测" self.datasheet = self.instrument_id.split( "-")[0].lower() + "_" + time_frame if config.first_run == "true": storage.mysql_save_strategy_run_info(self.database, self.datasheet, get_localtime(), "none", 0, 0, 0, 0, "none", 0, 0, 0, start_asset) # 读取数据库中保存的总资金数据 self.total_asset = storage.read_mysql_datas( 0, self.database, self.datasheet, "总资金", ">")[-1][-1] self.total_profit = storage.read_mysql_datas( 0, self.database, self.datasheet, "总资金", ">")[-1][-2] # 策略总盈亏 self.counter = 0 # 计数器 self.fast_length = fast_length # 短周期均线长度 self.slow_length = slow_length # 长周期均线长度 self.long_stop = long_stop # 多单止损幅度 self.short_stop = short_stop # 空单止损幅度 self.hold_price = 0 # 注意:okex的现货没有获取持仓均价的接口,故需实盘时需要手动记录入场价格。此种写法对于不同的交易所是通用的。 # 此种写法,若策略重启,持仓价格会回归0 except: logger.warning()
def price(self): """获取当前的持仓价格""" if config.backtest != "enabled": # 实盘模式下实时获取账户实际持仓价格 result = self.__platform.get_position()['price'] return result else: # 回测模式下从数据库中读取持仓价格 result = storage.read_mysql_datas( 0, "回测", self.__instrument_id.split("-")[0].lower() + "_" + self.__time_frame, "总资金", ">")[-1][5] return result
def price(self, mode=None, side=None): """获取当前的持仓价格""" if config.backtest is False: # 实盘模式下实时获取账户实际持仓价格 if mode == "both": # 如果传入参数"both",查询双向持仓模式的持仓价格 result = self.__platform.get_position(mode=mode) if side == "long": long_price = result["long"]["price"] return long_price elif side == "short": short_price = result["short"]["price"] return short_price else: result = self.__platform.get_position()['price'] return result else: # 回测模式下从数据库中读取持仓价格 result = storage.read_mysql_datas(0, "回测", self.__instrument_id.split("-")[0].lower() + "_" + self.__time_frame, "总资金", ">")[-1][5] return result
def amount(self, mode=None, side=None): """获取当前持仓数量""" if config.backtest != "enabled": # 实盘模式下实时获取账户实际持仓数量 if mode == "both": # 如果传入参数"both",查询双向持仓模式的持仓数量 result = self.__platform.get_position(mode=mode) if side == "long": long_amount = result["long"]["amount"] return long_amount elif side == "short": short_amount = result["short"]["amount"] return short_amount else: result = self.__platform.get_position()['amount'] return result else: # 回测模式下从数据库中读取持仓数量 result = storage.read_mysql_datas(0, "回测", self.__instrument_id.split("-")[0].lower() + "_" + self.__time_frame, "总资金", ">")[-1][7] return result
def __init__(self, instrument_id, time_frame, fast_length, slow_length, long_stop, short_stop): """双均线策略""" print("{}程序开始运行!".format(get_localtime())) config.loads('config.json') # 载入配置文件 # 在第一次运行程序时,将总资金数据保存至数据库中 start_asset = 20 storage.save_asset_and_profit('trade', 'asset', get_localtime(), 0, start_asset) # 读取数据库中保存的总资金数据 self.total_asset = storage.read_mysql_datas(0, 'trade', 'asset', 'asset', '>')[-1][-1] self.counter = 0 # 计数器 self.long_stop = long_stop # 多单止损幅度 self.short_stop = short_stop # 空单止损幅度 self.access_key = config.access_key # 读取配置文件中保存的api信息 self.secret_key = config.secret_key self.passphrase = config.passphrase self.instrument_id = instrument_id # 合约ID self.time_frame = time_frame # k线周期 self.fast_length = fast_length # 短周期均线长度 self.slow_length = slow_length # 长周期均线长度 self.exchange = OkexFutures(self.access_key, self.secret_key, self.passphrase, self.instrument_id) # 初始化交易所 self.position = Position(self.exchange, self.instrument_id, self.time_frame) # 初始化potion self.market = Market(self.exchange, self.instrument_id, self.time_frame) # 初始化market self.logger = Logger("config.json") # 初始化logger self.indicators = Indicators(self.exchange, self.instrument_id, self.time_frame)
def match(self): # 获取当前账户持仓信息 account_direction = self.__position.direction() account_amount = self.__position.amount() # 获取当前策略应持仓位信息 if self.__databank == "mysql": strategy_direction = storage.read_mysql_datas(0, self.__database, self.__datasheet, "amount", ">=")[-1][-2] strategy_amount = storage.read_mysql_datas(0, self.__database, self.__datasheet, "amount", ">=")[-1][-1] elif self.__databank == "mongodb": strategy_direction = storage.mongodb_read_data(self.__database, self.__datasheet)[-1][0]["strategy_direction"] strategy_amount = int(storage.mongodb_read_data(self.__database, self.__datasheet)[-1][0]["strategy_amount"]) else: strategy_direction = None strategy_amount = None raise DataBankError # 比较账户持仓与策略持仓,如不匹配则同步之 if strategy_direction == "long" and account_direction == "long": if account_amount < strategy_amount: receipt = self.__exchange.buy(self.__market.last() * (1 + self.__overprice_range), strategy_amount - account_amount, 0) return "当前持多,当前实际持仓小于策略应持仓位数量,自动同步结果:{}".format(receipt) elif account_amount > strategy_amount: receipt = self.__exchange.sell(self.__market.last() * (1 - self.__overprice_range), account_amount - strategy_amount, 0) return "当前持多,当前实际持仓大于策略应持仓位数量,自动同步结果:{}".format(receipt) if strategy_direction == "short" and account_direction == "short": # 策略与账户均持空时 if account_amount < strategy_amount: receipt = self.__exchange.sellshort(self.__market.last() * (1 - self.__overprice_range), strategy_amount - account_amount, 0) return "当前持空,当前实际持仓小于策略应持仓位数量,自动同步结果:{}".format(receipt) elif account_amount > strategy_amount: receipt = self.__exchange.buytocover(self.__market.last() * (1 + self.__overprice_range), account_amount - strategy_amount, 0) return "当前持空,当前实际持仓大于策略应持仓位数量,自动同步结果:{}".format(receipt) if strategy_direction == "long" and account_direction == "short": # 策略持多,账户却持空时 receipt1 = self.__exchange.buytocover(self.__market.last() * (1 + self.__overprice_range), account_amount, 0) if "完全成交" not in receipt1: return "策略应持多,当前实际持空,自动同步结果:{}".format(receipt1) else: receipt2 = self.__exchange.buy(self.__market.last() * (1 + self.__overprice_range), strategy_amount, 0) return "策略应持多,当前实际持空,自动同步结果:{}".format(receipt1 + receipt2) if strategy_direction == "short" and account_direction == "long": # 策略持空,账户却持多时 receipt1 = self.__exchange.sell(self.__market.last() * (1 - self.__overprice_range), account_amount, 0) if "完全成交" not in receipt1: return "策略应持空,当前实际持多,自动同步结果:{}".format(receipt1) else: receipt2 = self.__exchange.sellshort(self.__market.last() * (1 - self.__overprice_range), strategy_amount, 0) return "策略应持空,当前实际持多,自动同步结果:{}".format(receipt1 + receipt2) if strategy_direction == "none" and account_direction == "long": # 策略无持仓,账户却持多时 receipt = self.__exchange.sell(self.__market.last() * (1 - self.__overprice_range), account_amount, 0) return "策略应无持仓,当前实际持多,自动同步结果:{}".format(receipt) if strategy_direction == "none" and account_direction == "short": # 策略无持仓,账户却持空时 receipt = self.__exchange.buytocover(self.__market.last() * (1 + self.__overprice_range), account_amount, 0) return "策略应无持仓,当前实际持空,自动同步结果:{}".format(receipt) if account_direction == "none" and strategy_direction == "long": # 账户无持仓,策略却应持多时 receipt = self.__exchange.buy(self.__market.last() * (1 + self.__overprice_range), strategy_amount, 0) return "策略应持多仓,当前实际无持仓,自动同步结果:{}".format(receipt) if account_direction == "none" and strategy_direction == "short": # 账户无持仓,策略却应持空 receipt = self.__exchange.sellshort(self.__market.last() * (1 - self.__overprice_range), strategy_amount, 0) return "策略应持空仓,当前实际无持仓,自动同步结果:{}".format(receipt) if account_amount == strategy_amount and account_direction == strategy_direction: dict = {"策略持仓方向": strategy_direction, "策略持仓数量": strategy_amount, "账户实际持仓方向": account_direction, "账户实际持仓数量": account_amount} return "策略持仓与账户持仓匹配! {}".format(dict) else: raise MatchError