//SCDLLName DO NOT REMOVE
/* ------------------------------------------------------------------------
This program includes : ECIDelta.
Developped by Emmanuel Chriqui (aka wwwingman).
Contact : ecidelta@chriqui.name
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see
The ECIAnchorDelta allows the user to set the start point at any point in the past. It will only work on intraday charts and if bid/ask data is available
" "Developped by Emmanuel Chriqui (aka wwwingman, contact : ecidelta@chriqui.name)
"; //XXconst SCString g_ECIDeltaChannelStudyDescription = //XX"ECIDeltaChannel...
" //XX"Developped by Emmanuel Chriqui (aka wwwingman, contact : ecidelta@chriqui.name)
"; // Sierra DLL name const SCString g_ScDllName = g_DeltaName; SCDLLName (g_ScDllName) // supported period type by ECIVwap enum ECI_PeriodType { ECI_PERIOD_TYPE_DAILY = 0, ECI_PERIOD_TYPE_WEEKLY = 1, ECI_PERIOD_TYPE_MONTHLY = 2, ECI_PERIOD_TYPE_QUARTERLY = 3, ECI_PERIOD_TYPE_YEARLY = 4, }; #define ECI_PERIOD_INPUT_STRINGS "Daily;Weekly;Monthly;Quarterly;Yearly" // misc #define ECIDELTA_MAIN_COLOR RGB(0,128,255) /* ========================================================================== // // Check if a new vwap period need to start (session change/day change...) // // sc : sierra study context // periodType : type of period // startNewPeriod : returned result, true if new period started // ============================================================================ */ void ECIDelta_ComputeNewPeriod(const SCStudyGraphRef sc, const ECI_PeriodType periodType, bool& startNewPeriod) { startNewPeriod = false; if ( sc.Index < 1) // need at least two bars return; // // New period computation is different with daily sessions periods and overnight periods (crossing 00:00) // On daily session we look for the daily start session. // On overnight sessions wek look the next day start session. // SCDateTime currentBarDateTime = sc.BaseDateTimeIn[sc.Index]; int currentBarDate = currentBarDateTime.GetDate(); SCDateTime currentBarTradingStartDateTime = sc.GetStartDateTimeForTradingDate(currentBarDate); int currentBarTradingStartDate = currentBarTradingStartDateTime.GetDate(); SCDateTime previousBarDateTime = sc.BaseDateTimeIn[sc.Index-1]; int previousBarDate= previousBarDateTime.GetDate(); // Handle daily sessions // Date computation is enough for determining start of period if ( currentBarDate == currentBarTradingStartDate ) { int cbPeriod = 0, pbPeriod = 0; // current and previous bar period (# of day/week/month...) switch (periodType) { case ECI_PERIOD_TYPE_DAILY: cbPeriod = currentBarDate; // # of days since December 30, 1899 pbPeriod = previousBarDate; break; case ECI_PERIOD_TYPE_WEEKLY: cbPeriod = currentBarDate / 7; // # of weeks since December 30, 1899 pbPeriod = previousBarDate / 7 ; break; case ECI_PERIOD_TYPE_MONTHLY: cbPeriod = currentBarDateTime.GetMonth(); // # of month in the year pbPeriod = previousBarDateTime.GetMonth(); break; case ECI_PERIOD_TYPE_QUARTERLY: cbPeriod = ((currentBarDateTime.GetMonth()-1) / 3) + 1; // # of quarter in the year, pbPeriod = ((previousBarDateTime.GetMonth()-1) / 3) + 1; break; case ECI_PERIOD_TYPE_YEARLY: cbPeriod = currentBarDateTime.GetYear(); // # of year pbPeriod = previousBarDateTime.GetYear(); break; default: return; // should not be here. } startNewPeriod = (cbPeriod != pbPeriod); } else { // Handle intraday using night sessions // We need the DateTime start period for determining start of period // and then compare it to the current and previous bars // SCDateTime newPeriodBarDateTime = 0; if ( periodType == ECI_PERIOD_TYPE_DAILY ) { // new period is tomorrow start session. // except when market stopped more than 24h if ( currentBarDate - previousBarDate <= 1 ) newPeriodBarDateTime = sc.GetStartDateTimeForTradingDate(currentBarDate+1); else newPeriodBarDateTime = currentBarDateTime; } else if ( periodType == ECI_PERIOD_TYPE_WEEKLY ) { // new period is start of week. // Use GetDate that gives # of days since December 1899 to determine week number int currentBarWeekStartDate = (currentBarDate/7)*7; newPeriodBarDateTime = sc.GetStartDateTimeForTradingDate(currentBarWeekStartDate+1); } else if ( periodType == ECI_PERIOD_TYPE_MONTHLY ) { // new period is tomorrow month start session int yyyy, mm, dd; DATE_TO_YMD(currentBarDate+1, yyyy, mm, dd); int monthStartDate = YMD_DATE(yyyy, mm, 1); newPeriodBarDateTime = sc.GetStartDateTimeForTradingDate(monthStartDate); } else if ( periodType == ECI_PERIOD_TYPE_QUARTERLY ) { // new period is tomorrow quarter start session int yyyy, mm, dd; DATE_TO_YMD(currentBarDate+1, yyyy, mm, dd); int quarterStartDate = YMD_DATE(yyyy, (((mm-1)/3)*3)+1, 1); newPeriodBarDateTime = sc.GetStartDateTimeForTradingDate(quarterStartDate); } else if ( periodType == ECI_PERIOD_TYPE_YEARLY ) { // new period is tomorrow year start session int yyyy, mm, dd; DATE_TO_YMD(currentBarDate+1, yyyy, mm, dd); int yearStartDate = YMD_DATE(yyyy, 1, 1); newPeriodBarDateTime = sc.GetStartDateTimeForTradingDate(yearStartDate); } else // should not be here return; startNewPeriod = ( currentBarDateTime >= newPeriodBarDateTime && previousBarDateTime < newPeriodBarDateTime ); } } /* ========================================================================== // // ECIDelta study // ============================================================================ */ SCSFExport scsf_ECIDelta(SCStudyGraphRef sc) { SCString logMsg; // // subgraphs // SCSubgraphRef _openDelta = sc.Subgraph[SC_OPEN]; SCSubgraphRef _highDelta = sc.Subgraph[SC_HIGH]; SCSubgraphRef _lowDelta = sc.Subgraph[SC_LOW]; SCSubgraphRef _lastDelta = sc.Subgraph[SC_LAST]; // // input // SCInputRef _userPeriodType = sc.Input[0]; // // Initialize configuration variables // if (sc.SetDefaults) { // General sc.GraphName = g_DeltaName + g_StudyVersion; sc.StudyDescription = g_ECIDeltaStudyDescription; // subgraphs sc.ValueFormat = 0; sc.GraphUsesChartColors = true; sc.GraphDrawType = GDT_CANDLESTICK; _openDelta.Name = "Open Delta"; _openDelta.DrawStyle = DRAWSTYLE_LINE; _openDelta.DrawZeros = true; _highDelta.Name = "High Delta"; _highDelta.DrawStyle = DRAWSTYLE_LINE; _highDelta.DrawZeros = true; _lowDelta.Name = "Low Delta"; _lowDelta.DrawStyle = DRAWSTYLE_LINE; _lowDelta.DrawZeros = true; _lastDelta.Name = "Last Delta"; _lastDelta.DrawStyle = DRAWSTYLE_LINE; _lastDelta.DrawZeros = true; // input _userPeriodType.Name = "Delta period type"; _userPeriodType.SetDescription("Delta period type"); _userPeriodType.SetCustomInputStrings(ECI_PERIOD_INPUT_STRINGS); _userPeriodType.SetCustomInputIndex(0); // misc sc.AutoLoop = 1; sc.FreeDLL = DEV_FREE_DLL; sc.MaintainAdditionalChartDataArrays = 1; // for bid/ask data return; } // // Do data processing // ECI_PeriodType& _periodType = (ECI_PeriodType&)sc.PersistVars->Integers[0]; // type of delta period int& _periodStartIndex = sc.PersistVars->Integers[1]; // start of delta period // // initialize // if ( sc.Index == 0 ) { _periodType = (ECI_PeriodType)_userPeriodType.GetInt(); _periodStartIndex = 0; } // // determine if a new delta period starts // bool _startNewPeriod = false; ECIDelta_ComputeNewPeriod(sc, _periodType, _startNewPeriod); if ( _startNewPeriod ) _periodStartIndex = sc.Index; // // compute delta bars data // sc.CumulativeDeltaVolume(sc.BaseDataIn, _lastDelta, sc.Index, _startNewPeriod); _openDelta[sc.Index] = _lastDelta.Arrays[0] [sc.Index]; _highDelta[sc.Index] = _lastDelta.Arrays[1] [sc.Index]; _lowDelta[sc.Index] = _lastDelta.Arrays[2] [sc.Index]; //logMsg.Format("sc.Index=<%d> periodType=<%d>", sc.Index, periodType); //sc.AddMessageToLog(logMsg,0); } /* ========================================================================== // // ECIAnchorDelta study // ============================================================================ */ SCSFExport scsf_ECIAnchorDelta(SCStudyGraphRef sc) { SCString logMsg; // // subgraphs // SCSubgraphRef _openDelta = sc.Subgraph[SC_OPEN]; SCSubgraphRef _highDelta = sc.Subgraph[SC_HIGH]; SCSubgraphRef _lowDelta = sc.Subgraph[SC_LOW]; SCSubgraphRef _lastDelta = sc.Subgraph[SC_LAST]; // // input // SCInputRef _hiddenStartIndex = sc.Input[0]; // just for saving // // Initialize configuration variables // int& _periodStartIndex = sc.PersistVars->Integers[0]; int& _menuID = sc.PersistVars->Integers[1]; if (sc.SetDefaults) { // General sc.GraphName = g_AnchorDeltaName + g_StudyVersion; sc.StudyDescription = g_ECIAnchorDeltaStudyDescription; // subgraphs sc.ValueFormat = 0; sc.GraphUsesChartColors = true; sc.GraphDrawType = GDT_CANDLESTICK; _openDelta.Name = "Open Delta"; _openDelta.DrawStyle = DRAWSTYLE_LINE; _openDelta.DrawZeros = true; _highDelta.Name = "High Delta"; _highDelta.DrawStyle = DRAWSTYLE_LINE; _highDelta.DrawZeros = true; _lowDelta.Name = "Low Delta"; _lowDelta.DrawStyle = DRAWSTYLE_LINE; _lowDelta.DrawZeros = true; _lastDelta.Name = "Last Delta"; _lastDelta.DrawStyle = DRAWSTYLE_LINE; _lastDelta.DrawZeros = true; // input //XXHiddenStartIndex.Name = "Hidden start index"; // used to store start index _hiddenStartIndex.SetInt(INT_MAX); // misc sc.AutoLoop = 1; sc.FreeDLL = DEV_FREE_DLL; sc.MaintainAdditionalChartDataArrays = 1; // for bid/ask data //MenuID = 0; return; } // // Do data processing // // // initilize // if ( sc.Index == 0 ) { // add chart shortcut menu item SCString _menuName; _menuName.Format("Anchor Delta <%d>", sc.StudyGraphInstanceID); //if (_menuID <= 0) // when duplicating chart _menuID is not at 0 _menuID = sc.AddACSChartShortcutMenuItem(sc.ChartNumber, _menuName); if (_menuID < 0) sc.AddMessageToLog("Failed adding Menu Item", 1); _periodStartIndex = _hiddenStartIndex.GetInt(); } // // Update start period if needed // bool _needNewStart = false; if (sc.MenuEventID != 0 && sc.MenuEventID == _menuID) { _needNewStart = true; _periodStartIndex = sc.ActiveToolIndex; _hiddenStartIndex.SetInt(_periodStartIndex); // erase all previous delta values if new period set for (int _i = 0 ; _i <= sc.Index; _i++) _openDelta[_i] = _highDelta[_i] = _lowDelta[_i] = _lastDelta[_i] = 0.f; } if (sc.LastCallToFunction) { // be sure to remove the menu command when study is removed sc.RemoveACSChartShortcutMenuItem(sc.ChartNumber, _menuID); return; } // // draw delta // for (int _i = _periodStartIndex; _i <= sc.Index; _i++) { sc.CumulativeDeltaVolume(sc.BaseDataIn, _lastDelta, _i, _periodStartIndex == _i); _openDelta[_i] = _lastDelta.Arrays[0][_i]; _highDelta[_i] = _lastDelta.Arrays[1][_i]; _lowDelta[_i] = _lastDelta.Arrays[2][_i]; } //logMsg.Format("sc.Index=<%d> periodType=<%d>", sc.Index, periodType); //sc.AddMessageToLog(logMsg,0); } /* ========================================================================== // // ECIDeltaChannel study // ============================================================================ */ /*SCSFExport scsf_ECIDeltaChannel(SCStudyGraphRef sc) { SCString logMsg; // // subgraphs // SCSubgraphRef _openDelta = sc.Subgraph[SC_OPEN]; SCSubgraphRef _highDelta = sc.Subgraph[SC_HIGH]; SCSubgraphRef _lowDelta = sc.Subgraph[SC_LOW]; SCSubgraphRef _lastDelta = sc.Subgraph[SC_LAST]; // // input // SCInputRef _period = sc.Input[0]; // // Initialize configuration variables // if (sc.SetDefaults) { // General sc.GraphName = g_DeltaChannelName + g_StudyVersion; sc.StudyDescription = g_ECIDeltaChannelStudyDescription; sc.GraphRegion = 0; // subgraphs sc.ValueFormat = 0; sc.GraphUsesChartColors = true; sc.GraphDrawType = GDT_CANDLESTICK; _openDelta.Name = "Open Delta"; _openDelta.DrawStyle = DRAWSTYLE_LINE; _openDelta.DrawZeros = true; _highDelta.Name = "High Delta"; _highDelta.DrawStyle = DRAWSTYLE_LINE; _highDelta.DrawZeros = true; _lowDelta.Name = "Low Delta"; _lowDelta.DrawStyle = DRAWSTYLE_LINE; _lowDelta.DrawZeros = true; _lastDelta.Name = "Last Delta"; _lastDelta.DrawStyle = DRAWSTYLE_LINE; _lastDelta.DrawZeros = true; // input _period.Name = "Period"; _period.SetDescription("Delta channel period"); _period.SetInt(5); // misc sc.AutoLoop = 1; sc.FreeDLL = DEV_FREE_DLL; sc.MaintainAdditionalChartDataArrays = 1; // for bid/ask data return; } // // Do data processing // // // initilize // int _periodStartIndex = max(sc.Index - _period.GetInt() + 1, 0); // // compute delta channel // sc.CumulativeDeltaVolume(sc.BaseDataIn, _lastDelta, _periodStartIndex, true); sc.CumulativeDeltaVolume(sc.BaseDataIn, _lastDelta, sc.Index, false); _openDelta[sc.Index] = _lastDelta.Arrays[0] [sc.Index]; _highDelta[sc.Index] = _lastDelta.Arrays[1] [sc.Index]; _lowDelta[sc.Index] = _lastDelta.Arrays[2] [sc.Index]; //XXECIDelta_ComputeBarDelta(sc, sc.Index, _barDelta); //XXECIDelta_ComputePeriodDelta(sc, _periodStartIndex, sc.Index, _barDelta, _delta); //XXECIDelta_ComputeStddev(sc, _periodStartIndex, sc.Index, _delta, _multiplier.GetFloat(), //XX _tb1, _bb1, //XX _tb2, _bb2, //XX _tb3, _bb3, //XX _tb4, _bb4 ); //logMsg.Format("sc.Index=<%d> periodType=<%d>", sc.Index, periodType); //sc.AddMessageToLog(logMsg,0); }*/