金字塔决策交易系统

 找回密码
 

微信登录

微信扫一扫,快速登录

搜索
查看: 2955|回复: 11

可够帮我把这段代码转换成金字塔

[复制链接]

12

主题

58

帖子

68

积分

Rank: 4

等级: 专业版

注册:
2022-10-26
曾用名:
发表于 2023-5-5 11:01 | 显示全部楼层 |阅读模式
/*backtest
start: 2021-06-01 00:00:00
end: 2021-07-01 23:59:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
mode: 1
*/


var NewFuturesTradeFilter = function(period) {
    var self = {} // 创建一个对象

    self.c = Chart({ // 创建Chart图表
        chart: {
            zoomType: 'x', // 缩放
            backgroundColor: '#272822',
            borderRadius: 5,
            panKey: 'shift',
            animation: false,
        },
        plotOptions: {
            candlestick: {
                color: '#00F0F0',
                lineColor: '#00F0F0',
                upColor: '#272822',
                upLineColor: '#FF3C3C'
            },
        },
        tooltip: {
            xDateFormat: '%Y-%m-%d %H:%M:%S, %A',
            pointFormat: '{point.tips}',
            borderColor: 'rgb(58, 68, 83)',
            borderRadius: 0,
        },
        series: [{
            name: exchange.GetName(),
            type: 'candlestick',
            data: []
        }],
        yAxis: {
            gridLineColor: 'red',
            gridLineDashStyle: 'Dot',
            labels: {
                style: {
                    color: 'rgb(204, 214, 235)'
                }
            }
        },
        rangeSelector: {
            enabled: false
        },
        navigation: {
            buttonOptions: {
                height: 28,
                width: 33,
                symbolSize: 18,
                symbolX: 17,
                symbolY: 14,
                symbolStrokeWidth: 2,
            }
        }
    })
    self.c.reset() // 清空图表数据

    self.pre = null // 用于记录上一个数据
    self.records = []
    arr = []
    lastTime = 0
    self.feed = function(ticker, contractCode) {
        if (!self.pre) { // 如果上一个数据不为真
            self.pre = ticker // 赋值为最新数据
        }
        var action = '' // 标记为空字符串
        if (ticker.Last >= self.pre.Sell) { // 如果最新数据的最后价格大于等于上一个数据的卖价
            action = 'buy' // 标记为buy
        } else if (ticker.Last <= self.pre.Buy) { // 如果最新数据的最后价格小于等于上一个数据的买价
            action = 'sell' // 标记为sell
        } else {
            if (ticker.Last >= ticker.Sell) { // 如果最新数据的最后价格大于等于最新数据的卖价
                action = 'buy' // 标记为buy
            } else if (ticker.Last <= ticker.Buy) { // 如果最新数据的最后价格小于等于最新数据的买价
                action = 'sell' // 标记为sell
            } else {
                action = 'both' // 标记为both
            }
        }
        // reset volume
        if (ticker.Volume < self.pre.Volume) { // 如果最新数据的成交量小于上一个数据的成交量
            self.pre.Volume = 0 // 把上一个数据的成交量赋值为0
        }
        var amount = ticker.Volume - self.pre.Volume // 最新数据的成交量减去上一个数据的成交量
        if (action != '' && amount > 0) { // 如果标记不为空字符串,并且action大于0
            var epoch = parseInt(ticker.Time / period) * period // 计算K线时间戳并取整
            var bar = null
            var pos = undefined
            if (
                self.records.length == 0 || // 如果K线长度为0或者最后一根K线时间戳小于epoch
                self.records[self.records.length - 1].time < epoch

            ) {
                bar = {
                    time: epoch,
                    data: {},
                    open: ticker.Last,
                    high: ticker.Last,
                    low: ticker.Last,
                    close: ticker.Last
                } // 把最新的数据赋值给bar
                self.records.push(bar) // 把bar添加到records数组中
            } else { // 重新给bar赋值
                bar = self.records[self.records.length - 1] // 上一个数据最后一根K线
                bar.high = Math.max(bar.high, ticker.Last) // 上一个数据最后一根K线的最高价与最新数据最后价格的最大值
                bar.low = Math.min(bar.low, ticker.Last) // 上一个数据最后一根K线的最低价与最新数据最后价格的最小值
                bar.close = ticker.Last // 最新数据的最后价格
                pos = -1
            }
            if (typeof bar.data[ticker.Last] === 'undefined') { // 如果数据为空
                bar.data[ticker.Last] = { // 重新赋值
                    buy: 0,
                    sell: 0
                }
            }
            if (action == 'both') { // 如果标记等于both
                bar.data[ticker.Last]['buy'] += amount // buy累加
                bar.data[ticker.Last]['sell'] += amount // sell累加
            } else {
                bar.data[ticker.Last][action] += amount // 标记累加
            }
            var initiativeBuy = 0
            var initiativeSell = 0
            var sellLongMax = 0
            var buyLongMax = 0
            var sellVol = 0
            var buyVol = 0
            for (var i in bar.data) {
                sellLong = bar.data[i].sell.toString().length
                buyLong = bar.data[i].buy.toString().length
                if (sellLong > sellLongMax) {
                    sellLongMax = sellLong
                }
                if (buyLong > buyLongMax) {
                    buyLongMax = buyLong
                }
                sellVol += bar.data[i].sell
                buyVol += bar.data[i].buy
            }
            // var date = new Date(bar.time);
            // var Y = date.getFullYear() + '-';
            // var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
            // var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' ';
            // var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
            // var m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + '<br>';
            // var tips = Y + M + D + h + m
            tips = '<b>&#9673; ' + (sellVol + buyVol) + '</b>'
            Object.keys(bar.data) // 将对象里的键放到一个数组中
                .sort() // 排序
                .reverse() // 颠倒数组中的顺序
                .forEach(function(p) { // 遍历数组
                    pSell = bar.data[p].sell
                    pBuy = bar.data[p].buy
                    if (pSell > pBuy) {
                        arrow = ' ▼ '
                    } else if (pSell < pBuy) {
                        arrow = ' ▲ '
                    } else {
                        arrow = ' &#9830; '
                    }
                    initiativeSell += pSell
                    initiativeBuy += pBuy
                    sellLongDiff = sellLongMax - pSell.toString().length
                    buyLongDiff = buyLongMax - pBuy.toString().length
                    if (sellLongDiff == 1) {
                        pSell = '0' + pSell
                    }
                    if (sellLongDiff == 2) {
                        pSell = '00' + pSell
                    }
                    if (sellLongDiff == 3) {
                        pSell = '000' + pSell
                    }
                    if (sellLongDiff == 4) {
                        pSell = '0000' + pSell
                    }
                    if (sellLongDiff == 5) {
                        pSell = '00000' + pSell
                    }
                    if (buyLongDiff == 1) {
                        pBuy = '0' + pBuy
                    }
                    if (buyLongDiff == 2) {
                        pBuy = '00' + pBuy
                    }
                    if (buyLongDiff == 3) {
                        pBuy = '000' + pBuy
                    }
                    if (buyLongDiff == 4) {
                        pBuy = '0000' + pBuy
                    }
                    if (buyLongDiff == 5) {
                        pBuy = '00000' + pBuy
                    }
                    code = contractCode.match(/[a-zA-Z]+|[0-9]+/g)[0]
                    if (code == 'IF' || code == 'j' || code == 'IC' || code == 'i' || code == 'ZC' || code == 'sc' || code == 'IH' || code == 'jm' || code == 'fb') {
                        p = parseFloat(p).toFixed(1)
                    } else if (code == 'au') {
                        p = parseFloat(p).toFixed(2)
                    } else if (code == 'T' || code == 'TF' || code == 'TS') {
                        p = parseFloat(p).toFixed(3)
                    } else {
                        p = parseInt(p)
                    }
                    tips += '<br>' + p + ' → ' + pSell + arrow + pBuy

                })
            tips += '<br>' + '<b>&#8855; ' + (initiativeBuy - initiativeSell) + '</b>'
            self.c.add( // 添加数据
                0, {
                    x: bar.time,
                    open: bar.open,
                    high: bar.high,
                    low: bar.low,
                    close: bar.close,
                    tips: tips
                },
                pos
            )
            arr.push({
                'open': bar.open,
                'close': bar.close,
                'diff': initiativeBuy - initiativeSell
            })
            if (arr.length > 2) {
                arr.shift()
            }
            let position = exchange.GetPosition()
            let holdAmount = 0
            let profit = 0
            if (position.length > 0) {
                if (position[0].Type == 0 || position[0].Type == 2) {
                    holdAmount = position[0].Amount
                } else {
                    holdAmount = -position[0].Amount
                }
                profit = position[0].Profit
            }
            if (bar.time != lastTime) {
                lastOpen = arr[0].open
                lastClose = arr[0].close
                diff = arr[0].diff
                lastTime = bar.time
                priceDiff = lastClose - lastOpen
                volDiff = diff
                if (holdAmount == 0 && priceDiff > 0 && volDiff < 0) {
                    Log('多开')
                    exchange.SetDirection("buy")
                    exchange.Buy(arr[1].close, 1)
                }
                if (holdAmount == 0 && priceDiff < 0 && volDiff > 0) {
                    Log('空开')
                    exchange.SetDirection("sell")
                    exchange.Sell(arr[1].close - 1, 1)
                }
                if (holdAmount > 0 && profit > 100) {
                    Log('多平')
                    exchange.SetDirection("closebuy")
                    exchange.Sell(arr[1].close - 1, holdAmount)
                }
                if (holdAmount < 0 && profit > 100) {
                    Log('空平')
                    exchange.SetDirection("closesell")
                    exchange.Buy(arr[1].close, -holdAmount)
                }
            }

        }
        self.pre = ticker // 重新赋值
    }
    return self // 返回对象
}


