void Process::HandleTSTrading( const Quote& quote ) { // m_dblCallPrice = m_iterOILatestGammaSelectCall->Call()->Ask(); m_dblPutPrice = m_iterOILatestGammaSelectPut->second.Put()->Ask(); ptime dt = ou::TimeSource::Instance().Internal(); if ( dt.time_of_day() >= m_dtMarketClosingOrder ) { m_ss.str( "" ); m_ss << dt; m_ss << " State: Close Orders." << std::endl; OutputDebugString( m_ss.str().c_str() ); m_TradingState = ETSCloseOrders; } else { double dblMidQuote = ( quote.Bid() + quote.Ask() ) / 2.0; double dblDeltaPut = m_iterOILatestGammaSelectPut->second.Put()->Delta() * m_posPut->GetRow().nPositionActive * 100; //double dblDeltaCall = m_iterOILatestGammaSelectCall->second.Call()->Delta() * m_nCalls * 100; bool bTraded = false; if ( ( 0.0 != dblDeltaPut ) && !m_posUnderlying->OrdersPending() && !m_posPut->OrdersPending() ) { try { // todo: while implied volatility is rising, hold back on exiting? // todo: while implied volatility is falling, hold back on entering? double dblDeltaTotalUnderlying = m_posUnderlying->GetRow().nPositionActive; if ( ou::tf::OrderSide::Sell == m_posUnderlying->GetRow().eOrderSideActive ) { dblDeltaTotalUnderlying *= -1.0; } double dblDeltaDif = dblDeltaPut + dblDeltaTotalUnderlying; if ( dblDeltaDif > m_dblBaseDeltaIncrement ) { // sell underlying to get closer to put delta //m_posUnderlying->PlaceOrder( OrderType::Market, OrderSide::Sell, m_dblBaseDeltaIncrement / 100 ); // <<=== temporary fix for this simulation set m_posUnderlying->PlaceOrder( OrderType::Market, OrderSide::Sell, m_dblBaseDeltaIncrement ); bTraded = true; m_ss.str( "" ); m_ss << dt; m_ss << " Underlying Sell " << m_dblBaseDeltaIncrement << ", trigger @" << dblMidQuote << std::endl; OutputDebugString( m_ss.str().c_str() ); } else { if ( dblDeltaDif < -m_dblBaseDeltaIncrement ) { // buy underlying to get closer to put delta //m_posUnderlying->PlaceOrder( OrderType::Market, OrderSide::Buy, m_dblBaseDeltaIncrement / 100 ); // <<=== temporary fix for this simulation set m_posUnderlying->PlaceOrder( OrderType::Market, OrderSide::Buy, m_dblBaseDeltaIncrement ); bTraded = true; m_ss.str( "" ); m_ss << dt; m_ss << " Underlying Buy " << m_dblBaseDeltaIncrement << ", trigger @" << dblMidQuote << std::endl; OutputDebugString( m_ss.str().c_str() ); } } } catch ( std::logic_error &e ) { // just catch, don't do anything } if ( bTraded ) { PrintGreeks(); } } } }
void Process::HandleTSMarketOpened( const Quote& quote ) { double dblOpenValue = ( quote.Bid() + quote.Ask() ) / 2.0; // comment our starting trade of the day m_ss.str( "" ); m_ss << ou::TimeSource::Instance().Internal(); m_ss << " Opening mid quote: " << dblOpenValue << std::endl; OutputDebugString( m_ss.str().c_str() ); // set iterators for center of the pack (crossovers are above and below trade): m_iterAboveCrossOver = m_vCrossOverPoints.begin(); while ( dblOpenValue >= *m_iterAboveCrossOver ) { ++m_iterAboveCrossOver; } m_iterBelowCrossOver = m_iterAboveCrossOver; while ( dblOpenValue <= *m_iterBelowCrossOver ) { --m_iterBelowCrossOver; } // comment our crossover points m_ss.str( "" ); m_ss << "Trade start " << *m_iterBelowCrossOver << ", " << dblOpenValue << ", " << *m_iterAboveCrossOver << std::endl; OutputDebugString( m_ss.str().c_str() ); // calculate where to have put/call option watches, // have a range of strikes above and below current trade (have maximum 100 watches available) m_iterOIHighestWatch = m_mapStrikeInfo.begin(); while ( (m_iterOIHighestWatch->first) <= dblOpenValue ) { ++m_iterOIHighestWatch; } m_iterOILowestWatch = m_iterOIHighestWatch; --m_iterOILowestWatch; for ( int i = 0; i < 15; ++i ) { if ( m_mapStrikeInfo.begin() != m_iterOILowestWatch ) { --m_iterOILowestWatch; } if ( m_mapStrikeInfo.end() != m_iterOIHighestWatch ) { ++m_iterOIHighestWatch; } } // set the actual watches m_bWatchingOptions = true; if ( keytypes::EProviderSimulator != m_pDataProvider->ID() ) { for ( mapStrikeInfo_iter_t iter = m_iterOILowestWatch; iter != m_iterOIHighestWatch; ++iter ) { StrikeInfo& oi = iter->second; m_pDataProvider->AddQuoteHandler( oi.Call()->GetInstrument(), MakeDelegate( oi.Call(), &CNakedCall::HandleQuote ) ); m_pDataProvider->AddTradeHandler( oi.Call()->GetInstrument(), MakeDelegate( oi.Call(), &CNakedCall::HandleTrade ) ); m_pDataProvider->AddGreekHandler( oi.Call()->GetInstrument(), MakeDelegate( oi.Call(), &CNakedCall::HandleGreek ) ); m_pDataProvider->AddQuoteHandler( oi.Put()->GetInstrument(), MakeDelegate( oi.Put(), &CNakedPut::HandleQuote ) ); m_pDataProvider->AddTradeHandler( oi.Put()->GetInstrument(), MakeDelegate( oi.Put(), &CNakedPut::HandleTrade ) ); m_pDataProvider->AddGreekHandler( oi.Put()->GetInstrument(), MakeDelegate( oi.Put(), &CNakedPut::HandleGreek ) ); } } m_TradingState = ETSFirstTrade; }