量化交易之HFT篇 - long beach - SigDiff.cc

// .cc

#include "SigDiff.h"
#include <boost/assign/list_of.hpp>
#include <longbeach/clientcore/EventDist.h>
#include <longbeach/signals/SignalBuilder.h>
#include <longbeach/signals/SignalsPriority.h>
#include <longbeach/clientcore/PriceProviderBuilder.h>
#include <longbeach/math/dataset.h>
#include <longbeach/math/dataset_stats.h>

namespace longbeach {
namespace signals {

/************************************************************************************************/
// SigDiffSpec
/************************************************************************************************/

SigDiffSpec::SigDiffSpec()
{
    initMembers();
}

void SigDiffSpec::initMembers()
{
    if( !MemberList::m_bInitialized ) {
        MemberList::className("SigDiff");
        MemberList::add( "description", &SigDiffSpec::m_description );
        MemberList::add( "a", &SigDiffSpec::a );
        MemberList::add( "b", &SigDiffSpec::m_refPxP );
        MemberList::m_bInitialized = true;
    }
}

bool SigDiffSpec::registerScripting(lua_State &state)
{
    initMembers();
    LONGBEACH_REGISTER_SCRIPTING_ONCE( state, "longbeach::signals::SigDiffSpec" );
    // each Spec class must be added to registerScripting in Signals_Scripting.cc
    luabind::module( &state )
    [
        luabind::class_<SigDiffSpec, SignalSpec, ISignalSpecPtr>("SigDiffSpec")
            .def( luabind::constructor<>() )
            .def_readwrite("a",    &SigDiffSpec::a)
            .def_readwrite("b",    &SigDiffSpec::m_refPxP)
    ];
    luaL_dostring( &state, (MemberList::className() + "=SigDiffSpec").c_str() );
    return true;
}

void SigDiffSpec::getDataRequirements(IDataRequirements *rqs) const
{
    SignalSpec::getDataRequirements(rqs);
    a->getDataRequirements(rqs);
}

void SigDiffSpec::checkValid() const
{
    SignalSpec::checkValid();
    a->checkValid();
}

ISignalPtr SigDiffSpec::build( SignalBuilder* builder ) const
{
    IPriceProviderPtr a_obj = builder->getPxPBuilder()->buildPxProvider(a);
    IPriceProviderPtr b_obj = builder->getPxPBuilder()->buildPxProvider(m_refPxP);
    return ISignalPtr(new SigDiff( builder->getClientContext(), a_obj, b_obj, getDescription(), builder->getVerboseLevel()));
}

/************************************************************************************************/
// SigDiff
/************************************************************************************************/
SigDiff::SigDiff( const ClientContextPtr& cc, const IPriceProviderPtr& a, const IPriceProviderPtr& b, const std::string& desc, bool vbose)
    : SignalSmonImpl( a->getInstrument(), desc, cc->getClockMonitor(), vbose )
    , m_spED(cc->getEventDistributor())
    , m_evalPriority(PRIORITY_SIGNALS_Signal)
    , m_a(a)
    , m_b(b)
    , m_bEvalScheduled(false)
    , m_tw(seconds(5))
{
    using namespace boost::assign;
    initSignalStates( list_of("d0")("avg") );

    Subscription sub;
    m_a->addPriceListener( sub, boost::bind( &SigDiff::onInputChange, this, _1 ) );
    m_subs.push_back(sub);
    m_b->addPriceListener( sub, boost::bind( &SigDiff::onInputChange, this, _1 ) );
    m_subs.push_back(sub);
}

void SigDiff::onInputChange( const IPriceProvider& pxp )
{
    if(pxp.isPriceOK()) {
        if(!m_bEvalScheduled) {
            LONGBEACH_ASSERT( m_spED->getEventContext().workerPriority() > m_evalPriority );
            m_bEvalScheduled = m_spED->addWork( boost::bind( &SigDiff::eval, this ), m_evalPriority );
        }
    }
}

void SigDiff::eval()
{
    bool ok_a = m_a->isPriceOK();
    bool ok_b = m_b->isPriceOK();
    if( ok_a && ok_b ) {
        double px_a = m_a->getRefPrice();
        double px_b = m_b->getRefPrice();
        double value = px_a - px_b;
        TimeWindow<double>::Entry e( getClockMonitor()->getTime(), value );
        m_tw.push_end(e);
        m_tw.flush_start();

        setDirty(true);
        setOK(true);
        notifySignalListeners();
    } else { // not ok
        if(isOK()) {
            setOK(false);
            notifySignalListeners();
        }
    }
    
    m_bEvalScheduled = false;
}

void SigDiff::recomputeState() const
{
    if(isOK()) {
        // we only get here if a && b
        bool ok_a = false;
        bool ok_b = false;
        double px_a = m_a->getRefPrice(&ok_a);
        double px_b = m_b->getRefPrice(&ok_b);
        if( ok_a && ok_b ) {
            double value = px_a - px_b;
            datasetT<double> points;
            BOOST_FOREACH( const TimeWindow<double>::Entry& e, m_tw.data() ) {
                points->push_back(e.data());
            }
            double avg = mean(points);

            setSignalState( 0, value );
            setSignalState( 1, avg );
            setDirty(false);
        }
    } else {
        setSignalState( 0, 0 );
        setDirty(false);
    }
}

} // namespace signals
} // namespace longbeach

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值