1、 缩进与空格:使用4个空格进行缩进,不使用制表符(Tab)。在运算符两侧、逗号后面和冒号后面添加空格。
2、命名规范:变量、函数和类名使用小写字母和下划线分隔,如my_variable。常量使用大写字母和下划线分隔,如MY_CONSTANT。
首先在期魔方策略界面中,先点击指标列表,再点击[新增]进入金增分类窗口,输入文件名和注释说明后点击[确定]后成功创建新文件夹
(1)策略->指标列表 -> 新增按钮->新增指标弹窗->填写好指标名称,选择语言为“python”->点击确定按钮
(2)第一次使用编辑器的用户需先下载编辑器
(3)策略页面出现下载中进度条
(4)编辑器下载完后,vscode编辑器会自动出现系统自带的基础编程代码,您可以根据您的需求进行编写代码,编写完成后,点击右上方的[Run Python File]即可运行
(5)如遇到缺失模块,找到安装目录下coder文件夹所在的位置,复制路径,使用命令:“xx\期魔方\coder\python3116\python.exe -m pip install xx模块”
编译成功的指标,可在行情->指标->自编指标中查看并渲染到K线图上展示效果
一个行情可以加载多个指标,您只需要继续点击加载别的指标即可,并在我的加载或行情左上方查看您添加的具体指标
在任务->启动任务->指标标识->指标面板->选择指标,应用指标在任务实时行情K线中
函数:data_init
说明:定义指标初始化
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
var1 | str | 是 | 序列名称 |
MULTI_LINE | str | 是 | 序列类型,参考DrawStyle |
rgba(255,0,0,1) | str | 是 | K线颜色 |
用法:
xxxxxxxxxx
#这里只定义了一个buffer:
def data_init(self):
self.var1 = []
init_buffer(self,"var1","var1","MULTI_LINE","rgba(255,0,0,1)")
#如果定义多个,例如:
def data_init(self):
self.var1 = []
init_buffer(self,"var1","var1","MULTI_LINE","rgba(255,0,0,1)")
self.var2 = []
init_buffer(self,"var2","var2","MULTI_LINE","rgba(255,0,0,1)")
返回结果:
xxxxxxxxxx
#如果您只定义1个buffer,返回值为 [var1的序列]
#如果您定义2个buffer,返回值就是 [var1的序列,var2的序列]
#同理,定义多个buffer在计算后按顺序返回
#储值的顺序在任务中调用后为了和任务同步,顺势是顺时间正向的,最新的值在最后面
函数:data_calculate
说明:指标的计算函数
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
rates_total | int | 是 | 数据长度 |
time | list | 是 | k线的时间集合 |
open | list | 是 | k线的开盘价 |
high | list | 是 | k线的最高价 |
low | list | 是 | k线的最低价 |
close | list | 是 | k线的收盘价 |
volume | list | 是 | k线的成交量 |
用法:
xxxxxxxxxx
def data_init(self):
self.params_map = self.Params()
self.var1 = []
init_buffer(self,"var1","var1","MULTI_LINE","rgba(255,0,0,1)")
def data_calculate(self,rates_total:int, # 数据长度
time:list, # k线的时间集合
open:list, # k线的开盘价
high:list, # k线的最高价
low:list, # k线的最低价
close:list, # k线的收盘价
volume:list): # k线的成交量
#原代码耗时较长,现提供部分代码节省算力
limit = 1
if self.pre_calculate_len == 0:
self.pre_calculate_len = rates_total
limit = rates_total
#如果self.pre_calculate_len等于0,则表示第一次调用data_calculate,此时limit = rates_total,即会计算所有序列数据;如果self.pre_calculate_len不等于0,则表示不是第一次调用data_calculate,此时limit = 1,只对新的部分数据做计算
for i in range(limit):
self.var1[i] = (2 * close[i] + high[i] + low[i] ) / 4
#以如下数据为例:#close[3775,3774,3781,3783,3783,3785];high[3778,3776,3782,3783,3785,3787];low[3775,3774,3779,3778,3781,3785]
for i in range(limit):
self.var1[i] = (2 * close[i] + high[i] + low[i] ) / 4
#得出self.var1[i]=[3775.75,3774.5,3780.75,3781.75,3783,3785.5]
函数:DrawStyle
说明:目前仍在整理中,待完善,仅供简单参考
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
MULTI_LINE | str | 是 | 线条 |
MULTI_BAR | str | 是 | 主题 |
MULTI_TEXT | str | 是 | 多行文字 |
MULTI_SVGICON | str | 是 | SVG图标集合 |
COLOR_KLINEK | str | 是 | 彩色K线 |
CALCULATE_DATA | str | 是 | 计算数据 |
用法:
xxxxxxxxxx
class DrawStyle(Enum):
MULTI_LINE = "MULTI_LINE"
MULTI_BAR = "MULTI_BAR"
MULTI_TEXT = "MULTI_TEXT"
MULTI_SVGICON = "MULTI_SVGICON"
COLOR_KLINEK = "COLOR_KLINEK"
CALCULATE_DATA = "CALCULATE_DATA"
#制作记录 不做输出
后续将补充优化指标案例
xxxxxxxxxx
#指标开发者无需关注(勿动),用于接收运行的品种名称
symbol = ""
from pydantic import BaseModel
class Params(BaseModel, validate_assignment=True):
from pydantic import Field
"""参数映射模型"""
is_main:bool = Field(default=True,title = "是否是主图")
def data_init(self):
self.params_map = self.Params()
self.var1 = []
init_buffer(self,"var1","var1","MULTI_LINE","rgba(255,0,0,1)")
self.pre_calculate_len = 0 #用于记录前一计算长度
def data_calculate(self,rates_total:int, # 数据长度
time:list, # k线的时间集合
open:list, # k线的开盘价
high:list, # k线的最高价
low:list, # k线的最低价
close:list, # k线的收盘价
volume:list): # k线的成交量
limit = 1
if self.pre_calculate_len == 0:
self.pre_calculate_len = rates_total
limit = rates_total
for i in range(limit):
self.var1[i] = (2 * close[i] + high[i] + low[i] ) / 4
在策略页面中点击策略列表,再点击[新增]开始新增策略分类文件夹
(1)策略->策略列表文件 -> 新建按钮->新增策略弹窗->填写好策略名称,选择语言为“python(已固定)”->点击确定按钮
(2)添加策略成功后跳转到vscode编辑器页,完成您的代码编写后点击[Run Python File]按钮进行编译,如下图
(1)添加回测策略
编译成功的策略,可在回测->添加回测页面->测试模型中选择自己的策略模型,带有参数的策略,还需填写策略参数
(2)开始回测
添加成功后,点击[回测]按钮,回测进度条100%表示回测完成
(3)查看回测报告
点击[详情]查看您的回测策略数据是否匹配
(1)添加任务
在任务界面找到您自己的策略,双击即可进入添加任务窗口,设置您的参数
(2)启动任务
启动任务后的实时k线图
初始策略函数
函数:onInit
说明:初始策略函数,每次开启只运算一次
用法:
xxxxxxxxxx
def onInit():
mf_engine.log("测试案例初始化完成")
...
新行情输入运算
函数:onTick
说明:每当有新行情时,输入则运算一次
用法:
xxxxxxxxxx
def onTick():
...
#每个行情的新报价会运行一次,是任务的核心函数,每个任务必须包含,无参数
结束函数
函数:onStop
说明:每次任务结束会调用一次; 可以执行一些结尾统计操作
用法:
xxxxxxxxxx
#初始策略函数 每次开启只运算一次
def onInit():
mf_engine.log("测试案例初始化完成")
...
def onTick():
indicators_data = mf_engine.getIndicators("test_ind1",
mf_engine.mFsymbol,
mf_engine.mFperiod,
mf_engine.mFexchange)
mf_engine.log(indicators_data)
...
# 结束函数 每次任务结束会调用一次; 可以执行一些结尾统计操作;
def onStop():
mf_engine.log("测试案例停止")
...
接收任务订单信息
函数:onOrder
说明:接收该任务开出的订单信息,可以在接收到订单后执行撤单
用法:
xxxxxxxxxx
#初始策略函数 每次开启只运算一次
def onInit():
mf_engine.log("撤单示例 开始")
...
def onTick():
"""onTick函数,每当行情有新行情输入则运算一次"""
"""
撤销指定单号的订单
"""
order_num = 123456
"""
order_id需要满足2个条件:
1.靠右
2.不够12位字符串要求用空格填充满12位
"""
order_id = f"{order_num:>12}"
order_base_info = {"OrderSysID":order_id}
mf_engine.actionOrder(order_base_info)
...
def onOrder(order):
"""
接收该任务开出的订单信息
"""
"""
可以在接收到订单后执行撤单
"""
order_status = order.get("OrderStatus")
"""
订单状态详细了解 请查询文档...................
"""
"""
当订单为未成交时
需要撤单直接填入order对象
"""
if order_status == "3":
mf_engine.actionOrder(order)
...
def allOrder(order):
"""
接收该账户开出的订单信息
"""
"""
全局订单操作同上
"""
...
# 结束函数 每次任务结束会调用一次; 可以执行一些结尾统计操作;
def onStop():
mf_engine.log("撤单示例 结束")
...
获取指标
函数:getIndicators
说明:获取账户的指标计算结果
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
indicators_name | str | 是 | 指标的名称 |
symbol | str | 是 | 产品名称 |
period | str | 是 | 周期 |
exchange | str | 是 | 交易所CODE |
params | 外置参数 | 否 | 指标的外置参数列表 |
用法:
xxxxxxxxxx
#获取在上期所的产品沥青2409,在“DEMO_MAIN_INT_PARAMS”指标的结果
#没参数:
mf_engine.getIndicators("DEMO_MAIN_INT_PARAMS","bu2409","1分钟","SHFE",[])
#有参数:(后续补充)
返回结果:
xxxxxxxxxx
[[1,2,3,4,5,6,7,8......],[1,2,3,4,5,6,7,8,9....]]
#根据指标中的设置顺序输出
#数组里的数组的长度同指标里的buffer的长度,可在指标文件代码编写第4小点查看
#其中1,2,3,4,5,6,7,8......是指标中对应每个位置计算的结果
#例:用户访问result[0][-1] 就是0号序列的最新值
获取k线数据
函数:getKline
说明:获取k线具体数据
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
symbol | str | 是 | 品种合约 |
exchange | str | 是 | 交易所CODE |
period | str | 是 | 运行周期 |
price | str | 是 | 价格序列 |
len | int | 是 | 获取k线数据长度 |
用法:
xxxxxxxxxx
mf_engine.getKline(mf_engine.mFsymbol,mf_engine.mFexchange,mf_engine.mFperiod,len)
#使用方法:在任务模块中,如果您想改变量化选择的品种合约、产品所属交易所、周期、价格序列名称和获取k线数据长度,只需要改变其数值运行即可
#示例:def mf_engine.getKline("bu2403","SHFE","10分钟","close",10)
#改变周期后:def mf_engine.getKline("bu2403","SHFE","5分钟","close",10)
#len不填默认值为:30
获取产品合约信息
函数:getSymbolInfo
说明:获取品种合约信息
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
mf_engine.mFsymbol | str | 是 | 品种合约 |
tickFiledName | str | 是 | CTP返回字段名称,如PriceTick是每根tick的价格 |
用法:
xxxxxxxxxx
mf_engine.getSymbolInfo(mf_engine.mFsymbol).get(tickFiledName)
返回结果:
xxxxxxxxxx
{"ExchangeID": "SHFE",#交易所代码
"LongMarginRatio": 0.19,#多头保证金率
"MaxLimitOrderVolume": 500,#限价单最大下单量
"MaxMarginSideAlgorithm": "1",#是否使用大额单边保证金算法
"MaxMarketOrderVolume": 30,#市价单最大下单量
"MinLimitOrderVolume": 1,#限价单最小下单量
"MinMarketOrderVolume": 1,#市价单最小下单量
"PriceTick": 1.0,#最小变动价位
"ProductID": "ag",#产品代码
"ShortMarginRatio": 0.19,#空头保证金率
"UnderlyingInstrID": "ag",#基础商品代码
"VolumeMultiple": 15,#合约数量乘数
"transactionFee": 1e-05,#交易费
"transactionFeeMode": 6#交易费模式}
输出日志
函数:log
说明:输出日志内容
用法:
xxxxxxxxxx
mf_engine.log("日志内容")
开单
函数:customOpenOrder
说明:期货交易接口,开仓、开空、平仓和平空
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
symbol | str | 是 | 合约代码 |
price | str | 是 | 价格 |
volume | str | 是 | 手数 |
priceType | str | 是 | 报价类型 ,包含"市价/限价",默认限价 |
dicrection | str | 是 | 报单方向,包含 "多/空" |
offset | str | 是 | 报单类型,0:开单;1:平今仓;3:平昨 |
用法:
customOpenOrder(symbol,price,volume,priceType,dicrection,offset)
#开仓案例
mf_engine.customOpenOrder(symbol="ag2410",price=4500,volume=1,priceType="市价",dicrection="多",offset = "0")
#平昨仓/平仓案例 平空单
mf_engine.customOpenOrder(symbol="ag2410",price=4500,volume=1,priceType="市价",dicrection="空",offset = "1")
#平今案例 平多单
mf_engine.customOpenOrder(symbol="ag2410",price=4500,volume=1,priceType="市价",dicrection="空",offset = "3")
返回账户信息
函数:getAccount
说明:返回登录账户的信息(无参数)
用法:
xxxxxxxxxx
mf_engine.getAccount()
返回结果:
对象查看途径:Python帮助文档->Python策略编写->策略代码编写->对象->ACCOUNTDATA
#初始策略函数 每次开启只运算一次
def onInit():
mf_engine.log("getAccount获取示例 开始")
def onTick():
"""onTick函数,每当行情有新行情输入则运算一次;"""
'''在ACCOUNTDATA中查询您想输出的数据,以下为部分数据示例'''
account_info = mf_engine.getAccount()
mf_engine.log(f"结算后余额:{account_info["Balance"]}")
#>>>>>输出该账户余额
mf_engine.log(f"可用资金:{account_info["Available"]}")
#>>>>>输出该账户可用资金
# 结束函数 每次任务结束会调用一次; 可以执行一些结尾统计操作;
def onStop():
mf_engine.log("getAccount获取示例 结束")
...
返回订阅产品数据
函数:getTickByPosition
说明:返回当前本机订阅的产品数据(无参数)
用法:
xxxxxxxxxx
mf_engine.getTickByPosition(self)
返回结果:
对象查看途径:Python帮助文档->Python策略编写->策略代码编写->对象->TICKDATA
xxxxxxxxxx
#初始策略函数 每次开启只运算一次
def onInit():
mf_engine.log("getTickByPosition获取示例 开始")
def onTick():
"""onTick函数,每当行情有新行情输入则运算一次;"""
'''在TICKDATA中查询您想输出的数据,以下为部分数据示例'''
TickByPosition_info = mf_engine.getTickByPosition()
mf_engine.log(f"交易所代码:{TickByPosition_info["ag2410"]["ExchangeID"]}")
#>>>>>输出该交易所代码
mf_engine.log(f"昨收盘:{TickByPosition_info["ag2410"]["PreClosePrice"]}")
#>>>>>输出该账户昨收盘价
# 结束函数 每次任务结束会调用一次; 可以执行一些结尾统计操作;
def onStop():
mf_engine.log("getTickByPosition获取示例 结束")
...
返回K线数量
函数:bars
说明:返回基础K线的数量(无参数;返回值为整数)
用法:
xxxxxxxxxx
mf_engine.bars()
返回结果:
xxxxxxxxxx
#初始策略函数 每次开启只运算一次
def onInit():
mf_engine.log("bars获取示例 开始")
def onTick():
"""onTick函数,每当行情有新行情输入则运算一次"""
bar=mf_engine.bars()
mf_engine.log(bar)
# 返回当前模型中当前K线的数量
# 结束函数 每次任务结束会调用一次; 可以执行一些结尾统计操作;
def onStop():
mf_engine.log("getPosition获取示例 结束")
...
获取撤单信息
函数:actionOrder
说明:无返回值,撤单信息在onOrder 获得(途径:Python帮助文档->Python策略编写->策略代码编写->结构函数->onOrder )
用法:
xxxxxxxxxx
mf_engine.actionOrder(order)
#参数是字典且必须包含OrderSysID字段
{"OrderSysID":" 13254"}
获取持仓信息
函数:getPosition
说明:获取持仓信息(无参数)
用法:
xxxxxxxxxx
mf_engine.getPosition()
返回结果:
对象查看途径:Python帮助文档->Python策略编写->策略代码编写->对象->POSITIONDATA
'''输出持仓列表所有数据'''
#初始策略函数 每次开启只运算一次
def onInit():
mf_engine.log("getPosition获取示例 开始")
def onTick():
"""onTick函数,每当行情有新行情输入则运算一次;"""
Positions= mf_engine.getPosition()
for pos in Positions:
mf_engine.log(pos)
# 结束函数 每次任务结束会调用一次; 可以执行一些结尾统计操作;
def onStop():
mf_engine.log("getPosition获取示例 结束")
...
'''输出持仓列表部分数据'''
#初始策略函数 每次开启只运算一次
def onInit():
mf_engine.log("getPosition获取示例 开始")
def onTick():
"""onTick函数,每当行情有新行情输入则运算一次;"""
'''在POSITIONDATA中查询您想输出的数据,以下为部分数据示例'''
Positions= mf_engine.getPosition()
for pos in Positions:
mf_engine.log(f"持仓日期:{pos["PositionDate"]}")
#>>>>>输出该产品持仓日期
mf_engine.log(f"平仓盈亏:{pos["CloseProfit"]}")
#>>>>>输出该账户平仓盈亏
# 结束函数 每次任务结束会调用一次; 可以执行一些结尾统计操作;
def onStop():
mf_engine.log("getPosition获取示例 结束")
...
ACCOUNTDATA
属性 | 类型 | 说明 |
---|---|---|
BrokerID | str | 经纪公司代码 |
AccountID | str | 投资者帐号 |
PreMortgage | float | 上次质押金额 |
PreCredit | float | 上次信用额度 |
PreDeposit | float | 上次存款额 |
PreBalance | float | 上次结算准备金 |
PreMargin | float | 上次占用的保证金 |
InterestBase | float | 利息基数 |
Interest | float | 利息收入 |
Deposit | float | 入金金额 |
Withdraw | float | 出金金额 |
FrozenMargin | float | 冻结的保证金 |
FrozenCash | float | 冻结的资金 |
FrozenCommission | float | 冻结的手续费 |
CurrMargin | float | 当前保证金总额 |
CashIn | float | 资金差额 |
Commission | float | 手续费 |
CloseProfit | float | 平仓盈亏 |
PositionProfit | float | 持仓盈亏 |
Balance | float | 期货结算准备金 |
Available | float | 可用资金 |
WithdrawQuota | float | 可取资金 |
Reserve | float | 基本准备金 |
TradingDay | str | 交易日 |
SettlementID | int | 结算编号 |
Credit | float | 信用额度 |
Mortgage | float | 质押金额 |
ExchangeMargin | float | 交易所保证金 |
DeliveryMargin | float | 投资者交割保证金 |
ExchangeDeliveryMargin | float | 交易所交割保证金 |
ReserveBalance | float | 保底期货结算准备金 |
CurrencyID | str | 币种代码 |
PreFundMortgageIn | float | 上次货币质入金额 |
PreFundMortgageOut | float | 上次货币质出金额 |
FundMortgageIn | float | 货币质入金额 |
FundMortgageOut | float | 货币质出金额 |
FundMortgageAvailable | float | 货币质押余额 |
MortgageableFund | float | 可质押货币金额 |
SpecProductMargin | float | 特殊产品占用保证金 |
SpecProductFrozenMargin | float | 特殊产品冻结保证金 |
SpecProductCommission | float | 特殊产品手续费 |
SpecProductFrozenCommission | float | 特殊产品冻结手续费 |
SpecProductPositionProfit | float | 特殊产品持仓盈亏 |
SpecProductCloseProfit | float | 特殊产品平仓盈亏 |
SpecProductPositionProfitByAlg | float | 根据持仓盈亏算法计算的特殊产品持仓盈亏 |
SpecProductExchangeMargin | float | 特殊产品交易所保证金 |
RemainSwap | float | 剩余换汇额度 |
FrozenSwap | float | 延时换汇冻结金额 |
TICKDATA
属性 | 类型 | 说明 |
---|---|---|
TradingDay | str | 交易日 |
InstrumentID | str | 合约代码 |
ExchangeID | str | 交易所代码 |
ExchangeInstID | str | 合约在交易所的代码 |
LastPrice | float | 最新价 |
PreSettlementPrice | float | 上次结算价 |
PreClosePrice | float | 昨收盘 |
PreOpenInterest | float | 昨持仓量 |
OpenPrice | float | 今开盘 |
HighestPrice | float | 最高价 |
LowestPrice | float | 最低价 |
Volume | int | 数量 |
Turnover | float | 成交金额 |
OpenInterest | float | 持仓量 |
ClosePrice | float | 今收盘 |
SettlementPrice | float | 本次结算价 |
UpperLimitPrice | float | 涨停板价 |
LowerLimitPrice | float | 跌停板价 |
PreDelta | float | 昨虚实度 |
CurrDelta | float | 今虚实度 |
UpdateTime | str | 最后修改时间 |
UpdateMillisec | int | 最后修改毫秒 |
BidPrice1 | float | 申买价一 |
BidVolume1 | int | 申买量一 |
AskPrice1 | float | 申卖价一 |
AskVolume1 | int | 申卖量一 |
BidPrice2 | float | 申买价二 |
BidVolume2 | int | 申买量二 |
AskPrice2 | float | 申卖价二 |
AskVolume2 | int | 申卖量二 |
BidPrice3 | float | 申买价三 |
BidVolume3 | int | 申买量三 |
AskPrice3 | float | 申卖价三 |
AskVolume3 | int | 申卖量三 |
BidPrice4 | float | 申买价四 |
BidVolume4 | int | 申买量四 |
AskPrice4 | float | 申卖价四 |
AskVolume4 | int | 申卖量四 |
BidPrice5 | float | 申买价五 |
BidVolume5 | int | 申买量五 |
AskPrice5 | float | 申卖价五 |
AskVolume5 | int | 申卖量五 |
AveragePrice | float | 当日均价 |
ActionDay | str | 业务日期 |
POSITIONDATA
属性 | 类型 | 说明 |
---|---|---|
InstrumentID | int | 合约代码 |
BrokerID | str | 经纪公司代码 |
InvestorID | str | 投资者代码 |
PosiDirection | str | 持仓多空方向 |
HedgeFlag | str | 投机套保标志 |
PositionDate | str | 持仓日期 |
YdPosition | int | 上日持仓 |
Position | int | 今日持仓 |
LongFrozen | int | 多头冻结 |
ShortFrozen | int | 空头冻结 |
LongFrozenAmount | float | 开仓冻结金额 |
ShortFrozenAmount | float | 平仓冻结金额 |
OpenVolume | int | 开仓量 |
CloseVolume | int | 平仓量 |
OpenAmount | float | 开仓金额 |
CloseAmount | float | 平仓金额 |
PositionCost | float | 持仓成本 |
PreMargin | float | 上次占用的保证金 |
UseMargin | float | 占用的保证金 |
FrozenMargin | float | 冻结的保证金 |
FrozenCash | float | 冻结的资金 |
FrozenCommission | float | 冻结的手续费 |
CashIn | float | 资金差额 |
Commission | int | 手续费 |
CloseProfit | int | 平仓盈亏 |
PositionProfit | float | 持仓盈亏 |
PreSettlementPrice | int | 上次结算价 |
SettlementPrice | float | 本次结算价 |
TradingDay | str | 交易日 |
SettlementID | int | 结算编号 |
OpenCost | float | 开仓成本 |
ExchangeMargin | float | 交易所保证金 |
CombPosition | int | 组合成交形成的持仓 |
CombLongFrozen | int | 组合多头冻结 |
CombShortFrozen | int | 组合空头冻结 |
CloseProfitByDate | float | 日盯市平仓盈亏 |
CloseProfitByTrade | float | 逐笔对冲平仓盈亏 |
TodayPosition | int | 今日持仓 |
MarginRateByMoney | float | 保证金率 |
MarginRateByVolume | float | 保证金率(按手数) |
StrikeFrozen | int | 执行冻结 |
StrikeFrozenAmount | float | 执行冻结金额 |
AbandonFrozen | int | 放弃执行冻结 |
ExchangeID | str | 交易所代码 |
YdStrikeFrozen | int | 执行冻结的昨仓 |
InvestUnitID | str | 投资单元代码 |
PositionCostOffset | float | 大商所持仓成本差值,只有大商所使用 |
TasPosition | int | tas持仓手数 |
TasPositionCost | float | tas持仓成本 |
后续将补充优化策略案例
xxxxxxxxxx
"""
DEMO
双均线策略
"""
"""
定义您的外置参数
创建 Params 类
"""
from pydantic import BaseModel, Field
class Params(BaseModel, validate_assignment=True):
"""参数映射模型"""
volume:int = Field(default=1.0,title = "交易手数")
ma1_period:int = Field(default=5,title = "均线1")
ma2_period:float = Field(default=10,title = "均线2")
stop_ticks:int = Field(default=10.0,title = "固定止损(跳)")
class TRADE():
#经纪公司代码
BrokerID = ""
#投资者代码
InvestorID= ""
#合约代码
InstrumentID= ""
#报单引用
OrderRef= ""
#用户代码
UserID= ""
#交易所代码
ExchangeID= ""
#成交编号
TradeID= ""
#买卖方向
Direction= ""
#报单编号
OrderSysID= ""
#会员代码
ParticipantID= ""
#客户代码
ClientID= ""
#交易角色
TradingRole= ""
#合约在交易所的代码
ExchangeInstID= ""
#开平标志
OffsetFlag= ""
#投机套保标志
HedgeFlag= ""
#价格
Price= 0
#数量
Volume = 0
#成交时期
TradeDate= ""
#成交时间
TradeTime= ""
#成交类型
TradeType= ""
#成交价来源
PriceSource= ""
#交易所交易员代码
TraderID= ""
#本地报单编号
OrderLocalID= ""
#结算会员编号
ClearingPartID= ""
#业务单元
BusinessUnit= ""
#序号
SequenceNo= ""
#交易日
TradingDay= ""
#结算编号
SettlementID= ""
#经纪公司报单编号
BrokerOrderSeq= ""
#成交来源
TradeSource= ""
#投资单元代码
InvestUnitID= ""
def __init__(self,**kwargs):
for key,value in kwargs.items():
setattr(self,key,value)
from typing import Dict,List
class ORDERMANAGER():
def __init__(self):
self.orders:Dict[str,TRADE] ={}
def update_order(self,orderInfo:dict) -> None:
order_id = orderInfo.get("OrderLocalID")
if orderInfo["OffsetFlag"] != "0": #非开启订单 不做记录
return
if not order_id:
print("该订单无订单号 不用处理")
return
self.orders[order_id] = TRADE(**orderInfo)
def clear(self,order_id):
del self.orders[order_id]
def current_order(self) ->List[TRADE]:
order_list = []
for k,v in self.orders.items():
#一个开仓单 且 没有成交 且没有被撤
order_list.append(v)
if not order_list:
self.orders:Dict[str,TRADE] = {}
return None
return order_list
om = ORDERMANAGER()
#初始策略函数 每次开启只运算一次
def onInit():
"""
在初始化函数中把外置参数实例化
"""
mf_engine.params_map = Params()
mf_engine.log("DEMO_DOUBLE_MA init success!")
"""
计算出快线和慢线的值
"""
def calculateMovingAverage()->list:
"""
调用 mf_engine.getKline 获取K线数据中的close序列
"""
fastPeriod = mf_engine.params_map.ma1_period
slowPeriod = mf_engine.params_map.ma2_period
closeArray=mf_engine.getKline(mf_engine.mFsymbol,\
mf_engine.mFexchange,mf_engine.mFperiod,"close",slowPeriod + 2)
array_size = len(closeArray)
if array_size < slowPeriod+2:
return [0,0],[0,0]
fastMaArray = [sum(closeArray[max(0,i-int(fastPeriod)+1):i+1])/fastPeriod\
for i in range(int(fastPeriod) - 1,array_size)]
slowMaArray = [sum(closeArray[max(0,i-int(slowPeriod)+1):i+1])/slowPeriod\
for i in range(int(slowPeriod) - 1,array_size)]
assert len(fastMaArray) == array_size - fastPeriod + 1, "Fast MA array size mismatch."
assert len(slowMaArray) == array_size - slowPeriod + 1, "Slow MA array size mismatch."
return fastMaArray,slowMaArray
wait_order_list = []
"""用来保持订单开启的节奏 每个K线最多开一单"""
bars = [0]
def TradeThread():
volume:int = mf_engine.params_map.volume
"""
如果未正确报给ctp或ctp连接失败,即wait_order_list运行失败; ,
出现无法响应,为了延续执行,会执行清除;
"""
"""
避免同一k线下频繁报单,
通过bars来区分,重置该参数
同一个bar内是不会进行再次计算;
"""
if mf_engine.bars() > bars[0]:
wait_order_list.clear()
if len(wait_order_list)==0 and \
mf_engine.bars() > bars[0]:
#当订单不存在时 考虑开单
fastMaArray,slowMaArray = calculateMovingAverage()
crossAbove = fastMaArray[-2] > slowMaArray[-2] and fastMaArray[-3] < slowMaArray[-3]
crossBelow = fastMaArray[-2] < slowMaArray[-2] and fastMaArray[-3] > slowMaArray[-3]
direction ="无"
open_price = 0
if crossAbove:
direction = "多"
open_price = mf_engine.last_tick.HighestPrice
if crossBelow:
direction = "空"
open_price = mf_engine.last_tick.LowestPrice
"""
如果持有反向订单需要先平
"""
orders = om.current_order()
if orders:
for currentOrder in orders:
open_price = currentOrder.Price
close_direction = "多"
close_volume = 0
close_offset = "1"
close_price = 0
if mf_engine.mFexchange in "SHFE INE":
#需要区分昨仓今仓
if currentOrder.TradeDate == mf_engine.last_tick.ActionDay:
close_offset = "3"
if currentOrder.Direction == "0" and direction=="空":
close_direction = "空"
close_price = mf_engine.last_tick.LowerLimitPrice
close_volume= currentOrder.Volume
elif currentOrder.Direction == "1" and direction=="多":
close_direction = "多"
close_price = mf_engine.last_tick.HighestPrice
close_volume= currentOrder.Volume
if close_volume > 0:
mf_engine.customOpenOrder(direction=close_direction,
priceType="市价",
price=close_price,
volume=close_volume,
offset=close_offset)
om.clear(currentOrder.OrderLocalID)
if direction != "无":
mf_engine.customOpenOrder(direction=direction,
priceType="市价",
price = open_price,
volume=volume,
offset="0")
bars[0] = mf_engine.bars()
"""
该列表用于 网速慢时,订单发出 但是并没有得到回复时 等待的情况;
必须等到回复 才继续执行开单操作;避免重复开单
"""
wait_order_list.append(0)
...
def closeThread():
last_price = mf_engine.last_tick.LastPrice
stop_ticks = mf_engine.params_map.stop_ticks
PriceTick = mf_engine.getSymbolInfo(mf_engine.mFsymbol).get("PriceTick")
orders = om.current_order()
if orders:
for currentOrder in orders:
open_price = currentOrder.Price
close_direction = "多"
close_volume = 0
close_offset = "1"
close_price = 0
if mf_engine.mFexchange in "SHFE INE":
#需要区分昨仓今仓
if currentOrder.TradeDate == mf_engine.last_tick.ActionDay:
close_offset = "3"
if currentOrder.Direction == "0":
if last_price <= open_price - stop_ticks * PriceTick:
close_direction = "空"
close_price = mf_engine.last_tick.LowerLimitPrice
close_volume= currentOrder.Volume
mf_engine.log("多单触发止损")
elif currentOrder.Direction == "1":
if last_price >= open_price + stop_ticks * PriceTick:
close_direction = "多"
close_price = mf_engine.last_tick.HighestPrice
close_volume= currentOrder.Volume
mf_engine.log("空单触发止损")
if close_volume > 0:
mf_engine.customOpenOrder(direction=close_direction,
priceType="市价",
price=close_price,
volume=close_volume,
offset=close_offset)
om.clear(currentOrder.OrderLocalID)
def onTick():
"""onTick函数,每当行情有新行情输入则运算一次;"""
closeThread()
TradeThread()
def onOrder(order):
"""
需要处理订单信息时就使用
"""
if order["OrderStatus"] == "5":
#接收到了对应的撤单信息
if len(wait_order_list)>0:
wait_order_list.clear() #放开权限 重新开仓
...
def onTrade(trade):
om.update_order(trade)
if len(wait_order_list)>0:
wait_order_list.pop(0)
...
# 结束函数 每次任务结束会调用一次; 可以执行一些结尾统计操作;
def onStop():
mf_engine.log("DEMO_DOUBLE_MA stop!")
...
在指标列表中任意分类中点击[新增],选择[My-Language],输入指标名称点击确定
面板自动显示出vscode编辑器,此时需要将其放大打开进行编译
IsMainIndex,当IsMainIndex为0时,指标叠加方式为副图,当IsMainIndex为1时,指标叠加方式为主图,当IsMainIndex为3时,指标叠加方式为主图替换, 当不设置IsMainIndex函数时。默认为副图叠加
xxxxxxxxxx
IsMaIsMainIndex:=myinput(1);
TYP:=(HIGH+LOW+CLOSE)/3;
CCI:(TYP-MA(TYP,N))*1000/(15*AVEDEV(TYP,2));
#CCI指标在副图展示inIndex,当IsMainIndex为0时,指标叠加方式为副图,当IsMainIndex为1时,指标叠加方式为主图,当IsMainIndex为3时,指标叠加方式为主图替换,
#当不设置IsMainIndex函数时。默认为副图叠加
myinput();将指标参数映射到客户端参数栏
xxxxxxxxxx
Parm1:=myinput(10);
Parm2:=myinput(20);
M1:MA(C,Parm1);
M2:MA(C,Parm2);
#M1均线的外部参数为10,M2均线的外部参数为20
MESSAGE(COND,'TEXT',Empty);满足信号COND时,触发预警消息,消息内容为TEXT,Empty为0时,则为立即触发,Empty为1时,收线触发。消息方式在设置中设置
xxxxxxxxxx
M1:MA(C,10);
M2:MA(C,20);
预警:=MESSAGE(CROSS(M1,M2),'金叉',1);
#当10日均线和20日均线发生金叉时,预警消息内容为:金叉,收线触发
在指标列表中,找到麦语言的指标,点击[编辑]后进入vscode剪辑器
根据您的需求编写指标后,右键点击[麦语言编译]
如果编译成功,在界面右下方会出现编译通过,此时指标调试成功
如果编译失败,界面右下方会出现编译异常,请到控制“输出”看原因,此时点击界面左上方终端->新建终端查看具体原因
点击终端的输出以及麦语言输出
出现具体错误原因,您可以据此继续完善编译
后续将补充优化指标案例
在默认指标代码中,只输出一条单均线,下文以输出两条线为例,一条为单均线,另一条为5倍均线
(1)填写第二根线参数
- 注释:用户可以根据自身的偏好选择两条线的颜色
- R、G、B 都是 0~255 的数字,透明度 A 是 0%~100% 的数字,先转成对应的 0~255 的数字(A*255)
- 下方提供rega颜色和数字对应的查询网站:https://www.toolhelper.cn/Color/RGBToHex
编写代码如下:
xxxxxxxxxx
def data_init(self):
#定义指标输出的保存对象,即在K线上定义一条线,如多条线,定义多个数组即可,多条线下面的需要初始化多次
self.buffer_line1 = []
# setBuffer方法,用于设置定义的输出的属性
# 参数1:该对象的字符串名称,跟上面的代码self.bufferObj初始化的名字保持一致,放在字符串里面
# 参数2:self.bufferObj这个对象在图表显示的名称
# 参数3:ENUM_DRAWSTYLE(该对象输出的类型),如MULTI_LINE
# 参数4:color(颜色) ,rgba(255, 0, 0, 0.5)
init_buffer(self,"buffer_line1","avg_four","MULTI_LINE","rgba(0,128,0,0.7)")
#定义k线上的第二条线,改变参数1、参数2的名称;参数3、参数4根据您的偏好调整,这里只改变参数4(颜色)
self.buffer_line2 = []
init_buffer(self,"buffer_line2","avg_six","MULTI_LINE","rgba(255,165,0,0.7)")
具体示例如下图:
(2)对两根线循环赋值
编写代码如下:
def data_calculate(self,rates_total:int, #数据长度
time:list, # k线的时间集合
open:list, # k线的开盘价
high:list, # k线的最高价
low:list, # k线的最低价
close:list, # k线的收盘价
volume:list): # k线的成交量
#通过循环赋值 给初始化创建的序列传值;
#这里的 self.bufferArray[0] 等于 self.bufferObj 用这两个对象去赋值,都能成功为该对象赋值;
#从上往下,先在data_init中init的部分为self.bufferArray[0],第二个为self.bufferArray[1],之后依次排序
for i in range(rates_total):
#给指标输出对象第一个序列赋值: 单均线公式(开盘价+收盘价2倍+最高价)/4
self.bufferArray[0][i] = (open[i] + close[i]*2 + high[i]) / 4
#给指标输出对象第二个序列赋值:5倍均线
self.bufferArray[1][i] = sum(close[i:i+5])/5
...
具体示例如下图:
编写代码如下:
xxxxxxxxxx
def data_calculate(self,rates_total:int, #数据长度
time:list, # k线的时间集合
open:list, # k线的开盘价
high:list, # k线的最高价
low:list, # k线的最低价
close:list, # k线的收盘价
volume:list): # k线的成交量
#通过循环赋值 给初始化创建的序列传值;
for i in range(rates_total):
#给指标输出对象第一个序列赋值: 单均线公式(开盘价+收盘价2倍+最高价)/4
self.buffer_line1[i] = (open[i] + close[i]*2 + high[i]) / 4
#给指标输出对象第二个序列赋值:5倍均线
self.buffer_line2[i] = sum(close[i:i+5])/5
...
具体示例如下图:
(3)保存指标代码
对两条线进行赋值后,此例的指标编写完成,点击左上方[文件],在选项中选择[保存],也可以直接Ctrl+s进行保存
根据您的编写偏好,您可以选择将默认注释内容删掉或保留,不会影响麦语言的编写,下文以删掉注释内容为例
(1)设置主图叠加
编写代码如下:
{1.设置主图叠加}
IsMainIndex:=myinput(1);
具体示例如下图:
(2)设置外置参数
以文华ENV指标为例,需要两个参数(N1,N2),文华对参数进行了最大值和最小值限制,但期魔方麦语言编辑器未对最大值和最小值做出限制,只要符合您的指标设计思路,都可以填入
具体说明如下图:
编写代码如下:
xxxxxxxxxx
{1.设置主图叠加}
IsMainIndex:=myinput(1);
{2.设置外置参数}
{对N1,N2两个参数进行赋值}
N1:=myinput(14);
N2:=myinput(6);
{将指标公式输入进去}
UPPER : MA(CLOSE,N1)*(1+N2/100);
LOWER : MA(CLOSE,N1)*(1-N2/100);
具体示例如下图:
(3)麦语言编译
编写完成后,鼠标右键点击[麦语言编译]
右下角出现[编译通过],即表示编译成功
(4)保存麦语言代码
点击左上方[文件],在选项中选择[保存],也可以直接Ctrl+s进行保存
(1)设置副图叠加
编写代码如下:
{设置附图}
IsMainIndex:=myinput(0);
具体示例如下:
(2)设置外置参数
以文华DBCD指标为例,需要三个参数(N,M,T),文华对参数进行了最大值和最小值限制,但期魔方麦语言编辑器未对最大值和最小值做出限制,只要符合您的指标设计思路,都可以填入
参数说明如下图:
编写代码如下:
xxxxxxxxxx
{设置附图}
IsMainIndex:=myinput(0);
{设置外置参数}
{对三个参数进行赋值}
N:=myinput(9);
use_N:=IF(N<5,5,IF(N>100,100,N));
M:=myinput(16);
T:=myinput(76);
{输入指标公式}
BIAS:=(CLOSE-MA(CLOSE,use_N))/MA(CLOSE,use_N);
DIF:=(BIAS-REF(BIAS,M));
DBCD:SMA(DIF,T,1);
MM:MA(DBCD,5);
具体示例如下图:
(3) 麦语言编译
编写完成后,鼠标右键点击[麦语言编译]
右下角出现[编译通过],即表示编译成功
(4)保存麦语言代码
点击左上方[文件],在选项中选择[保存],也可以直接Ctrl+s进行保存
策略说明:当上一个K线收线时,收盘价大于开盘价,则开启多单;当上一个K线收线时,收盘价小于开盘价,则开启空单
(1)返回k线数量
编写代码如下:
xxxxxxxxxx
#阳线做多,阴线做空策略
#初始化BAR_DATA变量
BAR_DATA=0
#初始策略函数 每次开启只运算一次
def onInit():
...
#返回k线函数,一根k线开一单
bar=mf_engine.bars()
#每个行情的新报价会运行一次,是任务的核心函数,每个任务必须包含,无参数
def onTick():
...
# 结束函数 每次任务结束会调用一次; 可以执行一些结尾统计操作;
def onStop():
...
具体示例如下图:
(2)获取k线数据
编写代码如下:
xxxxxxxxxx
#阳线做多,阴线做空策略
#初始化BAR_DATA变量
BAR_DATA=0
#初始策略函数 每次开启只运算一次
def onInit():
...
#返回k线数量函数,一根k线开一单
bar=mf_engine.bars()
#只有新的k线出现,才会继续运行一次
if BAR_DATA>=bar:
return
#获取k线收盘价与开盘价序列,按时间顺序获得(最新的值在最后,最老的值在前面)
#引入获取k线数据函数mf_engine.getKline
closearray=mf_engine.getKline(mf_engine.mFsymbol,mf_engine.mFexchange,mf_engine.mFperiod,"close",10)
openarray=mf_engine.getKline(mf_engine.mFsymbol,mf_engine.mFexchange,mf_engine.mFperiod,"open",10)
#每个行情的新报价会运行一次,是任务的核心函数,每个任务必须包含,无参数
def onTick():
...
# 结束函数 每次任务结束会调用一次; 可以执行一些结尾统计操作;
def onStop():
...
具体示例如下图:
(3)判断阴阳线
编写代码如下:
xxxxxxxxxx
#阳线做多,阴线做空策略
#初始化BAR_DATA变量
BAR_DATA=0
#初始策略函数 每次开启只运算一次
def onInit():
...
#返回k线函数,一根k线开一单
bar=mf_engine.bars()
#只有新的k线出现,才会继续运行一次
if BAR_DATA>=bar:
return
#获取k线收盘价与开盘价序列,按时间顺序获得(最新的值在最后,最老的值在前面)
#引用获取k线数据函数mf_engine.getKline
closearray=mf_engine.getKline(mf_engine.mFsymbol,mf_engine.mFexchange,mf_engine.mFperiod,"close",10)
openarray=mf_engine.getKline(mf_engine.mFsymbol,mf_engine.mFexchange,mf_engine.mFperiod,"open",10)
#从倒数第二根k线获取数据,最新的k线数据不稳定
if len(closearray)<2:
return
#阳线:倒数第二根k线收盘价大于开盘价
is_up=closearray[-2]>openarray[-2]
#阴线:倒数第二根k线收盘价低于开盘价
is_down=closearray[-2]<openarray[-2]
#每个行情的新报价会运行一次,是任务的核心函数,每个任务必须包含,无参数
def onTick():
...
# 结束函数 每次任务结束会调用一次; 可以执行一些结尾统计操作;
def onStop():
...
具体示例如下图:
(4)获取开仓价格,进行开单
完整编写代码如下:
xxxxxxxxxx
#阳线做多,阴线做空策略
#初始化BAR_DATA变量
BAR_DATA=0
#初始策略函数 每次开启只运算一次
def onInit():
...
#返回k线函数,一根k线开一单
bar=mf_engine.bars()
#只有新的k线出现,才会继续运行一次
if BAR_DATA>=bar:
return
#获取k线收盘价与开盘价序列,按时间顺序获得(最新的值在最后,最老的值在前面)
#引用获取k线数据函数mf_engine.getKline
closearray=mf_engine.getKline(mf_engine.mFsymbol,mf_engine.mFexchange,mf_engine.mFperiod,"close",10)
openarray=mf_engine.getKline(mf_engine.mFsymbol,mf_engine.mFexchange,mf_engine.mFperiod,"open",10)
#从倒数第二根k线获取数据,最新的k线数据不稳定
if len(closearray)<2:
return
#阳线
is_up=closearray[-2]>openarray[-2]
#阴线
is_down=closearray[-2]<openarray[-2]
#开仓价格初始化
open_price=0
#如果是阳线,开仓方向为"多",开仓价格为最高价
if is_up:
direction = "多"
open_price = mf_engine.last_tick.HighestPrice
#如果是阴线,开仓方向为"空",开仓价格为最低价
if is_down:
direction = "空"
open_price = mf_engine.last_tick.LowestPrice
#如果开仓价格不等于0,则开单
if open_price!=0:
mf_engine.customOpenOrder(symbol=mf_engine.mFsymbol,\
price=open_price,volume=1,priceType="市价",direction=direction ,offset = "0")
#每个行情的新报价会运行一次,是任务的核心函数,每个任务必须包含,无参数
def onTick():
...
# 结束函数 每次任务结束会调用一次; 可以执行一些结尾统计操作;
def onStop():
...
具体示例如下图:
(5)保存策略代码
阳线做多,阴线做空的策略编写完成,点击左上方[文件],在选项中选择[保存],也可以直接Ctrl+s进行保存
下载地址:https://www.qmfquant.com/#/product
进入下载网页后,双击[软件下载]
期魔方量化投研平台仅支持电脑端运行,且电脑配置需要在win7及以上操作系统,2核4G以上配置,在安装前,请确认您的电脑配置
点击软件下载后,若电脑有360或其他杀毒软件,会遭到拦截,此时需要点击信任即可(以Edeg浏览器作为案例)
如果出现以上提示,请点击右键后点击[保留]
在详细信息中点击[仍然保留]信任后即可开始安装
待软件下载成功后,在下载任务栏中双击[打开文件]
文件打开后,双击[下一步]进入安装
在准备安装页面中点击[安装],开始进行安装
初次安装时,需耐心等待此界面进度条完成后代表完成安装
如果您的电脑安装有360等杀毒软件,可能会阻止期魔方客户端的安装和运行,可以选择终止其运行或卸载。
在完成安装后,PC端会自动弹出登录窗口,如下图
如果没有自动弹出登录窗口,请您在电脑桌面找到期魔方客户端快捷方式,双击打开它
如果您是初次登录,没有期魔方账号,则需在登录窗口双击[注册]
在双击[注册]后,会自动进入魔方商学院注册界面,点击[立即注册]进入注册页面,如下图
在注册页面中,设置您的用户名,最好是用英文名或是您中文名的拼音,在后续登录期魔方客户端中更不易出错
输入正确的手机号后,会弹出人机验证窗口,向右准确滑动后,系统会自动发送验证码
在手机短信中查看验证码,复制或记住数字,输入验证码
在验证码正确输入后,设置您的登录密码,一定要记住您的密码
提交注册信息后,魔方学院会显示账户信息,则表示账号注册成功
如果账号注册成功或者本身已有账号,则可打开期魔方客户端窗口,输入您的账号密码,账号可以是您注册时设置的用户名或者电话号码,正确输入完成后即可双击登录
在登录过程中,可能会出现提示[连接获取品种的网络查询接口超时],此时点确定即可继续完成登录
如果您想修改密码,点击魔方学院网址(https://academy.qmfquant.com/user/account),在用户中心中双击[账户安全],如下图
双击[修改密码]即可开始修改密码,要输入您的旧密码和新密码后,双击[确认提交],即可完成修改密码
如果您忘记了原密码,双击修改密码窗口的[忘记原密码,重设密码]
此时需要您输入绑定的手机号码,以及新的密码,输入完成后点击[确认提交]即可成功修改密码
您在用微信登录期魔方官方网站前,应进行微信账号的绑定,在魔方学院—账户安全页面中点击微信绑定,如下图
用您的微信扫描二维码后自动进入期魔方公众号界面,点击关注公众号,如下图
关注期魔方公众号后,点击发消息,如下图
进入消息页面后,发送“验证码”,即可得到验证码,记住验证码在300秒内正确输入到验证码中,点击绑定,即可完成微信绑定
完成微信账号绑定后,在魔方商学院登录中可以选择微信社交账号登录,如下图
进入扫码登录界面,扫描二维码,向期魔方公众号发送“验证码”消息,得到验证码在300秒内正确输入后,点击[登录]即可完成微信登录
在指标列表中,点击右上方[导入],在导入窗口中选择您想导入的python或my-language语言
选择导入语言后,点击您想导入的文件,点击[打开]
页面中出现导入成功即可
在行情界面中,点击[导出]选择您要导出的文档,记住上方的打开路径,然后点击打开
打开后,会弹出此电脑文件,需要根据您之前的路径依次点进去后,找到文件后,点击[选择文件夹]
选择后,页面出现导出成功即可
在行情页面,点击右上方指标图形,弹出指标面板后,在自编指标中选择您想要运行的指标,点击三个小点后双击[加载指标]
指标运行成功后,会显示在实时行情K线图中,方便您进行观察分析
方式一:在行情页面,点进指标面板,对您想编辑的指标进行编辑,自动跳转到vscode编辑器
(只有自编指标且加载后才能进行编辑)
方式二:在策略页面,对您想编辑的指标点击[编辑],即可自动跳转至vscode编辑器页面
第一步,点期魔方客户端右下角,[登录] 按钮
第二步,选择自己的期货公司,并输入自己的期货账户和密码,执行登录
第三步,出现持仓面板弹窗后,登录完成
在持仓面板右上角点击[设置],进入期货账号管理窗口中,如下图
点击账号管理右下方的添加账号
输入您想添加的账号的信息,点击登录或完成,这个账号必须真实存在并绑定在对应期货公司中,否则无法登录成功
如果您已添加多个账户,在切换账户时,先点击您想登录的另一个期货账号前的选项,先选中它,然后点击登录
在期魔方客户端右上方点击设置
进入消息设置窗口,先点击邮件消息的选项后,点击邮箱配置
在邮箱配置中,输入您的邮箱地址后,点击测试,邮箱收到测试消息后点击确定即可完成邮箱绑定
在消息设置窗口,先点击微信消息的选项后,点击微信配置
输入您微信绑定的电话号码,点击确定后即可完成微信绑定
点击测试,企业微信收到消息绑定成功后,即绑定成功
完成绑定后,根据您想要收到的消息内容进行选择
在期魔方客户端平台点击上方回测板块,添加回测
并根据您想要回测的交易品种、测试资金及开始结束时间等来对回测基础参数进行设置,设置完成后点击保存即可在后续进行回测
设置好参数后,点击[回测],待回测进度条完成100%后或者右上方提示,即可点击[详情]查看回测报告
在回测报告中,您可以根据您想要了解的部分进行针对性的查看,也可以进行一个较为综合的查看分析。与此同时,回测报告包含了综合报告、收益回撤、资金风险、图表分析和明细详情等五大板块的内容,致力于为您提供较为详尽的回测分析,以期帮助您的投资决策
如果您设置的回测开始时间是比回测结束时间更近的年份,则回测进度将为0并提示未获得该时段的数据
此时您需要将开始时间和结束时间重新设置一下,点击[编辑参数]进入回测参数设置窗口
重新编辑参数,使开始时间早于结束时间,保存后即可进行回测
如果您选择回测的产品合约生效的时间少于开始时间到结束时间的时间间隔,不会影响回测的进行,但回测的信号起始时间是该产品合约生效开始交易的时间
在任务添加之前,必须登录期货账号任务才能运行,并且您设置的任务账号需与您登录的期货账号一致,如下图:登录的是226714的账号,task-01任务不能执行,因为其账号为185193
进入任务界面中,查看您添加的策略是否在策略列表中,双击您想添加的策略列表中[我的策略]的任意一个策略,进入添加任务窗口
设置好默认参数和外置参数后,点击提交后,添加任务成功
选择一个您想运行的任务,点击[启动]
任务启动后会出现实时行情K线图
您可在任务实时K线图中加载您需要的指标,点击实时K线图右上方的指标按钮,选择您想嵌入的指标,加载指标后即可显示在K线图中
如果您想同时启动多个任务,则直接点击多个任务的[启动]按钮,点击不同任务即可完成任务切换
- 任务启动后,若在盘中时间,则实时K线会更新,若不在盘中时间,则实时K线会停留在上一个收盘时间
- 修改和删除任务只能在任务未启动时进行
在期魔方客户端中点击训练模块,右下角点击设置,进入训练参数设置
初始资金,应不低于最小保证金金额
滑点损耗(输入0则不启用此参数)
保证金比例(默认读取交易所标准保证金比例,可以不用额外设置)
K线数量,默认不超过8000根,具体需要根据合约长度计算
开始时间,默认为从今天开始往前推根K线的时间,和K线根数设置二选一
在时间设置中,您可选择[Now]选项,则定位到现在的时间为初始训练时间,也可已在日期中选择任意时间作为训练开始时间
设置好训练参数后,点击[保存设置]即可
方式一:在训练模块左下角选择您想训练的品种,以及手数等,进行买多或卖空等操作
方式二:按键盘A~Z二十六个字母中任意一个,启动键盘精灵,在键盘精灵中搜索您想选择的交易品种
在训练页面中,在三个小窗口中可以选择不同的训练周期
所有参数都设置好后,点击右下角的的启动按钮,开始进行训练
待训练进度完成100%后,点击[数据分析]进入盘手训练数据报告
一旦弹出提示“后端接口服务已经中止运行”内容,意味这后端的server没有启动成功,首先才检查操作系统为window10以前的操作系统,目前暂时不支持win7,如果低操作系统版本,需要购买云windows服务器,并安装的是window10以上的操作系统
若第一次登录实盘账户时出现下图提示,请联系客服或客户经理开通权限
可以直接联系与您对接的客服或客户经理,也可以在期魔方官网(https://qmfquant.com/#/)的首页,下滑至最下端,扫描官方公众号和官方客服号二维码来联系我们
- SQLiteSpy是一款允许用户查看自己电脑中的sqlist3数据库.db文件的查看工具, 主要支持:.sqlite3、.db3、sqlite、.db四种格式数据库文件的查看
- SQLiteSpy官方下载地址:https://www.yunqa.de/delphi/apps/sqlitespy/index
- 进入官网后,在页面中点击【Download win32&win64】开始下载
下载栏中弹出提示,点击[打开]
打开后会跳转到SQLiteSpy的压缩包
先解压文件,选择您想解压到的文件夹目录后,点击[确定]
打开您解压的文件夹,如果您的电脑是64位处理器,则点击win64的文件,如果您的电脑是32位处理器,则点击win32文件,进入文件之后,双击SQLiteSpy.exe打开软件
软件打开后的界面如下图:
点击[File],进入选择窗口,点击[Open Database]进入文件选择
按照此路径选择文件并打开:C:\Users\(你的用户名)\AppData(看不到的话勾上显示隐藏文件)\Local\Microsoft\Windows\Notifications\wpndatabase.db
以本电脑为例,文件路径选择为:C:\Users\Administrator\AppData\Local\Microsoft\Windows\Notifications
找到[NotificationHandler],鼠标右键点击[Show Data]
在右边侧栏中找到名称[期魔方],点击它,获取它的RecordId并记住,以此电脑为例,期魔方ID(RecordId)为:91
找到[HandlerSettings],鼠标右键点击[Show Data]
在右边侧栏找到HandlerId为:91并在其中找到s:toast(注意不是c:toast),在预警信息能正常发送的情况下Value为1,若Value为0则说明预警信息被人工关闭
如果为0,请执行以下操作,进行脚本更新
点击[File],进入选择窗口,点击[New SQL]进入窗口执行
找到新增窗口,输入:UPDATE HandlerSettings SET Value=1 WHERE HandlerId="填入您电脑中期魔方的HandlerId" AND SettingKey='s:toast'
以本电脑为例,期魔方的HandlerId为91,所以在新增窗口输入:UPDATE HandlerSettings SET Value=1 WHERE HandlerId="91" AND SettingKey='s:toast'
点击上方[Execute],在选择窗口点击[Execute SQL]进行执行
键盘输入:win+R,输入命令:regedit,点击确定
将上方地址栏中的地址替换成:HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Notifications\Settings
替换方法:复制地址后按Enter回车键后,在Settings中点击期魔方
在右侧的窗口找到[enabld]项,删除enabld即可收到预警消息(由于本电脑能正常收到预警消息,所以此处并未显示enabld)