AI量化策略商城核心逻辑实现

策略发布

我们使用Json的方式创建策略,然后直接post到api上进行保存,保存后可以进行回测,两个策略,一个是大类资产配置,另一个是斜率动量/绝对动量加RSRS择时。

def build_slope():
task ={"symbols": ["513100.SH", "159934.SZ", "510880.SH", "159915.SZ"],
"features": ["roc(close,20)","slope_pair(high,low,18)"],
"feature_names": ["roc_20","rsrs_18"],
"rules_buy": [], "rules_sell": ["rsrs_18<0.7"],
"order_by":"roc_20"
}

from quant.services.backtest_utils import run_strategy
return run_strategy(task)

if __name__ == '__main__':
ratio, _ = build_slope()
print(ratio)

年化收益29.5%。

图片

策略已经发布到线上平台:

图片

图片

 

今天使用Django的ModelForm来保存星球会员以及创建论坛bbs问答系统

ModelForm是从Model里直接创建Form,这符合Django的设计理念,就是能固化下来的东西尽量复用。

官网中4.2的例子,就是博客发评论的例子,正好很合适咱们的场景。

https://docs.djangoproject.com/zh-hans/4.2/topics/forms/modelforms/

一般而言,CharField和IntField、FloatField等都会显示文本框。

如果模型字段设置了 choices ,那么表单字段的 widget 会被设置为 Select。——这一点就非常方便,如果前端要自己实现这个内容渲染,然后再读回控件的value,然后还需要把value再对应对choices,还是比较麻烦的。

咱们的星球会员绑定,需要会员名,会员到期日两个字段。

会员名就是普通文本CharField,这个比较简单。而DateField在Django默认是文本框。

头像使用ImageField可以上传图片。

pip install django-bootstrap-datepicker-plus


# File: forms.pyfrom bootstrap_datepicker_plus.widgets import DatePickerInput, TimePickerInput, DateTimePickerInput, MonthPickerInput, YearPickerInputfrom django import forms
class EventForm(forms.ModelForm):    class Meta:        model = Event        fields = ["start_date", "start_time", "start_datetime", "start_month", "start_year"]        widgets = {            "start_date": DatePickerInput(),            "start_time": TimePickerInput(),            "start_datetime": DateTimePickerInput(),            "start_month": MonthPickerInput(),            "start_year": YearPickerInput(),        }

在Meta里使用wigets里覆盖date字段,使用DatePickInput()即可。

另外是文章Article(标题,正文,作者,发布时间,分类)和评论Comment(文章,评论人,评论时间)——文章使用Django-CKEditor。

Django的布署

咱们的AI量化平台,使用django + uvicorn + nginx + docker + docker-compose一起来布署。

FastApi使用的就是uvicorn,一般django使用gunicorn;但gunicorn不支持windows,使用起来也麻烦一点,因此,我们使用uvicorn。

uvicorn myproject.asgi:application --workers=3

本周的核心工作:网站2.0上线,带策略商城和论坛功能。

今日工作: 策略回测,列表页,详情页。

我们创建一个策略表现的model:

class StrategyPerformance(models.Model):
strategy = models.OneToOneField(StrategyInfo, on_delete=models.CASCADE, verbose_name='策略名称')
CAGR = models.FloatField(verbose_name='年化收益', default=-1)
sharpe = models.FloatField(verbose_name='夏普比率', default=-1)
mdd = models.FloatField(verbose_name='最大回撤率', default=-1)

def __str__(self):
return self.strategy.name

class Meta:
verbose_name = '策略表现'
verbose_name_plural = verbose_name

然后api里,任务成功回测完成后,写入表格中:

@api.post('/strategy/run/<task_id>')
def run_task(request, task_id: int):
strategy = StrategyInfo.objects.get(pk=task_id)
if not strategy:
return {'message': '策略:{}不存在'.format(task_id)}

dict_data = strategy.rule_data dict_data['name'] = strategy.name dict_data['desc'] = strategy.desc ratio, df = run_strategy(dict_data) se_task = ratio['market_value'] CAGR = se_task['年化收益'] sharpe = se_task['夏普比率'] mdd = se_task['最大回撤'] p = StrategyPerformance(strategy=strategy) p.CAGR = CAGR p.sharpe = sharpe p.mdd = mdd p.save() return {'message':'策略运行成功!'}

在admin的后台,就可以看到策略运行的结果:

图片

接下来,我们就可以在“策略商城”里,把策略列表展现出来:

商城里展示效果如下:

图片

然后我们来实现策略详情页。

数据准备,我们需要把回测结果保存在mongo数据库里:

df['date'] = df.index
df['date'] = df['date'].apply(lambda x:str(x))
df['pk']=strategy.pk
df['_id'] = str(task_id) + '_' + df['date']
mongo_utils.get_db()['strategy_quotes'].delete_many({'pk': strategy.pk})
mongo_utils.get_db()['strategy_quotes'].insert_many(df.to_dict(orient='records'))
return {'message':'策略运行成功!'}

图片

后台提供查询接口:

@api.get('/strategy_quotes/<pk>')
def strategy_quotes(request, pk: int):
    items = mongo_utils.get_db()['strategy_quotes'].find({'pk': pk}, {'pk': 0, '_id': 0})

return {‘data’: list(items)}

数据很方便就查询出来了:

图片

使用antd的g2来渲染数据:

图片

{% load static %}
<script src="{% static 'js/g2.min.js' %}"></script>
<script>

    $.ajax({
        // 后端程序的url地址
        url: '/api/strategy_quotes/<pk>pk={{item.pk}}',
        // 也可以使用method,提交数据的方式,默认是'GET',常用的还有'POST'
        type: 'get',
        dataType: 'json',  // 返回的数据格式,常用的有是'json','html',"jsonp"
    })
    .done(function(resp) {     // 请求成功以后的操作
        console.log(resp);
        var chart = new G2.Chart({
          container: 'quotes',
          autoFit: true,
          height: 300,
          padding: [30, 20, 70, 30]
        });

        chart.data(resp['data']);
        chart.line().position('date*market_value').color('red')
        chart.line().position('date*基准').color('green')
        chart.render();

    })
    .fail(function(error) {    // 请求失败以后的操作
        console.log(error);
    });


    </script>

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/103493
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!

(0)
股市刺客的头像股市刺客
上一篇 2024 年 7 月 29 日
下一篇 2024 年 7 月 29 日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注