function main() {
    if (exchange.GetName().indexOf('CTP') == -1) {
        throw "只支持商品期货CTP";
    }
    SetErrorFilter("login|timeout|GetTicker|ready|流控|连接失败|初始|Timeout");
    while (!exchange.IO("status")) {
        Sleep(3000);
        LogStatus("正在等待与交易服务器连接, " + _D());
    }
    symbolDetail = _C(exchange.SetContractType, contractCode) // 订阅数据
    Log('交割日期:', symbolDetail['StartDelivDate'])
    Log('最小下单量:', symbolDetail['MaxLimitOrderVolume'])
    Log('最小价差:', symbolDetail['PriceTick'])
    Log('一手:', symbolDetail["VolumeMultiple"], '份')
    Log('合约代码:', symbolDetail['InstrumentID'])
    var filt = NewFuturesTradeFilter(60000) // 创建一个对象
    while (true) { // 进入循环模式
        while (!exchange.IO("status")) {
            Sleep(3000);
            LogStatus("正在等待与交易服务器连接, " + _D());
        }
        LogStatus("行情和交易服务器连接成功, " + _D());
        var ticker = exchange.GetTicker() // 获取交易所Tick数据
        if (ticker) { // 如果成功获取到Tick数据
            filt.feed(ticker, contractCode) // 开始处理数据
        }
    }
}


