
Stocks High Low Close Open Trace


JimProuty
This code snippet adds an "Append High Low close Open Trace" item to Igor's Graph menu, and also two submenus for controlling trace thickness and color. The submenus are warranted because the trace's color and thickness are controlled by multiple trace settings, and it makes it easier to ensure they're all set to the same values.
Igor 6.2's custom markers feature makes this trace possible: it draws the open and close markers as, essentially, half-markers, pointing to the left (for the opening price) or the right (for the closing price).
The snippet is not very sophisticated: it creates a wave in the current data folder that combines the high and low price waves into one trace.
Input data is a set of 5 equal length waves: {high price, low price, close price, open price} vs date
The output adds a 6th high/low wave graphed instead of the individual high price and low price wave.
#pragma rtGlobals=2 // Use modern global access method. #pragma IgorVersion=6.2 // for markerHook Menu "Graph", dynamic Submenu "High Low Close Open Trace" "Append High Low Close Open Trace", mAppendHighLowCloseOpen() Submenu "Line Sizes" HighLowCloseOpenLineSizesMenu(), /Q, DoHighLowCloseOpenLineSize() End Submenu "Color" HighLowCloseOpenColorMenu(),/Q, DoHighLowCloseOpenColor() End End End Function OpenCloseMarkerProc(s) STRUCT WMMarkerHookStruct &s if( s.marker > 3 ) return 0 endif Variable overhang= s.penThick/2 Variable size= s.size - overhang if( s.marker == 0 ) // open DrawLine s.x-size, s.y, s.x+overhang , s.y elseif( s.marker == 1 ) // close DrawLine s.x-overhang, s.y, s.x+size, s.y endif return 1 End Constant kOpenMarker =100 Constant kCloseMarker =101 StrConstant ksHighLowCloseOpenUserDataName="WMHighLowCloseOpenData" static Function HaveHighLowCloseOpen(graphName) String graphName if( strlen(graphName) == 0 ) return 0 endif DoWindow $graphName if( V_Flag == 0 ) return 0 endif String traces= TraceNameList(graphName, ";", 1) Variable i, n= ItemsInList(traces) for(i=0; i<n; i+=1 ) String traceName= StringFromList(i,traces) String userData= GetUserData(graphName, traceName, ksHighLowCloseOpenUserDataName) strswitch(userData) case "open": case "close": case "high/low": return 1 // have at least one open/close/high/low trace break endswitch endfor return 0 End Function/S HighLowCloseOpenColorMenu() String colorMenu= "*COLORPOP*" if( !HaveHighLowCloseOpen(WinName(0,1)) ) colorMenu= "\M1:(:"+colorMenu endif return colorMenu End Function/S HighLowCloseOpenLineSizesMenu() String sizes="0.5;1;2;3;4;5;6;7;8;9;" if( !HaveHighLowCloseOpen(WinName(0,1)) ) Variable i, n= ItemsInList(sizes) String disabledSizes="" for(i=0; i<n; i+=1 ) String size= StringFromList(i,sizes) disabledSizes += "\M1:(:"+size+";" endfor sizes= disabledSizes endif return sizes End Function DoHighLowCloseOpenLineSize() GetLastUserMenuInfo Variable lineSize= str2num(S_Value) SetHighLowCloseOpenLineSize(lineSize) End Function DoHighLowCloseOpenColor() GetLastUserMenuInfo SetHighLowCloseOpenColor(V_Red, V_Green, V_Blue) End Function SetHighLowCloseOpenColor(red, green, blue) Variable red, green, blue // find all the traces related to high-low-open-close and change the line size or marker stroke size. String graphName= WinName(0,1) if( strlen(graphName) == 0 ) Beep return 0 endif String traces= TraceNameList(graphName, ";", 1) Variable i, n= ItemsInList(traces) for(i=0; i<n; i+=1 ) String traceName= StringFromList(i,traces) String userData= GetUserData(graphName, traceName, ksHighLowCloseOpenUserDataName) strswitch(userData) case "open": case "close": case "high/low": ModifyGraph/W=$graphName rgb($traceName)=(red, green, blue) break endswitch endfor End Function SetHighLowCloseOpenLineSize(lineSize) Variable lineSize // find all the traces related to high-low-open-close and change the line size or marker stroke size. String graphName= WinName(0,1) if( strlen(graphName) == 0 ) Beep return 0 endif String traces= TraceNameList(graphName, ";", 1) Variable i, n= ItemsInList(traces) for(i=0; i<n; i+=1 ) String traceName= StringFromList(i,traces) String userData= GetUserData(graphName, traceName, ksHighLowCloseOpenUserDataName) strswitch(userData) case "open": case "close": ModifyGraph/W=$graphName mrkThick($traceName)=lineSize, msize($traceName)=lineSize*3 break case "high/low": ModifyGraph/W=$graphName lsize($traceName)=lineSize break endswitch endfor End Proc mAppendHighLowCloseOpen(wHigh, wLow, wClose, wOpen, wDays) String wHigh, wLow, wClose, wOpen, wDays Prompt wHigh, "High Prices", popup, WaveList("*",";","DIMS:1") Prompt wLow, "Low Prices", popup, WaveList("*",";","DIMS:1") Prompt wClose, "Close Prices", popup, WaveList("*",";","DIMS:1") Prompt wOpen, "Open Prices", popup, WaveList("*",";","DIMS:1") Prompt wDays, "Days", popup, WaveList("*",";","DIMS:1")+";_none_;" // can be string or numeric wave or _none_ AppendHighLowCloseOpen($wHigh, $wLow, $wClose, $wOpen, $wDays) End Function AppendHighLowCloseOpen(wHigh, wLow, wClose, wOpen,wDays) Wave wHigh, wLow, wOpen, wClose Wave/Z wDays String graphName= WinName(0,1) if( strlen(graphName) == 0 ) DoAlert 0, "Make a graph, first!" return 0 endif String outName= CleanupName(NameOfWave(wHigh)[0,14]+"_"+NameOfWave(wLow)[0,14],1) if( !WaveExists(wDays) ) Variable n= numpnts(wOpen) String daysName= CleanupName(outName[0,25]+"_days",1) Make/O/N=(n) $daysName= p+1 // 1-n WAVE wDays= $daysName endif SetWindow $graphName markerHook={OpenCloseMarkerProc,kOpenMarker,kCloseMarker} AppendToGraph/W=$graphName wOpen,wClose vs wDays String openTraceName= NameOfWave(wOpen) String closeTraceName= NameOfWave(wClose) ModifyGraph/W=$graphName mode($openTraceName)=3, mode($closeTraceName)=3 ModifyGraph/W=$graphName marker($openTraceName)=kOpenMarker,marker($closeTraceName)=kCloseMarker ModifyGraph/W=$graphName mrkThick($openTraceName)=1,mrkThick($closeTraceName)=1 // Make this work: String userData= GetUserData(graphName, $openTraceName, ksHighLowCloseOpenUserDataName) ModifyGraph/W=$graphName userData($openTraceName)={$ksHighLowCloseOpenUserDataName, 0, "open"} ModifyGraph/W=$graphName userData($closeTraceName)={$ksHighLowCloseOpenUserDataName, 0, "close"} WAVE wHighLow= fMakeHighLowWave(wHigh, wLow, outName) String dayOutName= CleanupName(NameOfWave(wDays)[0,14]+"_4HiLo",1) WAVE wHiLoDays= fMakeHighLowDays(wDays, dayOutName) AppendToGraph/W=$graphName wHighLow vs wHiLoDays ModifyGraph/W=$graphName mode($outName)=0 ModifyGraph/W=$graphName userData($outName)={$ksHighLowCloseOpenUserDataName, 0, "high/low"} End Function/WAVE fMakeHighLowWave(wHigh, wLow, outName) Wave wHigh, wLow String outName Duplicate/O wHigh, $outName/WAVE=wout Variable n=numpnts(wHigh) Redimension/N=(3*numpnts(wHigh)) wout wout[0;3] = wHigh[p/3] // interleave high first wout[1;3] = wLow[(p-1)/3] // then low wout[2;3] = NaN // then gap return wout End Function/WAVE fMakeHighLowDays(wDay, dayOutName) Wave wDay // can be text or numeric wave String dayOutName Duplicate/O wDay, $dayOutName/WAVE=wout Variable n=numpnts(wDay) Redimension/N=(3*n) wout wout= wDay[trunc(p/3)] return wout End Window OpenCloseHighLowStyle() : GraphStyle PauseUpdate; Silent 1 // modifying window... ModifyGraph/Z mode[0]=3,mode[1]=3 ModifyGraph/Z marker[0]=100,marker[1]=101 ModifyGraph/Z lSize[2]=3 ModifyGraph/Z rgb[0]=(1,16019,65535),rgb[1]=(1,16019,65535),rgb[2]=(1,16019,65535) ModifyGraph/Z msize[0]=9,msize[1]=9 ModifyGraph/Z mrkThick[0]=3,mrkThick[1]=3 ModifyGraph/Z grid(bottom)=1 ModifyGraph/Z nticks(bottom)=10 ModifyGraph/Z axOffset(bottom)=-1.66667 ModifyGraph/Z tkLblRot(bottom)=90 ModifyGraph/Z manTick(bottom)={3450384000,1,0,0,day},manMinor(bottom)={0,50} ModifyGraph/Z dateInfo(bottom)={0,0,0} Label/Z bottom " " SetWindow kwTopWin,markerHook={OpenCloseMarkerProc,100,101} EndMacro Macro MakeHighLowCloseOpenDemoData() Variable n=20 Make/O/D/N=(n) day // start at midnight+1 second String todaysDate= Secs2Date(datetime, -2, ";") Variable year= str2num(StringFromList(0,todaysDate)) Variable month= str2num(StringFromList(1,todaysDate)) Variable today= str2num(StringFromList(2,todaysDate)) today= date2secs(year, month, today) day= today+p*60*60*24 SetScale d, 0,0,"dat", day Make/O/N=(n) openPrice, highPrice, lowPrice, closePrice closePrice = 100+gnoise(4) openPrice[1,]= closePrice[p-1] openPrice[0] = closePrice[0]-gnoise(2) lowprice= (openPrice+closePrice)/2 + gnoise(max(1,abs(openPrice-closePrice))) lowPrice= min(lowPrice, min(openPrice,closePrice)) highprice= (openPrice+closePrice)/2 + gnoise(max(1,abs(openPrice-closePrice))) highPrice= max(highPrice, max(openPrice,closePrice)) Edit day, openPrice, lowPrice, highPrice, closePrice ModifyTable format(day)=6 Display DoAlert 0, "Choose \"Append High Low Close Open Trace\" from the Graph's \"High Low Close Open Trace\" menu." End


Forum

Support

Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More