期货交易支持传统商品期货CTP协议和易盛协议。执行任何操作前必须先使用```exchange.SetContractType()```函数设置合约代码。
```exchange.SetContractType()```函数返回一个结构体,其中包含合约的详细信息,例如:最小下单合约张数、手续费、交割时间等数据。
打印```exchange.SetContractType("MA888")```函数返回的数据,即合约详细信息如下:
```json
{
"InstrumentName": "甲醇连续",
"MinLimitOrderVolume": 1,
"OpenDate": "20190116",
"PositionType": 50,
"LongMarginRatio": 0.06999999999999999,
"DeliveryYear": 2020,
"MaxMarketOrderVolume": 1000,
"ExpireDate": "20200114",
"PositionDateType": 50,
"InstLifePhase": 49,
"UnderlyingMultiple": 1,
"CombinationType": 48,
"InstrumentID": "MA001",
"ExchangeInstID": "MA001",
"ProductClass": 49,
"MinMarketOrderVolume": 1,
"VolumeMultiple": 10,
"CreateDate": "20190116",
"ShortMarginRatio": 0.06999999999999999,
"UnderlyingInstrID": "",
"ProductID": "MA",
"PriceTick": 1,
"StartDelivDate": "20200114",
"EndDelivDate": "20200114",
"ExchangeID": "CZCE",
"MaxLimitOrderVolume": 1000,
"MaxMarginSideAlgorithm": 48,
"DeliveryMonth": 1,
"IsTrading": 1,
"StrikePrice": 0,
"OptionsType": 0
}
object
exchange.SetContractType(symbol)
例如:exchange.SetContractType("rb2310")
,作用为设置当前操作的合约为螺纹钢2023年10月交割的合约。
主力连续合约的代码为888
,例如MA888
;连续指数合约的代码为000
,例如MA000
。888
与000
虚拟合约仅支持回测交易,实盘环境下仅支持获取行情数据。
symbol
true
string
function main(){
while(true) {
if (exchange.IO("status")) {
var ret = exchange.SetContractType("MA888")
Log("订阅合约的详细信息:", ret)
break
} else {
LogStatus(_D(), "未连接")
}
}
}```
```python
def main():
while True:
if exchange.IO("status"):
ret = exchange.SetContractType("MA888")
Log("订阅合约的详细信息:", ret)
break
else:
LogStatus(_D(), "未连接")```
```cpp
void main() {
while(true) {
if(exchange.IO("status") == 1) {
auto ret = exchange.SetContractType("MA888");
Log("订阅合约的详细信息:", ret);
break;
} else {
LogStatus(_D(), "未连接");
}
}
}```
使用```exchange.SetContractType()```函数设置(订阅)合约。
```javascript
function main(){
var n = 0
while(true){
// 需要在判断exchange.IO("status")函数返回true,即为真值时才可调用行情、交易等函数
if(exchange.IO("status")){
// 设置合约为虚拟合约,MA888,即甲醇主力合约
var ret = _C(exchange.SetContractType, "MA888")
var ticker = exchange.GetTicker()
// 当到达交易条件时
if(n == 100) {
exchange.SetContractType(ret.InstrumentID)
Log("设置映射的实际合约:", ret.InstrumentID)
exchange.SetDirection("buy")
var id = exchange.Buy(ticker.Buy - 10, 1)
Log("id:", id)
Sleep(1000)
Log(exchange.GetOrder(id))
Sleep(1000)
Log(exchange.GetPositions())
Sleep(1000)
exchange.CancelOrder(id)
Sleep(1000)
Log(exchange.GetOrders())
}
n++
LogStatus(_D(), "已经连接CTP!")
} else {
LogStatus(_D(), "未连接CTP!")
}
}
}```
```python
def main():
n = 0
while True:
if exchange.IO("status"):
ret = _C(exchange.SetContractType, "MA888")
ticker = exchange.GetTicker()
if n == 100:
exchange.SetContractType(ret["InstrumentID"])
Log("设置映射的实际合约:", ret["InstrumentID"])
exchange.SetDirection("buy")
id = exchange.Buy(ticker["Buy"] - 10, 1)
Log("id:", id)
Sleep(1000)
Log(exchange.GetOrder(id))
Sleep(1000)
Log(exchange.GetPositions())
Sleep(1000)
exchange.CancelOrder(id)
Sleep(1000)
Log(exchange.GetOrders())
n += 1
LogStatus(_D(), "已经连接CTP!")
else:
LogStatus(_D(), "未连接CTP!")```
```cpp
void main() {
int n = 0;
while(true) {
if(exchange.IO("status") == 1) {
auto ret = exchange.SetContractType("MA888");
auto ticker = exchange.GetTicker();
if(n == 100) {
exchange.SetContractType(ret["InstrumentID"]);
Log("设置映射的实际合约:", ret["InstrumentID"]);
exchange.SetDirection("buy");
auto id = exchange.Buy(ticker.Buy - 10, 1);
Log("id:", id);
Sleep(1000);
Log(exchange.GetOrder(id));
Sleep(1000);
Log(exchange.GetPositions());
Sleep(1000);
exchange.CancelOrder(id);
Sleep(1000);
Log(exchange.GetOrders());
}
n++;
LogStatus(_D(), "已经连接CTP!");
} else {
LogStatus(_D(), "未连接CTP!");
}
}
}```
商品期货仅在回测时支持虚拟合约交易,实盘时虚拟合约仅支持获取行情。实盘交易时,我们可以使用虚拟合约映射的真实合约进行下单,示例代码如下:
- 主力连续合约(例如rb888):
由该期货品种不同时期的主力合约(价格和成交量)直接拼接而成,代码以888结尾,例如rb888。合约首次上市时,以当日收盘同品种持仓量最大者作为从第二个交易日开始的主力合约。当同品种其他合约持仓量在收盘后超过当前主力合约1.1倍时,则在第二个交易日进行主力合约切换。
- 指数合约(例如rb000):
由该期货品种所有正在交易的合约,以持仓量加权平均计算。
在商品期货策略中调用```exchange.SetContractType(ContractType)```函数时,实盘或**simnow**模拟盘中可能会订阅失败,例如连接期货公司前置机失败或设置了不存在的合约代码时。订阅虚拟合约成功后,返回字段中的```InstrumentID```为主力合约(在订阅时同步获取),便于策略在实盘下单交易时进行映射。
对于不熟悉商品期货合约代码的用户,可以使用以下```JavaScript```代码进行查询:
```js
function main(){
while(true){
if(exchange.IO("status")){
var products_CZCE_Tbl = {
"type" : "table",
"title" : "郑商所 CZCE",
"cols" : ["商品名称(ProductName)", "合约代码短名(ProductID)" , "一跳价格(PriceTick)", "一手合约乘数(VolumeMultiple)", "交易所代码(ExchangeID)"],
"rows" : []
}
var products_DCE_Tbl = {
"type" : "table",
"title" : "大商所 DCE",
"cols" : ["商品名称(ProductName)", "合约代码短名(ProductID)" , "一跳价格(PriceTick)", "一手合约乘数(VolumeMultiple)", "交易所代码(ExchangeID)"],
"rows" : []
}
var products_SHFE_Tbl = {
"type" : "table",
"title" : "上期所 SHFE",
"cols" : ["商品名称(ProductName)", "合约代码短名(ProductID)" , "一跳价格(PriceTick)", "一手合约乘数(VolumeMultiple)", "交易所代码(ExchangeID)"],
"rows" : []
}
var products_other_Tbl = {
"type" : "table",
"title" : "其它",
"cols" : ["商品名称(ProductName)", "合约代码短名(ProductID)" , "一跳价格(PriceTick)", "一手合约乘数(VolumeMultiple)", "交易所代码(ExchangeID)"],
"rows" : []
}
exchange.IO("products").forEach(function(product) {
if (product.ExchangeID == "CZCE") {
products_CZCE_Tbl.rows.push([product.ProductName, product.ProductID, product.PriceTick, product.VolumeMultiple, product.ExchangeID])
} else if (product.ExchangeID == "DCE") {
products_DCE_Tbl.rows.push([product.ProductName, product.ProductID, product.PriceTick, product.VolumeMultiple, product.ExchangeID])
} else if (product.ExchangeID == "SHFE") {
products_SHFE_Tbl.rows.push([product.ProductName, product.ProductID, product.PriceTick, product.VolumeMultiple, product.ExchangeID])
} else {
products_other_Tbl.rows.push([product.ProductName, product.ProductID, product.PriceTick, product.VolumeMultiple, product.ExchangeID])
}
})
LogStatus(_D(), "已经连接CTP", "\n`" + JSON.stringify([products_CZCE_Tbl, products_DCE_Tbl, products_SHFE_Tbl, products_other_Tbl]) + "`")
Sleep(1000 * 60 * 5)
} else {
LogStatus(_D(), "未连接CTP!")
}
Sleep(1000)
}
}
查询结果将显示各交易所的合约信息。 商品期货合约命名规则如下:
前面字母代表品种名称(合约代码简称),后面数字代表合约到期日期。
交易所 | 合约命名规则 |
---|---|
上期所/能源所 | 小写字母 + 4位数字 |
大商所 | 小写字母 + 4位数字 |
中金所 | 大写字母 + 4位数字 |
郑商所 | 大写字母 + 3位数字 |
{@fun/Futures/exchange.GetContractType exchange.GetContractType}