回复

使用道具 举报

2

主题

580

帖子

621

积分

Rank: 9Rank: 9Rank: 9

等级: 管理员

注册:
2021-5-10
曾用名:
发表于 2023-5-5 11:03 | 显示全部楼层
抱歉这个没有办法直接转换
您可以把思路用中文描述下,工作人员根据中文描述帮您编写
回复

使用道具 举报

12

主题

58

帖子

68

积分

Rank: 4

等级: 专业版

注册:
2022-10-26
曾用名:
 楼主| 发表于 2023-5-5 11:15 | 显示全部楼层
好的,这是一个订单流买卖策略,在其他平台上可以运行
先构建成交痕迹(足迹图)定义堆积异常情况,然后理论上当买方成交量大于卖方成交量,价格就会上涨;当卖方成交量大于买方成交量,价格就会下跌。
接下来我们利用买卖均衡与价格背离这种现象,以下是策略逻辑:

多头开仓:如果当前无持仓,并且收盘价大于开盘价,并且主动买量小于主动卖量
空头开仓:如果当前无持仓,并且收盘价小于开盘价,并且主动买量大于主动卖量
多头平仓:如果有多头持仓,并且利润超过100
空头平仓:如果有空头持仓,并且利润超过100
回复

使用道具 举报

12

主题

58

帖子

68

积分

Rank: 4

等级: 专业版

注册:
2022-10-26
曾用名:
 楼主| 发表于 2023-5-5 11:18 | 显示全部楼层
或者金字塔开放订单流价格失衡的函数或者特征给我们自己编写策略也行


补充内容 (2023-5-5 11:18):
回复

使用道具 举报

12

主题

58

帖子

68

积分

Rank: 4

等级: 专业版

注册:
2022-10-26
曾用名:
 楼主| 发表于 2023-5-5 11:20 | 显示全部楼层
这是示例的图片

26170620_6177c50c670bb64140.webp

94.19 KB, 下载次数: 1460

回复

使用道具 举报

2

主题

580

帖子

621

积分

Rank: 9Rank: 9Rank: 9

等级: 管理员

注册:
2021-5-10
曾用名:
发表于 2023-5-5 11:21 | 显示全部楼层
if tbuyholding(1)=0 and close>open and DYNAINFO( 18)<DYNAINFO( 19) then tbuy(1,1,mkt)
if tbuyholding(1)>0 and (close-TAVGENTERPRICEEX2('','',0)*MULTIPLIER>100  then tsell(1,1,mkt)

就是简单这样就行了?
回复

使用道具 举报

12

主题

58

帖子

68

积分

Rank: 4

等级: 专业版

注册:
2022-10-26
曾用名:
 楼主| 发表于 2023-5-5 14:04 | 显示全部楼层
admin 发表于 2023-5-5 11:21
if tbuyholding(1)=0 and close>open and DYNAINFO( 18)0 and (close-TAVGENTERPRICEEX2('','',0)*MULTIPLI ...

这样不行,没有引用到多空平衡的异常堆积,不是简单的主动买量大于主动卖量,需要引用一分钟之内,同一个价格上横向累计算对比主动买量大于主动卖量,您的这个对比无法统计一分钟或者更大周期的在某一价格上的对比
回复

使用道具 举报

12

主题

58

帖子

68

积分

Rank: 4

等级: 专业版

注册:
2022-10-26
曾用名:
 楼主| 发表于 2023-5-5 14:12 | 显示全部楼层
我需要引用或者描述成交痕迹中满足绿色或者红色条件的表述应该怎么写呢?
e84e46e976988da33b9baf549e5130c4_103616rokkgyn6o5unjvuk.png
927dfbc3ce97f249de7b3df6348f102.jpg
回复

使用道具 举报

3

主题

2万

帖子

2万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-24
曾用名:
发表于 2023-5-5 14:12 | 显示全部楼层
这个目前没有办法直接获取这个的
金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

12

主题

58

帖子

68

积分

Rank: 4

等级: 专业版

注册:
2022-10-26
曾用名:
 楼主| 发表于 2023-5-5 14:21 | 显示全部楼层
资深技术02 发表于 2023-5-5 14:12
这个目前没有办法直接获取这个的

那间接获取可以吗?其他的软件可以实现,一楼贴的这段代码就是其他平台实现和引用的方式,或者可以通过PYTHON在金字塔上实现吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 微信登录

本版积分规则

手机版|小黑屋|上海金之塔信息技术有限公司 ( 沪ICP备13035422号 )

GMT+8, 2024-12-22 18:08 , Processed in 0.225414 second(s), 24 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表